Bison 如何转义flex关键字

Bison 如何转义flex关键字,bison,flex-lexer,Bison,Flex Lexer,我在Linux上使用Flex&bison。我已进行了以下设置: //代币 创建{返回标记::创建;} SCHEMA{return token::SCHEMA;} 记录{返回标记::记录;} [\u a-zA-Z0-9][\u a-zA-Z0-9]*{yylval->strval=strdup(yytext);返回标记::NAME;} … //规则 创建架构名称… 创建记录名。。。 一切都很顺利。但是如果用户输入:“创建模式记录…”(其中“记录”是要创建的模式的名称),Flex将报告一个错误,因

我在Linux上使用Flex&bison。我已进行了以下设置:

//代币 创建{返回标记::创建;}
SCHEMA{return token::SCHEMA;}
记录{返回标记::记录;}
[\u a-zA-Z0-9][\u a-zA-Z0-9]*{yylval->strval=strdup(yytext);返回标记::NAME;}

//规则 创建架构名称…
创建记录名。。。

一切都很顺利。但是如果用户输入:“创建模式记录…”(其中“记录”是要创建的模式的名称),Flex将报告一个错误,因为它匹配“记录”作为标记,并且正在查找规则“创建模式记录”。我知道关键字可以转义,但这会让用户体验尴尬。我的问题是:

如何设计上述规则,使其接受“创建架构记录…”并将此输入与“创建架构名称…”匹配?


谢谢

> P> >不应该这样做,原因与C++中的变量< <代码> > <代码> > <代码> < <代码> >或<代码>类< /代码>相同。但是如果你真的想,那就仔细研究一下(这会很混乱)。

在有很多保留词的语言中,“半保留”词很常见。(即使现代的C++也有两个这样的例子:<代码>覆盖> <代码>和<代码>最终< /代码>),但它们对传统扫描器造成了一些困难,通常假设关键字是关键字。 lemon解析器生成器(并非巧合地设计用于解析SQL)具有一个有用的功能,其中上下文中无效的令牌可以被另一个令牌替换(不改变语义值)。不幸的是,bison没有实现这个特性,我所知道的任何其他解析器生成器也没有。然而,在许多情况下,可以在Bison语法中实现该功能。例如,在这里介绍的简单案例中,我们可以替换为:

create_statement: CREATE RECORD NAME ...
                | CREATE SCHEMA NAME ...
与:

显然,需要注意的是,
name
的备选方案列表中的(半)关键字在使用
name
的上下文中无效。这可能需要定义各种
名称
产品,适用于不同的上下文。(这是lemon式回退更方便的地方。)

如果执行此操作,则必须通过扫描仪或
名称
非终端的缩减规则正确设置关键字的语义值。如果只有一个
名称
非终结符,则在缩减操作中执行此操作可能更有效(因为它避免了不必要的字符串分配和取消分配,而取消分配将使关键字出现的其他语法规则复杂化),因此,
名称
规则实际上如下所示:

name: NAME
    | CREATE   { $$ = strdup("CREATE"); }
    | RECORD   { $$ = strdup("RECORD"); }
    | SCHEMA   { $$ = strdup("SCHEMA"); }
    | ...

当然,还有许多其他可能的方法来处理语义值问题。

您提到的柠檬反馈是什么?你能举一些例子吗?“回退”,而不是反馈。中的文档。我能给你指出的唯一例子是205行的。虽然真的没什么可看的;有趣的是这个功能的存在。听起来柠檬方式更简洁。要在flex/bison中执行同样的操作,如果有许多关键字需要回退,语法可能会变得过于复杂。是吗?@user1424739:是的,这是一个有用的功能。在sqlite3 SQL解析器示例中,我没有看到终止“.”。但手册提到了这一点。手册过时了吗?
name: NAME
    | CREATE   { $$ = strdup("CREATE"); }
    | RECORD   { $$ = strdup("RECORD"); }
    | SCHEMA   { $$ = strdup("SCHEMA"); }
    | ...