如何逃避flex关键字 [英] how to escape flex keyword

查看:119
本文介绍了如何逃避flex关键字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Flex&在Linux上的野牛.我有以下设置:

I am using Flex & bison on Linux. I have have the following set up:

//令牌 CREATE {返回令牌:: CREATE;}
SCHEMA {返回令牌:: SCHEMA; }
RECORD {返回令牌:: RECORD;}
[_a-zA-Z0-9] [_ a-zA-Z0-9] * {yylval-> strval = strdup(yytext);返回TOKEN :: NAME;}
...
//规则 创建架构名称...
创建记录名称... ...

// tokens CREATE { return token::CREATE;}
SCHEMA { return token::SCHEMA; }
RECORD { return token::RECORD;}
[_a-zA-Z0-9][_a-zA-Z0-9]* { yylval->strval = strdup(yytext); return TOKEN::NAME;}
...
// rules CREATE SCHEMA NAME ...
CREATE RECORD NAME ... ...

一切正常.但是,如果用户输入:"create schema record ..."(其中"record"是要创建的模式的名称),则Flex将报告错误,因为它与"record"作为令牌匹配并且正在寻找规则创建模式记录".我知道关键字可以转义,但这会使用户体验尴尬.我的问题是:

Everything worked just fine. But if users enter: "create schema record ..." (where 'record' is the name of the schema to be created), Flex will report an error since it matches 'record' as a token and it is looking for the rule "CREATE SCHEMA RECORD". I understand that keywords can be escaped, but that makes user experiences awkward. My question is:

"如何设计上述规则,使其接受创建模式记录..."并将此输入与创建模式名称..."相匹配?"

谢谢!

推荐答案

半保留"单词在具有很多保留单词的语言中很常见. (甚至现代C ++都有其中的几个:overridefinal.)但是它们给传统的扫描程序带来了一些困难,传统的扫描程序通常假定关键字是关键字.

"Semi-reserved" words are common in languages which have a lot of reserved words. (Even modern C++ has a couple of these: override and final.) But they create some difficulties for traditional scanners, which generally assume that a keyword is a keyword.

柠檬分析器生成器(并非巧合地用于解析SQL)具有有用的,其中上下文中无效的令牌可以由另一个令牌代替(无需更改语义值).不幸的是,野牛没有实现此功能,我所知道的任何其他解析器生成器也没有实现.但是,在许多情况下,可以在Bison语法中实现该功能.例如,在这里介绍的简单情况下,我们可以替换为:

The lemon parser generator, which not coincidentally was designed for parsing SQL, has a useful "fallback" feature, where a token which is not valid in context can be substituted by another token (without changing the semantic value). Unfortunately, bison does not implement this feature, and nor does any other parser generator I know of. However, in many cases it is possible to implement the feature in Bison grammars. For example, in the simple case presented here, we can substitute:

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

具有:

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

显然,需要注意的是,在使用name的上下文中,name的替代列表中的(半)关键字无效.这可能需要定义各种name产品,这些产品对不同的上下文有效. (这是柠檬式的后备选项更方便的地方.)

Obviously, care needs to be taken that the (semi-)keywords in the list of alternatives for name are not valid in the context in which name is used. This may require the definition of a variety of name productions, valid for different contexts. (This is where lemon-style fallbacks are more convenient.)

如果执行此操作,则必须由扫描程序或name非终结符的归约规则正确设置关键字的语义值,这一点很重要.如果只有一个name非终结符,那么在归约操作中执行此操作可能会更有效率(因为它避免了不必要的字符串分配和释放,在这种情况下,释放将使出现关键字的其他语法规则变得复杂) ,因此name规则实际上看起来像这样:

If you do this, it is important that the semantic values of the keywords be correctly set up, either by the scanner or by the reduction rule of the name non-terminal. If there is only one name non-terminal, it is probably more efficient to do it in the reduction actions (because it avoids unnecessary allocation and deallocation of strings, where the deallocation will complicate the other grammar rules in which the keywords appear), so that the name rule would actually look like this:

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

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

There are, of course, many other possible ways to deal with the semantic value issue.

这篇关于如何逃避flex关键字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆