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

Eri*_*ton 5 string-literals antlr4

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

但后来我尝试匹配文字字符串“foo%”,但失败了。我可以找到很多声称可以做到这一点的例子。我都试过了。

所以我创建了一个小项目来匹配文字字符串。我一定是在做一些愚蠢的事情。

grammar Test;

clause
  : stringLiteral EOF
  ;

fragment ESCAPED_QUOTE : '\\\'';
stringLiteral :   '\'' ( ESCAPED_QUOTE | ~('\n'|'\r') ) + '\'';
Run Code Online (Sandbox Code Playgroud)

简单测试:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

结果:

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
Run Code Online (Sandbox Code Playgroud)

完整的 Maven 化构建树可在此处快速查看

31 行代码……大部分是借用小例子的。

 $ mvn clean test
Run Code Online (Sandbox Code Playgroud)

使用antlr-4.5.2-1。

Bar*_*ers 4

fragment规则只能被其他词法分析器规则使用。因此,您需要制定stringLiteral词法分析器规则而不是解析器规则。只要让它以大写字母开头即可。

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

clause
  : StringLiteral EOF
  ;

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

fragment Escape : '\\' ( '\'' | '\\' );
Run Code Online (Sandbox Code Playgroud)