ANTLR4: няма жизнеспособна алтернатива на входа (генериране на AST)

Е, имам прост ANTLR код

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]+;

Моят Scala код:

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`

Опитвам се да генерирам AST
Моят вход: while 3 do something и грешката:
line 1:0 no viable alternative at input 'while' null
Но входът 3+4 работи перфектно и резултатът е AddtermAST(IntlitAST(3),+,IntlitAST(4))

Може ли някой да ми помогне с това??? Благодаря (Извинете за лошия ми английски)


person Tungshev    schedule 25.09.2015    source източник


Отговори (1)


Входната точка във вашата граматика е правилото exp.

val exp_parsetree = parser.exp()

Вероятно сте искали да използвате

val exp_parsetree = parser.stmt()

Разбира се, входът 3+4 вероятно няма да се анализира правилно -- той е просто гол exp.

person GRosenberg    schedule 25.09.2015
comment
Много много полезно. Благодаря @GRosenberg - person Tungshev; 25.09.2015