我正在学习flex&野牛和我被困在这里,无法弄清楚这么简单的语法规则如何不能像我预期的那样工作,下面是词法分析器代码:
%{
#include <stdio.h>
#include "zparser.tab.h"
%}
%%
[\t\n ]+ //ignore white space
FROM|from { return FROM; }
select|SELECT { return SELECT; }
update|UPDATE { return UPDATE; }
insert|INSERT { return INSERT; }
delete|DELETE { return DELETE; }
[a-zA-Z].* { return IDENTIFIER; }
\* { return STAR; }
%%
以下是解析器代码:
%{
#include<stdio.h>
#include<iostream>
#include<vector>
#include<string>
using namespace std;
extern int yyerror(const char* str);
extern int yylex();
%}
%%
%token SELECT UPDATE INSERT DELETE STAR IDENTIFIER FROM;
ZQL : SELECT STAR FROM IDENTIFIER { cout<<"Done"<<endl; return 0;}
;
%%
如果我尝试将“select * from something”
放入,可以告诉我为什么它会显示错误答案 0 :(得分:2)
[a-zA-Z].*
将匹配字母字符,后跟除换行符之外的任意数量的任意字符。换句话说,它将从字母字符匹配到行尾。
由于flex始终接受最长匹配,因此行select * from ...
似乎只有一个令牌IDENTIFIER
,这是语法错误。
答案 1 :(得分:1)
[a-zA-Z].* { return IDENTIFIER; }
问题出在这里。它允许任何垃圾跟随一个初始的字母字符,并返回IDENTIFIER,
,包括在这种情况下,在最初的's之后的整个行的其余部分。
应该是:
[a-zA-Z]+ { return IDENTIFIER; }
或可能
[a-zA-Z][a-zA-Z0-9]* { return IDENTIFIER; }
或您希望允许在您的标识符中使用初始字母字符的任何其他内容。