【问题标题】:How to consume text until newline in ANTLR?如何在 ANTLR 中使用文本直到换行符?
【发布时间】:2012-01-21 15:30:08
【问题描述】:

你如何用 ANTLR 做这样的事情?

示例输入:

title: hello world

语法:

header : IDENT ':' REST_OF_LINE ;
IDENT : 'a'..'z'+ ;
REST_OF_LINE : ~'\n'* '\n' ;

它失败了,line 1:0 mismatched input 'title: hello world\n' expecting IDENT

(我知道 ANTLR 用于解析类似 MIME 的标头是多余的,但这只是在一个更复杂的文件的顶部。)

【问题讨论】:

    标签: antlr


    【解决方案1】:

    失败,第 1:0 行不匹配输入 'title: hello world\n' 期待 IDENT

    您必须了解词法分析器独立于解析器运行。无论解析器在某个时间“想要”匹配什么,词法分析器都会按照一些严格的规则创建标记:

    1. 尝试在词法分析器规则中从上到下匹配标记(首先尝试先定义的规则);
    2. 匹配尽可能多的文本。如果 2 个规则匹配相同数量的文本,则首先定义的规则将被匹配。

    由于规则 2,您的 REST_OF_LINE 将始终从 IDENT 规则中“获胜”。唯一会创建IDENT 令牌的时间是最后没有\n。这就是你的语法出了什么问题:错误消息指出它需要一个 IDENT 令牌,但没有找到(但产生了一个 REST_OF_LINE 令牌)。

    我知道 ANTLR 在解析类似 MIME 的标头方面是多余的,但这只是在一个更复杂的文件的顶部。

    您不能只定义要应用于文件头的标记(词法分析器规则)。这些标记也将应用于更复杂的文件的其余部分。也许您应该将标头与文件的其余部分分开预处理?

    【讨论】:

      【解决方案2】:

      antlr 解析通常分两步完成。 1. 构建你的 ast 2. 定义你的语法

      伪代码(我玩 antlr 已经有几年了)- AST:

      WORD : 'a'..'z'+ ;
      SEPARATOR : ':';
      SPACE : ' ';
      

      伪代码 - 树解析器:

      header: WORD SEPARATOR WORD (SPACE WORD)+
      

      希望对您有所帮助....

      【讨论】:

      • 很遗憾,我想读到行尾的所有文本,其中可能包括数字、字母、标点符号。
      • 不,您不是从 AST 开始,而是从语法开始。此外,生成 AST 甚至不是强制性的:您可以只使用解析树。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-07
      • 2014-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多