antlr文本字符串匹配:我做错了什么



我已经使用antlr三天了。我可以解析表达式,编写监听器,解释解析树。。。这是梦想成真。

但后来我尝试匹配一个文本字符串"foo%",结果失败了。我可以找到很多声称这样做的例子。我都试过了。

所以我创建了一个小项目来匹配一个文字字符串。我一定在做傻事。

grammar Test;
clause
  : stringLiteral EOF
  ;
fragment ESCAPED_QUOTE : '\'';
stringLiteral :   ''' ( ESCAPED_QUOTE | ~('n'|'r') ) + ''';

简单测试:

public class Test {
    @org.junit.Test
    public void test() {
        String input = "'foo%'";
        TestLexer lexer = new TestLexer(new ANTLRInputStream(input));
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        TestParser parser = new TestParser(tokens);
        ParseTree clause = parser.clause();
        System.out.println(clause.toStringTree(parser));
        ParseTreeWalker walker = new ParseTreeWalker();
    }
}

结果:

Running com.example.Test
line 1:1 token recognition error at: 'f'
line 1:2 token recognition error at: 'o'
line 1:3 token recognition error at: 'o'
line 1:4 token recognition error at: '%'
line 1:6 no viable alternative at input '<EOF>'
(clause (stringLiteral ' ') <EOF>)
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.128 sec - in com.example.Test
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

完整的专业化构建树可在这里快速查看

31行代码。。。它大多借鉴了一些小例子。

 $ mvn clean test

使用antlr-4.5.2-1。

fragment规则只能由其他lexer规则使用。因此,您需要使stringLiteral成为lexer规则,而不是解析器规则。让它以大写字母开头。

此外,最好将否定类~('n'|'r')扩展为包含反斜杠和引号,并且您可能希望包含能够转义的反斜杠:

clause
  : StringLiteral EOF
  ;
StringLiteral :   ''' ( Escape | ~(''' | '\' | 'n' | 'r') ) + ''';
fragment Escape : '\' ( ''' | '\' );

相关内容

  • 没有找到相关文章

最新更新