首页 > 解决方案 > 在跳过空格的同时将单个单词解析为多个标记

问题描述

我有一种语言,其中空格是微不足道的,所以我跳过它。这是我到目前为止的语法的一个子集:

start: expr <EOF>;
expr
    : atom
    | expr '|' expr
    | expr expr+
    | '{' expr '}'
    ;
atom
    : ATOM_TOKEN
    ;
fragment LETTER: [a-zA-Z];
fragment DIGIT: [0-9];
ATOM_TOKEN: (LETTER | DIGIT)+;
WS: [ \r\n\t]+ -> skip;

当在以下输入上执行时(注意空格和缺少空格),它会正确生成所需的预期解析树:

{hello42   |  hi world}|{good bye} red blue green

解析树

现在,我的问题是理想情况下我想制定atom一个嵌套规则,以便我可以挑选出具有代表性的部分。

这是一个示例语法:

atom: atomToken+;
atomToken
    : LETTERS
    | DIGITS
    ;
LETTERS: LETTER+;
DIGITS: DIGIT+;

以及he11o通过它运行的结果(注意 1 而不是 L):

原子解析树

这种方法的问题在于,由于忽略了空格,he11o world因此现在将解析为单个atom.

有什么明显的我失踪了吗?根据我的研究,出现了几种可能性。

  1. 当我实际需要提取atom. 这似乎是最简单的解决方案。
  2. 通过对生成的 Lexer 进行子类化来实现某种令牌注入。这似乎很hacky,除非没有更好的选择,否则我想避免它。
  3. 使用词汇模式或通道做一些事情,以便仅有条件地跳过空格?我很确定这不会起作用,因为触发它的上下文将来自解析器,据我所知,您无法从解析器规则更改词法分析器行为。
  4. 不要跳过空格,而是在主要语法中乱扔所有可能出现的空格。

任何帮助表示赞赏。

标签: antlr4

解决方案


推荐阅读