0

我正在学习 flex & bison,我被困在这里,无法弄清楚这样一个简单的语法规则是如何无法按预期工作的,下面是词法分析器代码:

%{

#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”,谁能告诉我为什么会显示错误

4

2 回答 2

2

[a-zA-Z].*将匹配一个字母字符,后跟任意数量的任意字符,换行符除外。换句话说,它将从字母字符匹配到行尾。

由于 flex 总是接受最长的匹配,因此该行select * from ...似乎只有一个标记,IDENTIFIER,这是一个语法错误。

于 2013-08-08T01:28:15.693 回答
1

[a-zA-Z].* { return IDENTIFIER; }

问题就在这里。它允许任何垃圾跟随初始字母字符并返回,IDENTIFIER,在这种情况下包括初始 ''s 之后的整个其余行。

它应该是:

[a-zA-Z]+          { return IDENTIFIER; }

或者可能

[a-zA-Z][a-zA-Z0-9]*          { return IDENTIFIER; }

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

于 2013-08-08T03:37:12.837 回答