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

C++ 为什么野牛中的简单语法规则不起作用?,c++,parsing,bison,flex-lexer,C++,Parsing,Bison,Flex Lexer,我正在学习flex&bison,我被困在这里,无法理解这样一个简单的语法规则如何不能像我预期的那样工作,下面是lexer代码: %{ #include <stdio.h> #include "zparser.tab.h" %} %% [\t\n ]+ //ignore white space FROM|from { return FROM; } select|SELECT { return SELECT; } update|

我正在学习flex&bison,我被困在这里,无法理解这样一个简单的语法规则如何不能像我预期的那样工作,下面是lexer代码:

%{

#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某物放入时,为什么会显示错误吗?

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

因为flex总是接受最长的匹配,所以行select*from。。。将显示只有一个标记、标识符,这是一个语法错误。

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

因为flex总是接受最长的匹配,所以行select*from。。。将显示只有一个标记、标识符,这是一个语法错误

[a-zA-Z].{返回标识符;}

问题就在这里。它允许任何垃圾跟随初始字母字符并作为标识符返回,在这种情况下,包括初始s之后的整个行的剩余部分

应该是:

[a-zA-Z]+          { return IDENTIFIER; }
或者可能

[a-zA-Z][a-zA-Z0-9]*          { return IDENTIFIER; }
或者您希望允许在标识符中的初始alpha字符后面跟随的任何内容

[a-zA-Z].{返回标识符;}

问题就在这里。它允许任何垃圾跟随初始字母字符并作为标识符返回,在这种情况下,包括初始s之后的整个行的剩余部分

应该是:

[a-zA-Z]+          { return IDENTIFIER; }
或者可能

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

或者您希望允许在标识符中的初始字母字符后面添加任何其他字符。

小心标记。Flex标记用于Adobe/ApacheUI框架。Flex lexer标记用于词法分析器。显示什么错误,在什么标记处?小心标记。Flex标记用于Adobe/ApacheUI框架。Flex lexer标记用于词法分析器。显示了什么错误,在什么标记处?我知道了,但我仍然想问,这是匹配的唯一标准,我是指最长的匹配规则吗?实际上,我要做的是编写一个模式,该模式将匹配任何以字母表开头的标识符,而不是我已经为上述规则编写的关键字之一。@smit:您需要更精确一些。标识符不能由任何字符组成;通常,它必须是一个字母,后跟一系列字母或数字,可能还有一些其他有效字符,如u或$。例如,[a-zA-Z][a-zA-Z0-9]*只有字母和数字。为了避免与关键字冲突,您需要将关键字放在第一位,因为flex会从最长的匹配中选择第一个匹配项,也就是说,首先它会找到最长的匹配项,然后选择与之匹配的第一个模式。我实际上没有尝试过它,但您放在这里的是[a-zA-Z][a-zA-Z0-9]*它是否会与“选择”或“更新”等关键字不匹配?我的意思是,它们也以字母开头,后跟一些字符或数字…这让我很困惑。@smit:是的,它会匹配。在这种情况下,将有两条规则匹配,flex将选择第一条。正如我所说,flex首先找出哪些规则具有最长的匹配,然后如果有多个规则,则选择第一个这样的规则。所以你需要把关键词规则放在你的文件中,就像你做的那样。我知道了,但我仍然想问,这是匹配的唯一标准吗,我是说最长的匹配规则?实际上,我要做的是编写一个模式,该模式将匹配任何以字母表开头的标识符,而不是我已经为上述规则编写的关键字之一。@smit:您需要更精确一些。标识符不能由任何字符组成;通常,它必须是一个字母,后跟一系列字母或数字,可能还有一些其他有效字符,如u或$。例如,[a-zA-Z][a-zA-Z0-9]*只有字母和数字。为了避免与关键字冲突,您需要将关键字放在第一位,因为flex会从最长的匹配中选择第一个匹配项,也就是说,首先它会找到最长的匹配项,然后选择与之匹配的第一个模式。我实际上没有尝试过它,但您放在这里的是[a-zA-Z][a-zA-Z0-9]*它是否会与“选择”或“更新”等关键字不匹配?我的意思是,它们也以字母开头,后跟一些字符或数字…这让我很困惑。@smit:是的,它会匹配。在这种情况下,将有两条规则匹配,flex将选择第一条。正如我所说,flex首先找出哪些规则具有最长的匹配,然后如果有多个规则,则选择第一个这样的规则。因此,您需要将关键字规则放在您的文件中的第一位,就像您所做的那样。您可以帮助我编写一个规则,以匹配任何不属于某个关键字的标识符吗?我可能要添加更多关键字later@smit我刚才在我的回答中正是这样做的。多么可笑的要求 您可以帮助我编写一个规则,以匹配任何不属于某个关键字的标识符,我可能需要添加更多关键字later@smit我刚才在我的回答中正是这样做的。多么可笑的要求。