• C

C program with YACC and LEX.

Platform: Digital Unix
Compiler: cc

How can I write a program with this three files?
1.- myProgram.c: Contains the source code and the parser call: yyparse()

2.- myProgram.y: Contains the parser rules in YACC. Use the third module.

3.- myProgram.l: This is the lexer for the parser.

How do I write the include's in each file?

How do I compile this programs?

What makefile must I write?
carlos0007Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

curriCommented:
You may want to take a look at this free notes
http://members.xoom.com/thomasn/y_man.htm 
(or go to your library and get a good book on that, like using lex & yacc from o'reilly, or get the manuals from your system; there are good manuals for GNU flex & bison).

Now, the simple answer to your question (not that it would be useful if you don't know HOW to make the files :):

you type
   yacc myprogram.y
this would produce 2 files, y.tab.c and y.tab.h
    lex myprogram.l
this would produce a  file, lex.yy.c

In your program, you may want to #include y.tab.h (I'm not sure about this); And you may need to put declarations for yyparse and yylex.

Your final compilation would be something like:
cc myprogram.c y.tab.c lex.yy.c

Of course, you may want to put all of this into a makefile. (and then you need to know about makefiles)

The way I always go about that (I've used flex/bison several times, but don't use them often, so I always forget :) is to download an example (see the URL above) and modify the makefile :).


Orlando


What
 

0
carlos0007Author Commented:
Dear Curri:

Thank you for your comments.

I have already worked with yacc and lex and I know basically the way it works.

I would like to get as is follows:
I would like to have a module .c in which I could include mine main program and the call to the parser through the function yyparse().
In another module with extension .y I will write the gramatic rules to analyze.
The third module I will have the lexer that will give you back the tokens to the parser.

I DONT'T WANT writing all my code into the .y module but to have the three modules separated.

I DON'T WANT EITHER including the principal part of my code in the .y file.

I want to have clearlly divided these three parts:
1.- The C program.
2.- The Parser.
3.- The Lexer.

Can I do that?

Thanks a lot.

Carlos Urtasun
0
curriCommented:
Sure you can !! That is what I tried to explain.

You have a .l file, and when you pass it trough lex, you get a .c file.

You have a .y file, and when you pass it trough yacc, you get a .h file and a .c file.

You make your own .c file. there you include the .h file that yacc generated.

You compile all three programs, and link them all together.

You have three separate files (in fact 7 :)

Orlando
0
Making Bulk Changes to Active Directory

Watch this video to see how easy it is to make mass changes to Active Directory from an external text file without using complicated scripts.

GleasonGuyCommented:
With the files you mentioned, you would do the following (depending on your versions of lex & yacc)

yacc -l -o myGrammar.c -D tokens.h myProgram.y
lex -a -l -o myScanner.c myProgram.l
cc myProgram.c
link myProgram myScanner myGrammar

Where main.c includes:

int
main(int argc, char *argv[])
{
    HandleCommandlineArgs(argc, argv);

    yyout = stderr;
    if( (yyin = fopen("inputfile", "r")) == NULL) {
        return 1;
    }

    InitHelperFunctions();

    return yyparse();
}
0
carlos0007Author Commented:
Remembering:
Platform: Digital Unix
Compiler: cc

Dear Curri:
I've done "lex lexer.l" and I get: lex.yy.c

I've done "yacc parser.y" and I get: y.tab.c
But I don't get a .h file!

Dear Guy:
My lex and yacc are standards.
The yacc flags -o -D don't exists.
The lex flags -a -l -o either.

man yacc returns the flags:
-b -d -l -N -p -P -s -t -v

man lex returns the flags:
-c -n -r -t -v -V -Q
0
GleasonGuyCommented:
Sorry about those flags. I was trained in the Unix world, but now work in the "other" world. Thos flags that I used were for MKS lex & yacc. They are defined as follows:
-a = allows 8-bit ASCII (don't need)
-l = disables #line directives (don't need)
-o filename = specifies output filename (don't need)
-D filename = same as -d except that filename is specified (don't need). Tokens should default to y.tab.h

So with that out of the way you would get:
yacc -d myProgram.y
lex myProgram.l
cc myProgram.c
cc lex.yy.c
cc y.tab.c
link myProgram lex.yy y.tab
0
carlos0007Author Commented:
Dear Guy:
I've done "yacc -d parser.y" and I get: y.tab.c
and
y.tab.h

I've done "lex -d lexer.l" and I get: lex.yy.c

I've done "cc myProgram.c" and I get:
ld:
Unresolved:
yyparse

Why?
I have in myProgram.c:
#include "y.tab.h"
....
main(int argc, char *argv[])
{
   ...
   yyparse();
   ...
}

Thanks a lot.
0
GleasonGuyCommented:
Sorry about that. You need some externs in myProgram.c

extern int yyparse(void);

and probably,

extern FILE *yyin;
extern FILE *yyout;
0
carlos0007Author Commented:
I have in myProgram.c now:
#include "y.tab.h"
#include <ctype.h>
#include <stdio.h>
extern int yyparse(void);
extern FILE *yyin;
extern FILE *yyout;

And I get again after "cc myProgram.c":
ld:
Unresolved:
yyparse

In lexer.l I have:
%{
#undef input
#undef unput
int input(void);
void unput();
extern char *params; /*GLOBAL VAR FROM myProgram.c*/
%}

....

%%
....

%%
static int iLex =0;

int input (void)
{
   ...
}

void unput(int ch)
{
   ...
}

In parser.y I have:
%{
#include <ctype.h>
#include <stdio.h>
%}

....

%%

#include "lex.yy.c"

void yyerror(char *s)
{
   ...
}

Thanks a lot.

Carlos Urtasun
0
GleasonGuyCommented:
I think another apology is due on my part. It's been a while since I've used a make file (or command line), especially in Unix. Most of my program is done in a GUI, so my brain has gotten soft.

cc does both compiling and linking, so try just the following...

yacc -d myProgram.y
lex myProgram.l
cc myProgram.c lex.yy.c y.tab.c

Barring any more brain malfunctions on my end, that will do it.

0
carlos0007Author Commented:
I have in myProgram.c now:
#include "y.tab.h"
#include <ctype.h>
#include <stdio.h>
extern int yyparse(void);
extern FILE *yyin;
extern FILE *yyout;
....

In lexer.l I have:
%{
#include "y.tab.h"
#undef input
#undef unput
int input(void);
void unput();
void yyerror(char *s);
extern char *params; /*GLOBAL VAR FROM myProgram.c*/
%}
....

%%
....

%%
static int iLex =0;

int input (void)
{
   ...
}

void unput(int ch)
{
   ...
}

void yyerror(char *s)
{
        printf("ERROR: %s String: '%s'\n",s,yytext);
}

In parser.y I have:
%{
#include <ctype.h>
#include <stdio.h>
%}

....

%%

I've done:
yacc -d myProgram.y
lex myProgram.l
cc myProgram.c lex.yy.c y.tab.c

and I get:
myProgram.c:
lex.yy.c:
y.tab.c:
ld:
Unresolved:
yywrap

Why?

Thanks a lot.

Carlos Urtasun
0
GleasonGuyCommented:
Whenever you get an "Unresolved" error, it means that there is a function or variable that the linker cannot find.

In your case, the linker can't find yywrap. I think you need to add
extern int yywrap();
to your code (I'm pretty sure it goes in the public are of parse.y).

Good luck.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.