Reputation: 9
I created a small interpreter using flex/bison.
This just can print a number, but I want to know how can add a string print?
lexer :
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "y.tab.h"
%}
%%
<INITIAL>[s|S][h|H][o|O][w|W] {return show;}
<INITIAL>[0-9a-zA-z]+ {yylval.num=atoi(yytext);return string;}
<INITIAL>[\-\+\=\;\*\/] {return yytext[0];}
%%
int yywrap (void) {return 1;}
yacc :
%{
void yyerror(char *s);
#include <stdio.h>
#include <stdlib.h>
%}
%union {int num;}
%start line
%token show
%token <num> number
%type <num> line exp term
%%
line : show exp ';' {printf("showing : %d\n",$2);}
| line show exp ';' {printf("showing : %d\n",$3);}
;
exp : term {$$ = $1;}
| exp '+' term {$$ = $1 + $3;}
| exp '-' term {$$ = $1 - $3;}
| exp '*' term {$$ = $1 * $3;}
| exp '/' term {$$ = $1 / $3;}
;
term : number {$$ = $1;}
%%
int main (void)
{
return yyparse();
}
void yyerror (char *s)
{
printf("-%s at %s !\n",s );
}
test data :
show 5;
show 5+5;
show 5*2-5+1;
I want add string code to the lexer :
<INITIAL>\" {BEGIN(STRING);}
<STRING>\" {BEGIN(INITIAL);}
Now how to use from content of in <STRING>
?
Can you help me to complete my interpreter?
I need to add this examples to my interpreter :
show "hello erfan";//hello erfan
show "hello ".5;//hello 5
Please help me.
Upvotes: 0
Views: 1789
Reputation: 5893
At the moment your interpreter doesn't work on numbers either! (Its an interpreter because it generates the results directly and does not generate code like a compiler would).
To make it work for numbers (again) you'd have to return a number token from the lexer and not a string. This line is wrong:
<INITIAL>[0-9a-zA-z]+ {yylval.num=atoi(yytext);return string;}
It should return a number token:
<INITIAL>[0-9]+ {yylval.num=atoi(yytext);return number;}
Now lets add a string. I see you made a start:
<INITIAL>\" {BEGIN(STRING);}
<STRING>\" {BEGIN(INITIAL);}
We need to add the state for a string to the lexer:
%x STRING
We should also match the contents of the string. I'll cheat a little here:
<STRING>[^"]*\" {BEGIN(INITIAL); return(string);}
We also need to return the string value in the lval. Cheating again I can store a char pointer in the integer
<STRING>[^"]*\" {BEGIN(INITIAL); yylval.num=strdup(yytext); return(string); }
Now we have to add strings to the yacc grammar. I'm cheating again by not allowing integers and strings to be mixed. You can expand that later if you wish:
line : show exp ';' {printf("showing : %d\n",$2);}
| line show exp ';' {printf("showing : %d\n",$3);}
| show string ';' {printf("showing : %s\n",$2);}
| line show string ';' {printf("showing : %s\n",$3);}
;
We need to remember to declare the string token:
%token <num> number string
Now we can put that all together:
The lexer file:
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "y.tab.h"
%}
%x STRING
%%
<INITIAL>[s|S][h|H][o|O][w|W] {return show;}
<INITIAL>[0-9]+ {yylval.num=atoi(yytext);return number;}
<INITIAL>[\-\+\=\;\*\/] {return yytext[0];}
<INITIAL>\" {BEGIN(STRING);}
<STRING>[^"]*\" {BEGIN(INITIAL);yylval.num=strdup(yytext);return(string);}
%%
int yywrap (void) {return 1;}
The parser file:
%{
void yyerror(char *s);
#include <stdio.h>
#include <stdlib.h>
%}
%union {int num;}
%start line
%token show
%token <num> number string
%type <num> line exp term
%%
line : show exp ';' {printf("showing : %d\n",$2);}
| line show exp ';' {printf("showing : %d\n",$3);}
| show string ';' {printf("showing : %s\n",$2);}
| line show string ';' {printf("showing : %s\n",$3);}
;
exp : term {$$ = $1;}
| exp '+' term {$$ = $1 + $3;}
| exp '-' term {$$ = $1 - $3;}
| exp '*' term {$$ = $1 * $3;}
| exp '/' term {$$ = $1 / $3;}
;
term : number {$$ = $1;}
%%
int main (void)
{
return yyparse();
}
void yyerror (char *s)
{
printf("-%s at %s !\n",s );
}
#include "lex.yy.c"
Its basic and it works (I tested it). I've left plenty of things to be polished. You can remove the quote character from the string text; you can make the string token ave a string value rather than an integer to avoid the horrible type mismatch and you can make the show statements a bit more complex, but at least I've got you started.
Upvotes: 1