Reputation: 1
Flex definition:
"view" { return VIEW;}
"cell" { return CELL;}
[A-Za-z]+ {
yylval.strval=strdup(yytext);
return ALPHA;
}
[()] {return yytext[0];}
My bison grammar:
static int len=10;
static char *allkeywords[10]= {"view","acload","actual","after","alpha","and","annotate","apply","arc","array" };
cell:’(’ CELL ALPHA ’)’ { goal=$3;
flag=binary_search(allkeywords,len,goal);
if(flag)
{
yyerror("warnning: the component name is a keyword");
yyclearin;
yyerrok;
}
;
int binary_search(const char *a[10], int len, char *goal)
{
int low = 0;
int high = len - 1;
while(low <= high)
{
int middle = (low + high)/2;
if(strcmp (goal,a[middle])==0 )
return 1;
else if(strcmp (goal,a[middle]) < 0)
high = middle - 1;
else
low = middle + 1;
}
return 0;
}
My instructions:
bison -d -v bison.y
flex flex.l
gcc bison.tab.c lex.yy.c
For instance, the input stream is (cell view ), the word “view” is random monogram given by a user.Coincidentally, it is a keyword of EDIF file, and it also corresponds to ALPHA. I set that if the ALPHA given by user is a keyword, call yyerror function to warn, but the bison call yyerror itself. Its output is “zhouzhou:1.3-1.6:syntax error, unexpected CELL, expecting EDIF”, actually, I expect that it present” zhouzhou:1.3-1.6: warnning: the component name is a keyword”. How to make bison not to call its yyerror , just do what I mean ?
Upvotes: 0
Views: 447
Reputation: 753705
While you can code a grammar so that keywords are allowed as identifiers, doing so is unnatural and painfully hard. Keywords are so called because you can't use them as identifiers.
flex.l
%{
#include "bison.tab.h"
%}
%%
"view" { puts("VIEW"); return VIEW;}
"cell" { puts("CELL"); return CELL;}
[A-Za-z]+ {
yylval.strval=strdup(yytext);
puts("ALPHA:");
puts(yylval.strval);
return ALPHA;
}
[()] {puts("PARENS"); return yytext[0];}
. { printf("SKIP: %d %c\n", yytext[0], yytext[0]); }
%%
int yywrap(void)
{
return(1);
}
bison.y
%{
#include <stdio.h>
#include <string.h>
static int binary_search(char **a, int len, char *goal);
static char *goal;
static int flag;
static int len=10;
static char *allkeywords[10]= {"view", "acload", "actual", "after", "alpha", "and", "annotate", "apply", "arc", "array" };
%}
%union { char *strval; }
%token <strval> CELL
%token <strval> ALPHA
%token <strval> VIEW
%%
cell: '(' CELL ALPHA ')'
{
goal=$3;
flag=binary_search(allkeywords, len, goal);
if(flag)
{
printf("Before yyerror()\n");
yyerror("warning: the component name is a keyword");
printf("After yyerror()\nBefore yyclearin\n");
yyclearin;
printf("After yyclearin\nBefore yyerrok\n");
yyerrok;
printf("After yyerrok\n");
}
}
;
%%
static int binary_search(char **a, int len, char *goal)
{
int low = 0;
int high = len - 1;
while(low <= high)
{
int middle = (low + high)/2;
if(strcmp (goal, a[middle])==0 )
return 1;
else if(strcmp (goal, a[middle]) < 0)
high = middle - 1;
else
low = middle + 1;
}
return 0;
}
int main(void)
{
int rc;
yydebug = 1;
setvbuf(stdout, 0, _IOLBF, 0);
rc = yyparse();
printf("== In main after yyparse() = %d\n", rc);
return(0);
}
set -x
bison -d -v bison.y &&
flex flex.l &&
gcc -DYYDEBUG bison.tab.c lex.yy.c -ly &&
a.out < data
(cell alpha)
++ bison -d -v bison.y
++ flex flex.l
++ gcc -DYYDEBUG bison.tab.c lex.yy.c -ly
++ a.out
Starting parse
Entering state 0
Reading a token: PARENS
Next token is token '(' ()
Shifting token '(' ()
Entering state 1
Reading a token: CELL
Next token is token CELL ()
Shifting token CELL ()
Entering state 4
Reading a token: SKIP: 32
ALPHA:
alpha
Next token is token ALPHA ()
Shifting token ALPHA ()
Entering state 6
Reading a token: PARENS
Next token is token ')' ()
Shifting token ')' ()
Entering state 7
Reducing stack by rule 3 (line 29):
$1 = token '(' ()
$2 = token CELL ()
$3 = token ALPHA ()
$4 = token ')' ()
Before yyerror()
warning: the component name is a keyword
After yyerror()
Before yyclearin
After yyclearin
Before yyerrok
After yyerrok
-> $$ = nterm cell ()
Stack now 0
Entering state 3
Reducing stack by rule 2 (line 25):
$1 = nterm cell ()
Stack now 0
== In main after yyparse() = 0
Notice how the code returns successfully to the main()
function once and does not call yyerror()
.
Upvotes: 1