Question

I'm trying to create a parser-scanner which will get as input a file which file has stuff like this inside: 5 + 23 + ..... + 3; and I want it to print the outcome on the screen.

I find it a bit hard to understand how the $$ = $1 +... works and how are these $1, $2 are connected with the tokens. If someone can explain me that part I would be really grateful.

My code till now is this:

lex code:

%option noyywrap
%%
\+ //{ yylval.p = yytext[0]; return PLUS; }
; //{ yylval.q = yytext[0]; return Q_MARK; }
0|([-+]?(([1-9][0-9]*)|(0\.[0-9]+)|([1-9][0-9]*\.[0-9]+))) { yylval.d = atof(yytext); return NUMBER; }
%%

flex code:

%defines

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

%union {
    double d;
    }

%token <d> NUMBER  //some number
%token PLUS        // +
%token Q_MARK      // ;
%start addition_list
%%

addition_list : addition Q_MARK  {}
| addition_list addition Q_MARK  {}
;

addition : NUMBER PLUS NUMBER { }
| addition PLUS NUMBER {  }
;

%%
int yyerror(char *message)
{
    return 0;
}
void main()
{
    yyparse();
}

ps: I have some instructions on how it should look so that's why it's like that. Whatever clue you could give me would be really appreciated cause I find it hard understanding on internet guides(still trying though).

Was it helpful?

Solution

I dont want to go too deep into flex and bison so I try to explain it as simply as possible.

The $$ can interpreted as the return value of a grammar rule, once the rule is finnished ( reduced ) by the parser the $$ value will be given through.

So for example, the rule :

addition : NUMBER PLUS NUMBER { }

The inside of the curly bracelets is called an action rule. The $1 $2 $3 ... represents the first, second and third argument of the rule.

This means:

$1 = NUMBER
$2 = PLUS
$3 = NUMBER

If you want to add the NUMBER to the other NUMBER you have to write something like this in your action rule :

addition : NUMBER PLUS NUMBER { printf("%d",$1+$3);}

The Lexer is something like the subroutine of the parser, the parser requests the next symbol and flex scans the input for the next symbol and passes it to bison.

Something to mention: The parser has no idea what is inside the number, he just gets the symbol NUMBER. Thats why you need something like this in your flex/bison:

flex file:

[0-9]+   { yylval.val = atoi(yytext); return NUMBER; }

bison:

%union {
int val; 
};
%token <val> NUMBER

Once a NUMBER symbol is scanned, flex writes its value into the val variable so bison can access it.

To understand better what happens, I recommend that you do some printf in every grammar rule. Hope that helps!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top