I have this bison code and I don't know how to loop second expression in line_start
.
How can I check if there are more than two table names connected with &?
I need TABLE_NAME WS AND TABLE_NAME WS
run for as much as the input of my txt file.
It works only with two not more...
%{
#include <stdio.h>
#include <stdlib.h>
#define YYDEBUG 1
extern int yylineno;
extern FILE* yyin;
%}
%token CREATE_TABLE CREATE_RECORD_DATA
%token TABLE_NAME RECORD_NUMBER EXPRESSION
%token AND LPAR RPAR PLUS MINUS MULT DIV END
%token WS
%start program
%%
program :
|program line_start
;
line_start :
CREATE_TABLE WS TABLE_NAME END {printf("Table created in line %d \n",yylineno-1);}
|CREATE_TABLE WS TABLE_NAME WS AND WS TABLE_NAME END {printf("Table created in line %d \n",yylineno-1);}
|
;
%%
int yyerror(char *s){
printf("Error %s \n",s);
}
int main(int argc, char* argv[]) {
if (argc != 2) {
printf("Usage: ./parser <input_file>\n");
return 1;
}
FILE* inputFile = fopen(argv[1],"r");
if(!inputFile)
{
printf("Someting not right ! \n");
return 1;
}
yyin = inputFile;
yyparse();
fclose(inputFile);
return 0;
}
input :
Lets say that i have those inputs from my file ,the first two works fine the third one must work but it does not (it gives error) and the last one has error (this one must have an error because my grammer accepts only [a-z]):
create_table table
create_table table & table
create_table table & table & table
create_table taABle2
The error it gives me saying that it is syntax error
You need to show what the syntax of the language you are trying match is, perhaps by quoting an extract from the manual.
However, I will make a guess for what is required. You mention iteration about the AND keyword. BNF, and context free grammars like BNF which are used in Bison use recursion for repetition and not "loops". This means you have to use the name of the rule within the rule to show more is required. However, your rule contains the keywords CREATE_TABLE which is not repeated, which means you cannot recurse on the line_start
rule. The conclusion of this analysis is that you need to create a new rule for the body of the line which does repeat. Perhaps we can call this rule line_body
.
As already noted in the comments white-space in languages (WS) should not be passed from the lexer to the parser and should be ignored, and can be skipped in the bison rules.
Your grammar will now look like this:
%{
#include <stdio.h>
#include <stdlib.h>
#define YYDEBUG 1
extern int yylineno;
extern FILE* yyin;
%}
%token CREATE_TABLE CREATE_RECORD_DATA
%token TABLE_NAME RECORD_NUMBER EXPRESSION
%token AND LPAR RPAR PLUS MINUS MULT DIV END
%start program
%%
program :
|program line_start
;
line_start :
CREATE_TABLE line_body END {printf("Table created in line %d \n",yylineno-1);}
;
line_body: TABLE_NAME
| TABLE_NAME AND line_body
%%
int yyerror(char *s){
printf("Error %s \n",s);
}
Which hopefully you can see is much more elegant.