【问题标题】:Trying to use keywords as identifiers in ANTLR4; not working尝试在 ANTLR4 中使用关键字作为标识符;不工作
【发布时间】:2016-02-09 23:14:12
【问题描述】:

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

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

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

regular_ident :  // (1)
        KEYWORD_AS_IDENT
        |
        REGULAR_IDENT
    ;

REGULAR_IDENT 是 idents 的主要 lex 规则。大致是这样的(这里简化了),并且有效:

REGULAR_IDENT :
        [a-zA-Z]  ( [a-zA-Z0-9] * )
    ;

KEYWORD_AS_IDENT 是特殊词列表,摘录如下:

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
    ;

fetch sparse 突然没问题,因为它现在将“稀疏”视为常规标识符:

但为什么 (1) 不起作用? 我可以通过内联所有 KEYWORD_AS_IDENT 来轻松修复它,但我需要知道我缺少什么。

感谢所有建议。

【问题讨论】:

    标签: antlr4


    【解决方案1】:

    来自 google group antlr-discussion 的 Eric Vergnaud 的回复:

    LASTKEYWORD_AS_IDENT 之前声明,所以当词法分析器 遇到“最后一个”,它会生成一个 LAST 令牌,而不是 KEYWORD_AS_IDENT。您的开始规则不接受 LAST 令牌作为 有效的输入,因此大喊大叫。你的语法实际上永远不会 产生一个KEYWORD_AS_IDENT 令牌,因为另一个有效令牌将 之前的比赛。看来您正试图让词法分析器完成以下工作 解析器,即处理多种语义替代方案,但当时 令牌到达解析器为时已晚...您是否尝试过制作 KEYWORD_AS_IDENT 是解析器规则(小写)而不是词法分析器规则?

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

    【讨论】:

      【解决方案2】:

      我在自己的语法中使用了您的第二种方法(例如MySQL.g),因为这是使其可靠工作的唯一方法。然而,这仍然是 ANTLR3。我使用了一种技巧来更改规则 keyword 识别的令牌类型,以便它返回 IDENTIFIER,而不是单个关键字令牌。

      【讨论】:

      • "...只有这样才能让它可靠地工作"。好奇的。似乎不可能这是一个错误,但我会挖掘并尝试最小化重现。至于关键字hackery,如果语言很糟糕,而TSQL是,解析只反映了这一点。谢谢
      猜你喜欢
      • 2011-10-02
      • 2022-01-01
      • 1970-01-01
      • 2011-04-30
      • 2022-10-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多