当前位置: 首页 > 知识库问答 >
问题:

在ANTLR4中尝试使用关键字作为标识符;不起作用

凌轶
2023-03-14

我试图让一些sql关键字作为标识符被接受,当用作标识符时。Antlr的书p210提出了这个技巧:

id : 'if' | 'call' | 'then' | ID ;

我也有类似的东西,但它不起作用,我想这是我的误解。regular_ident是标识符的解析规则,因此:

regular_ident :  // (1)
        KEYWORD_AS_IDENT
        |
        REGULAR_IDENT
    ;

regular_ident是ident的主要lex规则。大致是这样的(这里简化了),它起作用了:

REGULAR_IDENT :
        [a-zA-Z]  ( [a-zA-Z0-9] * )
    ;
KEYWORD_AS_IDENT :  // (2)
[...snip...]
  | FILESTREAM
  | SPARSE
  | NO
  | ACTION
  | PERSISTED
  | FILETABLE_DIRECTORY
  | FILETABLE_COLLATE_FILENAME
  | FILETABLE_PRIMARY_KEY_CONSTRAINT_NAME
  | FILETABLE_STREAMID_UNIQUE_CONSTRAINT_NAME
  | FILETABLE_FULLPATH_UNIQUE_CONSTRAINT_NAME
  | COLUMN_SET
  | ALL_SPARSE_COLUMNS
 ;
SPARSE : 'sparse' ;
NO     : 'no'
(etc)

如果我给它fetch aaa作为输入('aaa'不是关键字),它将解析:

但是如果我给它fetch sparse,它就会失败--'sparse'是一个关键字:

也许我很笨,但我不明白为什么,因为sparsekeyword_as_ident的成员。如果我将(2)中的一些剪切并粘贴到(1)中,得到以下内容:

regular_ident :
    FILESTREAM
  | SPARSE
  | NO
  | ACTION
  | PERSISTED
  | FILETABLE_DIRECTORY
        |
    REGULAR_IDENT
    ;

感谢所有建议。

共有1个答案

孙博艺
2023-03-14

谷歌集团ANTLR的Eric Vergnaud的回复-讨论:

lastkeyword_as_ident之前声明,因此当lexer遇到“last”时,它将生成last标记,而不是keyword_as_ident。您的start规则不接受last标记作为有效输入,因此会出现喊叫。您的语法实际上永远不会生成keyword_as_ident标记,因为前面会匹配另一个有效的标记。您似乎试图让lexer完成解析器的工作,即处理多个语义替换,但当令牌到达解析器时,为时已晚······您是否尝试过将KEYWORD_AS_IDENT设置为解析器规则(小写)而不是lexer规则?

所以我对lexer的理解是错误的,他是正确的,我试图让它完成解析器的工作。

 类似资料:
  • 我有以下问题:我正在为GLSL着色语言创建一个编辑器。我希望在某些情况下允许关键字作为标识符,因为内置函数的名称可以用作标识符。 例如: 和不被识别为标识符。 完整语法供参考:http://paste2.org/YwDNkBYW 解决方案: 我创建了一个包含所有内置函数的源文件: 我使用保留的关键字来区分内置函数和本地创建的函数: ...在ScopeProvider中添加了以下内容: 在中,我在迭

  • 我一直在用C语言,用clang编译。我想包括 不幸的是,这个标题对一些字段名(比如第727行)使用了,这是C语言中的一个关键字。 有没有办法解决这个问题? xcb/xkb. h:

  • 问题内容: Python 2.7.5 (default, Feb 26 2014, 13:43:17) [GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2 Type “help”, “copyright”, “credits” or “license” for more information. >>> import sys >>> try: … sy

  • 我正在编写一个解析器来解析字符串,比如 antlr4语法文件如下所示: 如果我把def加回来,就会出现错误: 属性:1:0:不匹配 输入“aaa.bb”应为ATTR_ID 注意:如果输入字符串为:则可以工作

  • 我首先查看了新的ASP.NET标识类和它使用实体框架代码创建的数据库上的接口。我使用的是Visual Studio 2013 RC。 乍一看,数据库模式看起来相当正常: 但是所有的键都是NVARCHAR(128) http://www.asp.net/identity/overview/extensibility/change-primary-key-for-users-in-aspnet-ide

  • 问题内容: 我在OCJP for Java6的书中读到了带有断言的部分。我到达了那一部分,它概述了如果将“ assert”一词用作关键字或标识符时编译器的反应。 a 和an有什么区别?谁能给我一个简单的解释,并同时给我一个或多个例子? 问题答案: 术语“关键字”和“标识符”不是Java特定的。 关键字是Java关键字列表中的保留字,可为编译器提供指令。由于保留了关键字,因此程序员不能将其用于变量或