I learned the basic grammars of antlr4 and tried to build a simple calculator. But, I have no idea how to handle PLUS | MINUS and TIMES | DIV.
expression: multiplyingExpression ((PLUS | MINUS) multiplyingExpression)*;
multiplyingExpression: signedAtom ((TIMES | DIV) signedAtom)*;
signedAtom: PLUS signedAtom | MINUS signedAtom | func_ | atom;
(code extracted from Antlr4 sample calculator grammar)
It seems like no API can handle PLUS | MINUS, because they are not defined like signedAtom/expression, which can be handled in method like exitXXX.
Does this mean, the grammar like this can only be parsed in visitor model?
Example:
Here is a extremely simple example code in golang.
calculator.g4
grammar calculator;
expression: atom ((PLUS | MINUS) atom)*;
atom: '1';
PLUS: '+';
MINUS: '-';
WS: [ \r\n\t]+ -> skip;
Code in Golang listener model
func NewCalculatorListenrImpl() *CalculatorListenrImpl {
return &CalculatorListenrImpl{
stack: stack.New(),
}
}
type CalculatorListenrImpl struct {
BasecalculatorListener
stack *stack.Stack
}
func (s *CalculatorListenrImpl) ExitExpression(ctx *ExpressionContext) {
left, op, right := s.stack.Pop().(int), s.stack.Pop().(string), s.stack.Pop().(int)
switch op {
case "+":
s.stack.Push(left + right)
case "-":
s.stack.Push(left - right)
}
}
func (s *CalculatorListenrImpl) ExitAtom(ctx *AtomContext) {
v, _ := strconv.ParseInt(ctx.GetText(), 10, 32)
s.stack.Push(int(v))
}
I can push the atom element to stack in exitAtom and then handle the logic in exitExpression method. However, there is no listener for (PLUS | MINUS). What I am looking for is method like exitPLUS where I can simply push them to stack like atom. May be there is other ways to do this? I knostrateforw their is some magic syntax like # and op=xxx, but these code fragements are copied from grammars-v4.