【问题标题】:Antlr: how to match everything between the other recognized tokens?Antlr:如何匹配其他已识别令牌之间的所有内容?
【发布时间】:2017-08-28 02:31:47
【问题描述】:

如何匹配词法分析器中其他标记之间的所有剩余文本?

这是我的代码:

grammar UserQuery;

expr:  expr AND expr
    | expr OR expr
    | NOT expr
    | TEXT+
    | '(' expr ')'
    ;

OR  :    'OR';
AND :    'AND';
NOT :    'NOT';
LPAREN : '(';
RPAREN : ')';

TEXT: .+?;

当我在“xx AND yy”上运行词法分析器时,我得到了这些标记:

x type:TEXT
x type:TEXT
  type:TEXT
AND type:'AND'
  type:TEXT
y type:TEXT
y type:TEXT

这种方法有效,只是我不希望每个字符都成为标记。我想将所有剩余的文本合并到一个 TEXT 标记中。

【问题讨论】:

    标签: antlr antlr4 lexical-analysis


    【解决方案1】:

    我认为如果没有分隔符,这是不可能的,否则贪婪 (?) 词法分析器标记将匹配您的输入,包括您的显式标记,其原则是最长匹配会在词法分析器中获胜令牌。

    现在,如果您可以接受需要一个分隔符来描绘文本,并添加一个简单的空白规则来处理其间的空格,那么您会得到这样的结果:

    [@0,0:14=''longest token'',<TEXT>,1:0]
    [@1,16:18='AND',<'AND'>,1:16]
    [@2,20:23=''yy'',<TEXT>,1:20]
    [@3,24:23='<EOF>',<EOF>,1:24]
    

    从这个语法:

    grammar UserQuery;
    
    expr:  expr AND expr
        | expr OR expr
        | NOT expr
        | TEXT
        | '(' expr ')'
        ;
    
    OR  :    'OR';
    AND :    'AND';
    NOT :    'NOT';
    LPAREN : '(';
    RPAREN : ')';
    
    TEXT : '\'' .*? '\'';
    WS: [ \t\r\n] -> skip;
    

    使用此输入:

    'longest token' AND 'yy'
    

    这与编程语言中经常处理 cmets 和字符串的方式非常相似,其中有一个开始和结束分隔符,并且中间的所有内容都被标记为一个大标记。通常使用 cmets 我们会丢弃它们,但在这里我们像保留字符串一样保留它们。希望这会有所帮助。

    【讨论】:

    • 确实有帮助,谢谢。不过,这将迫使我更改查询语言。尽量不要那样做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 2018-07-08
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    相关资源
    最近更新 更多