0

This is my first time trying out BISON and I'm stuck trying to figure out how to take a complete statement for example astros = 2. Whenever I try to do that, I don't get any output. But if I try each part separately then I get output for each part. My code is as follow, just part of it of course:

.y file

%token ASSIGNMENT
%token <intToken> INTNUMBER
%token <intToken> INTTOKEN
%type <statement> STATEMENT

STATEMENT:    '\n'
              | INTTOKEN STATEMENT {printf("Token");}
              | INTNUMBER STATEMENT {printf("Number");}
              | STATEMENT ASSIGNMENT STATEMENT{printf("Assinging");}
              |  INTTOKEN '\t' ASSIGNMENT '\t' INTNUMBER STATEMENT {printf("FULL STATEMENT COMPLETE");}

               |error {yyerror("ERROR");}

My .l file:

"="                                 return ASSIGNMENT;
[0-9]+                      { ECHO; yylval.integer = atoi(yytext); return INTNUMBER; }
[a-fA-F]+[a-zA-Z]+      { ECHO; yylval.variableInteger = yytext; return INTTOKEN; }

Also if someone could explain me how the rules of the tokens work then that would be great. Maybe like that I can figure it by myself.

Silvestrini
  • 445
  • 4
  • 19
  • Perhaps you should take a look at the [flex manual](http://flex.sourceforge.net/manual/Simple-Examples.html#Simple-Examples), or John Levine's book on Bison and Flex (O'Reilly). – rici Jan 26 '16 at 18:33

1 Answers1

1

Rules are simple, Lex is searching sequentially for regular expressions, matching tokens and giving them to Yacc. Yacc is using yylex() function for this purpose.

Your question is not complete. Do you have something else written in Yacc file?

Yacc file consists of three parts:

  • C code that is later located somewhere near start of y.tab.c file (that Yacc generates), in this part of the file you need to declare extern int yylex(void) function. Yacc actually needs two things to work, first one is yylex() and seccond is yyerror().
  • Second part is Grammar with rules and actions

  • Third part is main function where you call yyparse().

As for declaration of tokens and types, that can be done before or after %{ %} part of the file. Some basic Yacc code would look like this:

%{ 
 #include <stdio.h>
 #include ...

 /* Extern keyword is just good practice, it doesn't have to be written */
 extern int yylex(void);

 void yyerror(char *string){

   fprintf(stderr,"Syntax error: %s", string);
   exit(EXIT_FAILURE);
 }

%}

%%
  /* Grammar with actions */
%%

int main(){

  yyparse();
  return 0;
}

So how does this work? Yacc is using yylex() function to get tokens and then his grammar to determine everything else. In order this to work, you have to compile both lex.yy.c generated with flex and y.tab.c generated with yacc to object file, and then compile those two object files into one executable.

For example:

yacc program.y
flex program.lex
gcc -c y.tab.c -o y.tab.o
gcc -c lex.yy.c -o lex.yy.o
gcc y.tab.o lex.yy.o -o program

Note: If you're declaring tokens in Yacc file, you need to generate y.tab.h file when running Yacc command with yacc -d program.y and then to include this file in your Lex. Option -d is for that.

Aleksandar Makragić
  • 1,957
  • 17
  • 32