antlr - 在 ANTLR 词法分析器规则中强制采用替代方案

标签 antlr antlr3 lexer

我正在尝试使用 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 为 false,我希望词法分析器退出此规则,忽略 SimpleIdent 之后的任何字符。不幸的是,ANTLR 将在测试谓词之前测试 SimpleIdent 之后的字符,因此如果那里有空格,将始终采用第二种选择。这在 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 在运行时在词法分析器中采用特定路径?

最佳答案

使用门控语义谓词而不是验证语义谓词1。如果表达式验证为 false验证谓词将引发异常。并让“没有替代方案”成为最后一个匹配的内容。

此外,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

您将得到以下解析:

enter image description here

即每当RULE以小写“a”开头时,它不会一直匹配到行尾。

1 What is a 'semantic predicate' in ANTLR?

关于antlr - 在 ANTLR 词法分析器规则中强制采用替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11838662/

相关文章:

c++ - LL(*) 解析器(如antlr3)可以解析C++吗?

lexer - 向 scintilla/scite 添加一个新的词法分析器(...最终是 wxPython StyledTextCtrl)

java - ANTLR4 - 使用 Visitor 将语法树转换为 AST

java - ANTLR4语法解析器问题

java - 如何从ANTLR语法中收集 'returns'

java - 如何在 ANTLR3 TreeParser 中获取行号

java - 如何编写 ANTLR 语法翻译器以返回带有方法的 java 类?

oop - 在构建词法分析器/扫描器时如何使用面向对象的设计范例?

regex - 词法分析器中标识符的正则表达式帮助

antlr,如何修复语法so(varname)?如果存在但错误则解析失败