Tungshev
Tungshev

Reputation: 49

ANTLR4: no viable alternative at input (generate AST)

Well, I have a simple ANTLR code

whilestmt: 'while' exp 'do' stmt;                       
forstmt: 'for' VAR 'equal' exp TO exp 'do' stmt;
dosthstmt: 'something';                             
stmt: whilestmt|forstmt|dosthstmt;

exp:   exp ADDOP exp    #addterm
       | fact           #factterm
       ;    

fact:  INTLIT           #intlit
       | VAR            #idlist
       | LB exp RB      #bracexp
       ;

WS : [ \t\r\n]+ -> skip ; 
INTLIT : [0-9]+ ;  
ADDOP: '+';
LB: '(';
RB: ')';
TO: 'to' | 'down to';
VAR: [a-z]+;

My Scala code:

import java.io.{PrintWriter,File}
import java.lang.RuntimeException
import org.antlr.v4.runtime.ANTLRFileStream
import org.antlr.v4.runtime.CommonTokenStream

object Main {
   def main(args:Array[String]):Unit = {
      val source = new ANTLRFileStream("test.txt")
      val lexer = new ExpLexer(source)
      val tokens = new CommonTokenStream(lexer)
      val parser = new ExpParser(tokens)
      val exp_parsetree = parser.exp() 
      //println(exptree.getClass)
      val astgen = new ASTGeneration()
      val exp_ast = exp_parsetree.accept(astgen)
      println(exp_ast)
   }
}
class ASTGeneration extends ExpBaseVisitor[ExpAST] {  
    override def visitWhilestmt(ctx: ExpParser.WhilestmtContext) = { 
        WhileAST(ctx.getChild(0).getText,ctx.exp.accept(this),ctx.getChild(1).getText,ctx.stmt.accept(this))
    }    
    override def visitForstmt(ctx: ExpParser.ForstmtContext) = {
        ForAST("for", ctx.VAR.accept(this), "equal", ctx.exp(1).accept(this), ctx.TO.accept(this) ,ctx.exp(1).accept(this), "do", ctx.stmt.accept(this))
    }  
    override def visitDosthstmt(ctx: ExpParser.DosthstmtContext) = {
        DosthAST("do something")
    }   
    override def visitAddterm (ctx:ExpParser.AddtermContext) =
        AddtermAST(ctx.exp(0).accept(this),ctx.getChild(1).getText,ctx.exp(1).accept(this))
    override def visitFactterm(ctx:ExpParser.FacttermContext) =
        ctx.fact.accept(this)
    override def visitIntlit(ctx:ExpParser.IntlitContext) =
        IntlitAST(ctx.INTLIT.getText.toInt)
    override def visitIdlist(ctx:ExpParser.IdlistContext) =
        IdAST(ctx.VAR.getText.toString)
    override def visitBracexp(ctx:ExpParser.BracexpContext) = 
        ctx.exp.accept(this) 
    }

trait ExpAST
case class WhileAST(op:String,exp1:ExpAST, op2:String,exp2:ExpAST) extends ExpAST
case class ForAST(forr:String,varr:ExpAST, equal:String,exp1:ExpAST,to:ExpAST,exp2:ExpAST,doo:String,stmt:ExpAST) extends ExpAST
case class DosthAST(stmt:String) extends ExpAST
case class AddtermAST(left:ExpAST,op:String,right:ExpAST) extends ExpAST 
case class IntlitAST(value:Int) extends ExpAST
case class IdAST(id:String) extends ExpAST`

I'm trying to generate a AST
My input: while 3 do something and the error:
line 1:0 no viable alternative at input 'while' null
But the input 3+4, it works perfectly and the result is AddtermAST(IntlitAST(3),+,IntlitAST(4))

Can anyone help me with this ??? Thank you (Sorry for my bad English)

Upvotes: 0

Views: 180

Answers (1)

GRosenberg
GRosenberg

Reputation: 5991

The entry point into your grammar is the exp rule.

val exp_parsetree = parser.exp()

Likely, you meant to use

val exp_parsetree = parser.stmt()

Of course, the input 3+4 is likely not to parse correctly -- it is just a bare exp.

Upvotes: 1

Related Questions