【问题标题】:Antlr hidden channel whitespace problemAntlr 隐藏通道空白问题
【发布时间】:2010-11-11 23:45:21
【问题描述】:

我有以下 Antlr 语法:

grammar MyGrammar;

doc :   intro planet;
intro   :   'hi';
planet  :   'world';
MLCOMMENT 
    :   '/*' ( options {greedy=false;} : . )* '*/' { $channel = HIDDEN; };
WHITESPACE : ( 
    (' ' | '\t' | '\f')+
  |
    // handle newlines
    ( '\r\n'  // DOS/Windows
      | '\r'    // Macintosh
      | '\n'    // Unix
    )
    )
 { $channel = HIDDEN; };

在 ANTLRWorks 1.2.3 解释器中,输入 hi worldhi/**/worldhi /*A*/ world 正常工作。

然而,输入hiworld不应该工作,也被接受。 如何使hiworld 失败?如何在“hi”和“world”之间强制使用至少一个空格(或注释)?

请注意,我在此示例中仅使用了 MLCOMMENT 和 WHITESPACE 来简化,但也支持其他类型的 cmets。

【问题讨论】:

  • 好吧,我不知道 Antlr,但“doc: intro WHITESPACE planet”或类似的东西不是最明显的吗?
  • 由于通道 WHITESPACE 被隐藏,导致 MismatchedTokenException。
  • 那你就不能再创建一个不隐藏的空白语法并使用它吗?
  • 我可以,我暂时使用你的方法,但是为什么每个教程都建议使用HIDDEN频道或skip()呢?

标签: whitespace antlr channel


【解决方案1】:

您需要创建一个通用 ID 令牌。由于词法分析器可以构建最长的标记,它会将输入“hiworld”视为一个单词,因为它本身比“hi”或“world”长。这样的规则可能如下所示:

ID : ('a'..'z' | 'A'..'Z')+;

例如,编程语言的解析器就是这样将“do”关键字与“double”(关键字类型,以“do”开头)或“done”(变量名)分开的。

【讨论】:

  • 这个答案让很多事情都在我脑海中浮现。谢谢
【解决方案2】:

使字符串hiworld 失败的一种方法是使用保证失败的验证语义谓词,如下所示:

doc:      intro planet;
failure : 'hiworld' { false }?;
intro   : 'hi';
planet  : 'world';
// rest of grammar omitted

【讨论】:

  • 非常有趣,但如果我将每一个可能的失败案例都添加到更复杂的语法中,失败情况的数量将呈指数级增长。
猜你喜欢
  • 1970-01-01
  • 2012-04-02
  • 1970-01-01
  • 1970-01-01
  • 2018-06-19
  • 2013-04-25
  • 2014-11-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多