【问题标题】:ANTLR4 - parsing `any string` without consuming the whole inputANTLR4 - 解析“任何字符串”而不消耗整个输入
【发布时间】:2016-11-25 17:05:05
【问题描述】:

我正在尝试解析以下文本格式:

<identifier> {
    <identifier> : <any-text-without-white-space-or-new-line> : <identifier>
    <identifier> : <identifier>.<identifier>
}

例如:

john {
    name : JohnJohnson.12.453.643-USA[NewYork] : default
    reference : something.else
}

我创建了以下语法:

SPACE          : [ \t\r\n]+ -> skip;
LEFT_BRACE     : '{';
RIGHT_BRACE    : '}';
COLON          : ':';
DOT            : '.';
ID             : [a-z]+
ANY            : ~(' '|'\t'|'\r'|'\n')+;

outer          : ID LEFT_BRACE inner_first inner_second RIGHT_BRACE EOF;
inner_first    : ID COLON (ANY | ID) COLON ID;
inner_second   : ID COLON ID DOT ID;

这个语法的问题是第二行输入中的&lt;identifier&gt;.&lt;identifier&gt;被识别为

ANY

而不是像

ID DOT ID

如果我将ANY 的定义更改为:

ANY            : ~(' '|'\t'|'\r'|'\n'|'.')+;

但这意味着. 符号不能再成为第一行任意文本的一部分。

这似乎是一个先有鸡还是先有蛋的问题。这可以解决吗?

(FWIW,我正在看好书The Definitive ANTLR 4 Reference,这是我前段时间买的,但我还没有找到解决方案。)

【问题讨论】:

    标签: java parsing antlr antlr4 lexer


    【解决方案1】:

    您总是可以让词法分析器规则标记最小数量,并使用一些解析器规则而不是词法分析器规则来表示您想要的任何组合。比方说:

    my_desired_seq     : NON_WS_CRLF_DOT_SEQ  DOT NON_WS_CRLF_DOT_SEQ  ;
    NON_WS_CRLF_DOT_SEQ      : ~(' '|'\t'|'\r'|'\n'|'.')+;
    

    而语法的其他部分使用解析器规则:

    inner_second   : ID COLON my_desired_seq;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多