为什么简单的语法规则在野牛不起作用?

时间:2013-08-07 20:22:27

标签: c++ parsing bison flex-lexer

我正在学习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”

放入,可以告诉我为什么它会显示错误

2 个答案:

答案 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; }

或您希望允许在您的标识符中使用初始字母字符的任何其他内容。