lex文件
%%
^((for)|(while))[(][)] return FORWHILE;
[ ]* return SPACE;
([a-z ]+[;])+ return LINE;
. ;
%%
yacc文件
%start s
%token FORWHILE
%token SPACE
%token LINE
%%
s: FORWHILE SPACE '{' SPACE LINE SPACE '}' SPACE
{
printf("Data OK\n");
};
%%
#include <stdio.h>
#include <string.h>
#include "lex.yy.c"
int main()
{
return yyparse();
}
int yyerror()
{
printf("Error in data\n");
return 0;
}
这就是我的尝试。
我希望输入for(){bla bla;bla bla;}
会产生Data OK
。
我出于某种原因无法让它工作。
问题是什么?
感谢
更新
%start s
%token FOR
%token WHILE
%token LINE
%token DO
%%
s: forwhile | dowhile { printf("Data OK\n"); };
dowhile: do_stmt '{' lines '}' while_stmt;
forwhile: for_or_while_stmt '{' lines '}';
lines: line | lines line;
line: LINE;
for_or_while_stmt: for_stmt | while_stmt;
for_stmt: FOR'()';
while_stmt: WHILE'()';
do_stmt: DO;
%%
#include <stdio.h>
#include <string.h>
#include "lex.yy.c"
int main()
{
return yyparse();
}
int yyerror()
{
printf("Error in data\n");
return 0;
}
法
%%
"while" return WHILE;
"for" return FOR;
"do" return DO;
[a-z ]+[;] return LINE;
. return yytext[0];
%%
我也添加了。但仍然无法做到正确。
答案 0 :(得分:1)
根据您的词汇扫描程序,bla bla;bla bla;
包含两个LINE
令牌。但是,你的语法只允许一个
s: FORWHILE SPACE '{' SPACE LINE SPACE '}' SPACE
您还应该解决其他一些问题。首先,与[ ]* { return SPACE; }
一样,lex模式与空字符串匹配并不是一个好主意。如果匹配成功(只有在不再存在匹配时才可能),那么您将发现自己处于无限循环中,因为扫描仪永远不会前进。
通常不建议将空格标记传递给解析器;更好的是在词法扫描器中简单地忽略它们,特别是(如本例所示)它们是可选的。另一方面,忽略无法识别的字符(. ;
)可以轻松掩盖错误。
最后,.
与任何角色都不匹配。它匹配换行符以外的任何字符。在您的词法扫描程序定义中,换行符不符合任何规则,因此会导致上面提到的无限循环。如果您将SPACE
规则修复为仅匹配非空序列,则新行将落入隐式默认规则ECHO
。这也不是一个好主意。
我强烈建议使用%option nodefault
,如果任何输入与任何规则不匹配,将导致flex提供诊断。但是,这不会警告你关于匹配空模式的规则,所以你仍然需要小心。