我正在尝试将ANTLR 4.3与相同版本的antlr4-maven-plugin一起使用,以实现两个目标:
context.identifier
。我遇到了第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规则返回预期的完全限定名称有什么问题?还有其他(更好的)方法来实现相同的目标吗?
提前感谢您的时间和专业知识。