SaltyCrane Blog — Notes on JavaScript and web development

Example using bison and flex with cygwin on Windows

Here is an example of how to use bison and flex (yacc and lex)with cygwin on windowsxp.
  1. Go to http://www.cygwin.com/, install Cygwin including bison 2.3-1, flex 2.5.4a-3, gcc-core 3.4.4-1, and make 3.81-1.

  2. Create a file called "simple.flex" in "c:\temp":
    %{                                                                                          
    #include "simple.tab.h"
    extern int line_number;
    %}
    %option noyywrap

    %%
    "float" { printf("FROM FLEX FLOAT %s\n", yytext); return FLOAT; }
    "int" { printf("FROM FLEX INT %s\n", yytext); return INT; }
    [;] { return *yytext; }
    [_a-zA-Z][_a-zA-Z0-9]* { printf("FROM FLEX IDENTIFIER: %s\n", yytext); return IDENTIFIER; }
    [ \t\r]+ /* eat up whitespace */
    [\n] { line_number++; }
    %%

  3. Create a file called "simple.y" in "c:\temp":
    %{                                                                                   
    #include <stdarg.h>
    #include "simple_shared.h"
    #define YYSTYPE char *
    int yydebug=1;
    int indent=0;
    char *iden_dum;
    %}
    %token FLOAT
    %token INT
    %token IDENTIFIER

    %% /* Grammar rules and actions follow */
    declaration:
    type_specifier identifier_dum ';'
    { printf("%3d: FROM BISON declaration\n", line_number); }
    ;
    type_specifier:
    FLOAT
    { printf("%3d: FROM BISON FLOAT\n", line_number); }
    | INT
    { printf("%3d: FROM BISON INT\n", line_number); }
    ;
    identifier_dum:
    IDENTIFIER
    { iden_dum = $1; printf("%3d: IDENTIFIER: %s\n", line_number, &iden_dum); }
    ;
    %%

    main ()
    {
    yyparse ();
    }

  4. Create a file called "simple_shared.h" in "c:\temp":
    int line_number=1;

  5. Create a file called "Makefile" in "c:\temp":
    simple: lex.yy.o simple.tab.o
    	gcc -o simple $^
    
    simple.tab.h: simple.y
    	bison --debug --verbose -d simple.y
    
    simple.tab.c: simple.y
    	bison -d simple.y
    
    lex.yy.c: simple.flex simple.tab.h
    	flex  simple.flex
    

  6. Create a file called "input.c" in "c:\temp":
    float variable;

  7. Open a Cygwin bash shell.
  8. "cd /cygdrive/c/temp"
  9. "make"
  10. "./simple.exe < input.c"

You should get some output like this:
$ ./simple.exe < input.c                      
Starting parse
Entering state 0
Reading a token: FROM FLEX FLOAT float
Next token is token FLOAT ()
Shifting token FLOAT ()
Entering state 1
Reducing stack by rule 2 (line 21):
$1 = token FLOAT ()
1: FROM BISON FLOAT
-> $$ = nterm type_specifier ()
Stack now 0
Entering state 4
Reading a token: FROM FLEX IDENTIFIER: variable
Next token is token IDENTIFIER ()
Shifting token IDENTIFIER ()
Entering state 6
Reducing stack by rule 4 (line 27):
$1 = token IDENTIFIER ()
1: IDENTIFIER:
-> $$ = nterm identifier_dum ()
Stack now 0 4
Entering state 7
Reading a token: Next token is token ';' ()
Shifting token ';' ()
Entering state 8
Reducing stack by rule 1 (line 17):
$1 = nterm type_specifier ()
$2 = nterm identifier_dum ()
$3 = token ';' ()
1: FROM BISON declaration
-> $$ = nterm declaration ()
Stack now 0
Entering state 3
Reading a token: Now at end of input.
Stack now 0 3
Cleanup: popping nterm declaration ()

Comments


#1 uvrakesh commented on :

hi, I am not sure this comment has been given already, was a good tutorial,keep it up.

I found two small mistakes, may be you missed accidently. ->The line 2 of simple.y is having a blank include statement ->secondly the yyerror is not defined yet

I was able to run the program after doing this change, but i didnt get expected output when i added two more declaration in the input.c file. may be my expection is incorrect.


#2 Eliot commented on :

uvrakesh,
thanks for your comment. i fixed the include statement. (i didn't use the proper HTML escape codes for the angle brackets.) regarding the rest of your comment, i haven't worked with this in a while so i can't give any informed response. if you post any further results, i can link to them here.


#3 BRUNO commented on :

Hello,

I'm french, my english is not OK.

I use your exemple, but i use gcc on windows whitout Cypwin and con you help me for compile example ?

My syntaxe :

bison simple.y flex simple.l

After ?

Thank you


#4 Code-E commented on :

Hi everyone, In addition to uvrakesh's comment, it appears the program won't compile if the "yyerror" function is not defined yet. the following modification to "simple.y" should fix that problem:

Insert the following around line 5:

 void yyerror (char const *);

Now, insert the following before main(), which is around line 30:

 #include <stdio.h>
 void yyerror(char const *s)
 {
 fprintf(stderr,"%s\n",s);
 }

I hope this helps someone.


#5 Code-E commented on :

I also have some tips for people using cygwin for the first time (like me!).

First of all, make sure all of your files are saved with ANSI encoding (not Unicode).

Second, if the "make" command is giving you trouble, make sure that the "make" package installed. If it is not, re-run the Cygwin setup, and select the "make" package, under the "Devel" Category.

Thirdly, it appears as if executables compiled in Cygwin won't work unless there is a file called "cygwin1.dll" in the folder being used. If you need it, you just have to do a simple search on your computer to find it, and copy and paste it into the folder that it is needed in.

I hope these tips helps someone save some time and frustration.


#6 Eliot commented on :

Hi Code-E, thanks for contributing your code and tips. I vaguely remember something about yyerror when I was working with this. I don't know why I didn't include it in my example.


#7 Hanoi commented on :

I'm stocked in the step #8, I've openened the cygwim bash shelland wrote down the step#8 but it keep saying that: there's not such file or directory.

note:I created the files in a folder named temp within the c folder.

Could you help me please?


#8 hanoi commented on :

Sorry Í forgot to say I'm running windows vista.


#9 buthayna commented on :

hi, when I tried to run make command for the first time the error "missing separator " appeared. It seamed that a tab character should be pressed before lines2,4,6,8 in the makefile file


#10 Eliot commented on :

buthayna, yes tab characters are required in the Makefile. i'm sorry, they must have gotten lost when i published the html. i have fixed the post to use tab characters now.


#11 Karl commented on :

I tried this but my cygwin returned this text.

*** no rule to make target `simple.exe`. Stop.

is there something wrong?

Thanks!


#12 Jordan commented on :

any input different from the example will give me a syntax error...

only input like these will work int var;

how can i fix this?


#13 venkatesh.p commented on :

thanks 4 the tips but what is the procedure of executing lex and yacc programs after the above steps


#14 taha commented on :

I have created the files in c:\temp, now i am stuck at step 7 : "Open a Cygwin Bash shell" how do i open cygwin bash shell ?? plz tell me.


#15 taha commented on :

how do i perform step 9 ?


#16 bala commented on :

sir i have downloade and instaled cygwin and when i tried to execute it i have the problem iam new to this so can you please mail me the procedure for executing x.l and x.y files in cygwin thanq..........