由于某种原因,Antlr 没有生成访问方法
Antlr not producing a visit method for some reason
Java 中的以下语法不会生成带有“visitExpr”的访问者,我不知道为什么...我添加了 valueExpression,它确实生成了 visitValueExpression,但这并没有成功很容易从所有数学表达式中得到一个表达式。
grammar Txml;
program: statement (NEWLINE statement)* NEWLINE? EOF;
statement: require # Condition
| entry # CreateEntry
| assignment # Assign
;
require: REQUIRE valueExpression;
valueExpression: expr;
expr: lhs=expr ('*' | '/') rhs=expr # MulDiv
| lhs=expr ('+' | '-') rhs=expr # AddSub
| lhs=expr '%' rhs=expr # Mod
| lhs=expr '^' rhs=expr # Pow
| '(' expr ')' # Parens
| NUMBER # NumberLiteral
| IDENT '(' args ')' # FunctionCall
| IDENT # Identifier
| STRING_LITERAL # StringLiteral
;
functionArgument: expr;
args: (functionArgument (',' functionArgument)*)?;
// Reserved words
REQUIRE: 'require';
// Whitespace and line break
NEWLINE : [\r\n];
WS: [ \t] + -> skip;
// Entities
NUMBER: ('0' .. '9') + ('.' ('0' .. '9') +)?;
IDENT: [a-zA-Z]+[0-9a-zA-Z]*;
STRING_LITERAL : '"' (~('"' | '\' | '\r' | '\n') | '\' ('"' | '\'))* '"';
此外,我不太明白如何访问基本访问者中的“通用”节点 - 如何从特定上下文中获取 RuleNode?
[...] does not produce a visitor with "visitExpr" and I have no idea why
当labelling一个解析器规则r
时,不会生成visitR(...)
。只会生成备选方案的 visit...()
方法。
所以没有替代标签:
r
: a
| b
;
// Only 1 method:
// - visitR(...)
带有替代标签:
r
: a #altA
| b #altB
;
// Two methods:
// - visitAltA(...)
// - visitAltB(...)
Also, I don't quite see how to visit a "generic" node in the base visitor - how do I get a RuleNode out of a specific context?
您可以覆盖 AbstractParseTreeVisitor<T>#visitChildren(...)
方法来监听任何规则。快速演示:
public class Main {
public static void main(String[] args) throws Exception {
String source = "require a + b";
TxmlLexer lexer = new TxmlLexer(CharStreams.fromString(source));
TxmlParser parser = new TxmlParser(new CommonTokenStream(lexer));
ParseTree root = parser.program();
new TestTXmlVisitor().visit(root);
}
}
class TestTXmlVisitor extends TxmlBaseVisitor<Object> {
@Override
public Object visitChildren(RuleNode node) {
System.out.println("visited: " + node.getClass().getSimpleName() + " -> " + node.getText());
return super.visitChildren(node);
}
}
将打印:
visited: ProgramContext -> requirea+b<EOF>
visited: ConditionContext -> requirea+b
visited: RequireContext -> requirea+b
visited: ValueExpressionContext -> a+b
visited: AddSubContext -> a+b
visited: IdentifierContext -> a
visited: IdentifierContext -> b
Java 中的以下语法不会生成带有“visitExpr”的访问者,我不知道为什么...我添加了 valueExpression,它确实生成了 visitValueExpression,但这并没有成功很容易从所有数学表达式中得到一个表达式。
grammar Txml;
program: statement (NEWLINE statement)* NEWLINE? EOF;
statement: require # Condition
| entry # CreateEntry
| assignment # Assign
;
require: REQUIRE valueExpression;
valueExpression: expr;
expr: lhs=expr ('*' | '/') rhs=expr # MulDiv
| lhs=expr ('+' | '-') rhs=expr # AddSub
| lhs=expr '%' rhs=expr # Mod
| lhs=expr '^' rhs=expr # Pow
| '(' expr ')' # Parens
| NUMBER # NumberLiteral
| IDENT '(' args ')' # FunctionCall
| IDENT # Identifier
| STRING_LITERAL # StringLiteral
;
functionArgument: expr;
args: (functionArgument (',' functionArgument)*)?;
// Reserved words
REQUIRE: 'require';
// Whitespace and line break
NEWLINE : [\r\n];
WS: [ \t] + -> skip;
// Entities
NUMBER: ('0' .. '9') + ('.' ('0' .. '9') +)?;
IDENT: [a-zA-Z]+[0-9a-zA-Z]*;
STRING_LITERAL : '"' (~('"' | '\' | '\r' | '\n') | '\' ('"' | '\'))* '"';
此外,我不太明白如何访问基本访问者中的“通用”节点 - 如何从特定上下文中获取 RuleNode?
[...] does not produce a visitor with "visitExpr" and I have no idea why
当labelling一个解析器规则r
时,不会生成visitR(...)
。只会生成备选方案的 visit...()
方法。
所以没有替代标签:
r
: a
| b
;
// Only 1 method:
// - visitR(...)
带有替代标签:
r
: a #altA
| b #altB
;
// Two methods:
// - visitAltA(...)
// - visitAltB(...)
Also, I don't quite see how to visit a "generic" node in the base visitor - how do I get a RuleNode out of a specific context?
您可以覆盖 AbstractParseTreeVisitor<T>#visitChildren(...)
方法来监听任何规则。快速演示:
public class Main {
public static void main(String[] args) throws Exception {
String source = "require a + b";
TxmlLexer lexer = new TxmlLexer(CharStreams.fromString(source));
TxmlParser parser = new TxmlParser(new CommonTokenStream(lexer));
ParseTree root = parser.program();
new TestTXmlVisitor().visit(root);
}
}
class TestTXmlVisitor extends TxmlBaseVisitor<Object> {
@Override
public Object visitChildren(RuleNode node) {
System.out.println("visited: " + node.getClass().getSimpleName() + " -> " + node.getText());
return super.visitChildren(node);
}
}
将打印:
visited: ProgramContext -> requirea+b<EOF>
visited: ConditionContext -> requirea+b
visited: RequireContext -> requirea+b
visited: ValueExpressionContext -> a+b
visited: AddSubContext -> a+b
visited: IdentifierContext -> a
visited: IdentifierContext -> b