为什么我的ANTLR 4解析器规则没有返回所需的值?

时间:2015-11-30 21:44:07

标签: parsing antlr antlr4

我正在尝试将ANTLR 4.3与相同版本的antlr4-maven-plugin一起使用,以实现两个目标:

  1. 根据相当简单的语法验证用户提供的表达式,以防止注入无效或潜在危险的代码。
  2. 重写表达式中的标识符,使其使用点表示法完全限定,例如: context.identifier
  3. 我遇到了第2项的问题。因为我只需要对输入表达式进行非常小的修改,使用带有返回值的解析器规则似乎是合适的解决方案。但是,解析器返回原始标识符,而不是我希望看到的重写标识符。

    这是用于说明行为的语法的简化版本:

    grammar Sample;
    
    expr
     : ( field_name ) EOF
     ;
    
    field_name returns [String fqn]
     : any_name { $fqn = "prefix." + $text; }
     ;
    
    any_name
     : IDENTIFIER
     | STRING_LITERAL
     | '(' any_name ')'
     ;
    
    IDENTIFIER
     : '"' (~'"' | '""')* '"'
     | '`' (~'`' | '``')* '`'
     | '[' ~']'* ']'
     | [a-zA-Z_] [a-zA-Z_0-9]*
     ;
    
    STRING_LITERAL
     : '\'' ( ~'\'' | '\'\'' )* '\''
     ;
    

    field_name规则旨在将限定符添加到它遇到的任何名称,并返回完全限定名称。但是,在我的测试中,这似乎永远不会起作用:

    package sample;
    
    import static org.junit.Assert.assertEquals;
    
    import org.antlr.v4.runtime.ANTLRInputStream;
    import org.antlr.v4.runtime.BailErrorStrategy;
    import org.antlr.v4.runtime.CharStream;
    import org.antlr.v4.runtime.CommonTokenStream;
    import org.antlr.v4.runtime.ParserRuleContext;
    import org.antlr.v4.runtime.TokenStream;
    import org.junit.Test;
    
    public class SampleParserTest {
    
        @Test
        public void testSampleParser() {
            CharStream input = new ANTLRInputStream("field1");
            SampleLexer lexer = new SampleLexer(input);
            CommonTokenStream tokens = new CommonTokenStream(lexer);
            SampleParser parser = new SampleParser(tokens);
            BailErrorStrategy errorHandler = new BailErrorStrategy();
            parser.setErrorHandler(errorHandler);
            ParserRuleContext tree = parser.expr();
            TokenStream tokenStream = parser.getTokenStream();
            String fqn = tokenStream.getText(tree);
            assertEquals("prefix.field1", fqn);
            // org.junit.ComparisonFailure: expected:<[prefix.]field1> but
            // was:<[]field1>
        }
    
    }
    

    我的语法或单元测试阻止了field_name规则返回预期的完全限定名称有什么问题?还有其他(更好的)方法来实现相同的目标吗?

    提前感谢您的时间和专业知识。

0 个答案:

没有答案