Flex定义:
"view" { return VIEW;}
"cell" { return CELL;}
[A-Za-z]+ {
yylval.strval=strdup(yytext);
return ALPHA;
}
[()] {return yytext[0];}
我的野牛语法:
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;
}
我的指示:
bison -d -v bison.y
flex flex.l
gcc bison.tab.c lex.yy.c
例如,输入流是(单元格视图),单词“view”是用户给出的随机会标。巧合的是,它是EDIF文件的关键字,它也对应于ALPHA。我设置如果用户给出的ALPHA是关键字,请调用yyerror函数进行警告,但是野牛调用yyerror本身。它的输出是“zhouzhou:1.3-1.6:语法错误,意外的CELL,期待EDIF”,实际上,我希望它出现“zhouzhou:1.3-1.6:warnning:组件名称是一个关键字”。 如何让野牛不要叫它的yyerror,只是做我的意思?
答案 0 :(得分:1)
虽然您可以编写语法代码以便允许关键字作为标识符,但这样做是不自然的,并且非常困难。所谓的关键字是因为你不能将它们用作标识符。
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
注意代码如何成功返回main()
函数一次,而不是调用yyerror()
。