2016-03-28 48 views
4

我一直在使用antlr 3天。我可以解析表达式,编写Listener,解析解析树......这是梦想成真。antlr文字字符串匹配:我做错了什么?

但后来我试图匹配一个字符串'富%',我失败了。我可以找到很多声称这样做的例子。我已经全部尝试过了。

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

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 

全Maven的美化版构建树是可用于快速审查here

31行代码。其中大部分是从小例子中借用的。

$ mvn clean test 

使用antlr-4.5.2-1。

+0

你的错误就在于,'stringLiteral'是一个解析器规则,但它应该是一个词法分析器规则。使它的名字以大写字母开头(或者完全用大写字母写出来,这样更容易作为词法分析规则)。 –

+0

谢谢!这使问题变得非常清楚! –

回答

2

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

而且,这是更好地扩大你的否定类~('\n'|'\r')包括一个反斜杠和引号,你可能要包括一个反斜杠,以便能够进行转义:

clause 
    : StringLiteral EOF 
    ; 

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

fragment Escape : '\\' ('\'' | '\\'); 
+0

谢谢!有一点区别(大写)有所不同,现在我明白了解析器规则与词法分析器的不同之处! –