我正在尝试为一个简单的antlr 4语法编写一个访问者-我正在改编书中的以下示例:
* directory tour
* example: LabeledExpr.g4, EvalVisitor.java, Calc.java
基于java代码,我写了下面的go代码:
package main
import (
"os"
"./parser"
"github.com/antlr/antlr4/runtime/Go/antlr"
)
type evalVisitor struct {
*parser.BaseLabeledExprVisitor
}
func (v *evalVisitor) VisitAddSub(c *parser.AddSubContext) int {
left := v.Visit(c.Expr(0))
right := v.Visit(c.Expr(1))
if(c.GetOp().GetTokenType() == parser.LabeledExprParserADD) {
return left + right //error: invalid operation: left + right (operator + not defined on interface)
} else {
return left - right
}
}
func main() {
input, _ := antlr.NewFileStream(os.Args[1])
lexer := parser.NewLabeledExprLexer(input)
stream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)
p := parser.NewLabeledExprParser(stream)
tree := p.Prog()
var visitor evalVisitor
visitor.Visit(tree)
}
我在上面显示了一个访问者,其他访问者也会写类似的内容。我得到了一些编译错误,如上面的评论所示。如何修复此错误?
在访问者的顶层调用中似乎也有一个错误,因为当我注解掉“左+右”行时,我得到了一个SIGSEGV错误。
下面是原始的java代码,供大家参考:
public Integer visitAddSub(LabeledExprParser.AddSubContext ctx) {
int left = visit(ctx.expr(0)); // get value of left subexpression
int right = visit(ctx.expr(1)); // get value of right subexpression
if ( ctx.op.getType() == LabeledExprParser.ADD ) return left + right;
return left - right; // must be SUB
}
另外,语法是这样的:
grammar LabeledExpr;
prog: stat+ ;
stat: expr NEWLINE # printExpr
| ID '=' expr NEWLINE # assign
| NEWLINE # blank
;
expr: expr op=('*'|'/') expr # MulDiv
| expr op=('+'|'-') expr # AddSub
| INT # int
| ID # id
| '(' expr ')' # parens
;
MUL : '*' ; // assigns token name to '*' used above in grammar
DIV : '/' ;
ADD : '+' ;
SUB : '-' ;
ID : [a-zA-Z]+ ; // match identifiers
INT : [0-9]+ ; // match integers
NEWLINE:'\r'? '\n' ; // return newlines to parser (is end-statement signal)
WS : [ \t]+ -> skip ; // toss out whitespace
注意:我到处寻找一个示例访问者代码,但我在54992660上遇到了一些负面评论,这也是在antlr问题上发布的。这个问题有一个不完整的答案,不能编译。那么,访问者在antlr 4的Go目标中工作吗?是否有一个示例代码可供使用?
2条答案
按热度按时间5rgfhyps1#
我在谷歌上搜索了一下,并一起破解了以下Go访问者:
文件:./antlr 4demo/eval_visitor.go
文件:./Expression.g4
首先下载ANTLR 4.9编译器,生成解析器和访问者Go文件,并将它们移动到
antlr4demo
文件夹:如果你现在运行下面的Go脚本:
文件:./main.go
你会看到输出:
请注意,我从来没有在Go中编程过任何东西:我肯定代码是一团糟,但嘿,“它工作”。
wfveoks02#
而不是
。你就写: