【问题标题】:Forcing an alternative in ANTLR lexer rule在 ANTLR 词法分析器规则中强制替代
【发布时间】:2012-08-07 03:00:08
【问题描述】:

我正在尝试使用 ANTLR 编写上下文相关的词法分析器规则,但无法让它完成我需要的工作。该规则需要根据在规则开头找到的字符匹配 2 个备选方案中的 1 个。下面是问题的简化版本。

本例语法:

lexer grammar X;

options
{
  language = C;
}

RULE :
  SimpleIdent {ctx->someFunction($SimpleIdent);}
  (
    {ctx->test != true}?
     //Nothing
  | {ctx->test == true}?
     SLSpace+ OtherText
  )
  ;

fragment SimpleIdent  : ('a'..'z' | 'A'..'Z' | '_')+;
fragment SLSpace    : ' ';
fragment OtherText :  (~'\n')* '\n';

如果 ctx->test 为假,我希望词法分析器退出此规则,忽略 SimpleIdent 之后的任何字符。不幸的是,ANTLR 将在 SimpleIdent before 测试谓词之后测试该字符,因此如果那里有空格,它将始终采用第二种选择。这在 C 代码中清楚地显示:

// X.g:10:3: ({...}?|{...}? ( SLSpace )+ OtherText )
{
    int alt2=2;
    switch ( LA(1) )
    {
    case '\t':
    case ' ':
        {
            alt2=2;
        }
        break;

    default:
        alt2=1;
    }

    switch (alt2)
    {
    case 1:
        // X.g:11:5: {...}?
        {
            if ( !((ctx->test != true)) )
            {
                    //Exception
            }

        }
        break;
    case 2:
        // X.g:13:5: {...}? ( SLSpace )+ OtherText
        {
            if ( !((ctx->test == true)) )
            {
                   //Exception
            }

如何强制 ANTLR 在运行时在词法分析器中采用特定路径?

【问题讨论】:

    标签: antlr antlr3 lexer


    【解决方案1】:

    使用门控语义谓词而不是验证语义谓词1。如果表达式验证为false验证谓词会引发异常。并让 “Nothing Alternative” 成为最后一个匹配的对象。

    另外,OtherText 也匹配 SLSpace,使 SLSpace+ OtherText 模棱两可。只需从中删除SLSpace+,或让OtherText' ' 以外的其他名称开头。

    我对 C 目标不是很熟悉,但是这个 Java 演示对 C 来说应该可以正常工作(当然是在翻译 Java 代码之后):

    grammar T;
    
    rules
     : RULE+ EOF
     ;
    
    RULE
     : SimpleIdent {boolean flag = $SimpleIdent.text.startsWith("a");}
       ( {!flag}?=> OtherText
       |            // Nothing
       )
     ;
    
    Spaces 
     : (' ' | '\t' | '\r' | '\n')+ {skip();}
     ;
    
    fragment SimpleIdent : ('a'..'z' | 'A'..'Z' | '_')+;
    fragment OtherText   : (~'\n')* '\n';
    

    如果您现在解析输入:

    abcd efgh ijkl mnop
    bbb aaa ccc ddd
    
    

    你会得到以下解析:

    即只要RULE 以小写"a" 开头,它就不会一直匹配到行尾。

    1What is a 'semantic predicate' in ANTLR?

    【讨论】:

    • 这适用于我的问题中的简化案例。不幸的是,在更复杂的规则(具有 DFA 预测功能的规则)中,ANTLR 将门控语义谓词转换为验证语义谓词。我似乎无法强制 ANTLR 始终根据运行时确定的条件选择路径。
    • @Adam12,在这种情况下,请考虑提供一个更能代表您的语法的规则。
    • 我看到了 ANTLR 现在在做什么。它将谓词提升到预测函数中,但在规则函数中再次检查它们。
    猜你喜欢
    • 1970-01-01
    • 2021-07-20
    • 1970-01-01
    • 2014-06-29
    • 1970-01-01
    • 2012-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多