This is my flex code:
%{
#include "parser.tab.h"
%}
%%
"save" { return SAVE; }
"depth" { return DEPTH; }
"exclude" { return EXCLUDE; }
[0-9]+ { yylval.number = atoi(yytext); return NUMBER; }
"[" { return LB; }
"]" { return RB; }
"=" { return EQ; }
"," { return COMMA; }
[a-zA-Z0-9_*?]+ { yylval.str = strdup(yytext); return STRING; }
[ \t\n] { /* ignore whitespace */ }
. { /* ignore unknown characters */ }
%%
int yywrap()
{
return 1;
}
This is my bison code:
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "parser.tab.h"
void yyerror(char *s);
%}
%union {
char *str;
int number;
}
%token SAVE DEPTH EXCLUDE
%token LB RB EQ COMMA NUMBER STRING
%%
command:
| SAVE DEPTH EQ NUMBER EXCLUDE EQ NUMBER { printf("Command parsed successfully.\n"); }
| error { printf("Error: Invalid command.\n"); }
;
%%
int main()
{
yyparse();
yyrestart();
return 0;
}
void yyerror(char *s)
{
printf("ERROR:%s\n",s);
}
This is the result when I ./parser :
save depth=1 exclude=1
Command parsed successfully.
save
ERROR:syntax error
Error: Invalid command.
Error: Invalid command.
save depth=1 exclude=1
Error: Invalid command.
Error: Invalid command.
Error: Invalid command.
Error: Invalid command.
Error: Invalid command.
Error: Invalid command.
Error: Invalid command.
The first time it will succeed, the next time it will all fail.
You have made the standard beginners mistake of only defining the syntax of a single command, but supplied a file containing more than one command, and thus bison informs you that it does not match the syntax of a single command!
You need to define the syntax of the whole language|file|program. I see you expect the input to be one command per-line, so this is what you have to instruct bison:
input: command
| command NEWLINE input
Then it will process a sequence of commands, each one on a line.
You will then need to redefine your whitespace in the lexer, as the end-of-line now has significance.