ANTLR4 词法分析器如何消耗更多的任何令牌并停止现有规则?

How ANTLR4 lexer consume more any tokens and stop at existing rules?

提问人:eaglewu 提问时间:10/7/2023 更新时间:10/7/2023 访问量:46

问:

ANTLR4 词法分析器是否可以消耗更多的任何令牌并停止现有规则? 期望将更多字符消耗到一个令牌中。

小规则

lexer grammar PhpLexer;

options {
    superClass = PhpLexerBase;
    caseInsensitive = true;
}

T_OPEN_TAG_WITH_ECHO: '<?='  -> pushMode(PHP);
T_OPEN_TAG: PhpOpenTag -> pushMode(PHP);

T_INLINE_HTML: .+?;      // Problem Point

mode PHP;
   T_CLOSE_TAG: '?>';
   T_BAD_CHARACTER: .;

fragment NEWLINE: '\r'? '\n' | '\r';

fragment PhpOpenTag
    : '<?php' ([ \t] | NEWLINE)
    | '<?php' EOF
    ;

输入:

<html><?php echo "Hello, world!"; ?></html>

有:

T_INLINE_HTML -> "<"
T_INLINE_HTML -> "h"
T_INLINE_HTML -> "t"
T_INLINE_HTML -> "m"
T_INLINE_HTML -> "l"
T_INLINE_HTML -> ">"
T_OPEN_TAG -> "<?php "
……

期望:

T_INLINE_HTML -> "<html>"
T_OPEN_TAG -> "<?php "
……
php 令牌 antlr4 词法分析器

评论


答:

1赞 Bart Kiers 10/7/2023 #1

请注意,结果与写入相同:两者将始终匹配单个字符。T_INLINE_HTML: .+?;T_INLINE_HTML: .;

尝试这样的事情:

T_INLINE_HTML
 : T_INLINE_HTML_ATOM+
 ;

fragment T_INLINE_HTML_ATOM
 : ~'<'               // match a char other than '<'
 | '<' ~'?'           // match a '<' followed by something other than '?'
 | '<?' ~[p=]         // match '<?' followed by something other than '?' and '='
 | '<?p' ~'h'         // match '<?p' followed by something other than 'h'
 | '<?ph' ~'p'        // match '<?ph' followed by something other than 'p'
 | '<?php' ~[ \t\r\n] // match '<?php' followed by something other than a space char
 ;

评论

0赞 eaglewu 10/7/2023
谢谢巴特,它有效。顺便问一下,当有很多规则时,有更好的解决方案吗?而不是一个接一个地反转
0赞 Bart Kiers 10/8/2023
别客气。不,没有:您需要一个接一个地完成它们。