我有一个简单的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 : [ trn]+ -> 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))
语法的入口点是exp
规则。
val exp_parsetree = parser.exp()
很可能,你想用
val exp_parsetree = parser.stmt()
当然,输入的3+4
可能无法正确解析——它只是一个简单的exp
。