how to escape flex keyword

本秂侑毒 提交于 2019-11-29 17:37:21

"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.

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 ...

with:

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

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.)

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.

eduffy

You shouldn't do this, for the same reason you can't have a variable in C++ named for, while, or class. But if you really want to, look into Start Conditions (it'll be messy).

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!