ANTLR4得到解析树scala代码,我做错了什么



我试图解析一个简单的scala表达式:val a = 4 + 54.

然而,每当我运行它,我得到错误:

line 1:0 extraneous input 'val a = 4 + 5' expecting {<EOF>, 'implicit', 'lazy', 'case', '@', 'override', 'abstract', 'final', 'sealed', 'private', 'protected', 'import', 'class', 'trait', 'package', ';'}
下面是我的代码:
object AntlrMain {
    val v = "val a = 4 + 5"
    val stream = new ANTLRInputStream(v)
    val lexer = new ScalaLexer(stream)
    val tokens = new CommonTokenStream(lexer)
    val parser = new ScalaParser(tokens)
    val tree: ParseTree = parser.compilationUnit()
}

ScalaLexer和ScalaParser是从这里的scala语法生成的:https://github.com/antlr/grammars-v4/blob/master/scala/Scala.g4

我做错了什么?

编辑

在sepp2k的注释之后,我试图将val v更改为以下内容:

val v = "object Test { def a(): Int = 4 + 5 }"

,但是同样的错误仍然存在。至于使用blockStat()的建议-它适用于v的前一个值

val a = 4 + 5不是有效的Scala文件。val需要在class, traitobject内(或在其中一个def内)。错误信息给出了一个关键字列表,您可以在顶层或文件中使用这些关键字。

如果您希望能够单独解析val定义,您应该解析与compilationUnit不同的规则。如果你试图实现类似REPL的东西,blockStat可能是有意义的,它包括任何可以在块中作为语句出现的东西(如局部定义或表达式)。


至于为什么它不能与object一起工作:显然,语法只允许object,如果它前面有case(您会注意到object没有出现在最初期望的令牌列表中)。如果我们查看语法内部,我们会发现:

tmplDef
   : 'case'? 'class' classDef
   | 'case' 'object' objectDef
   | 'trait' traitDef
;

所以case关键字在类定义之前是可选的,但在对象定义之前是必需的。

这显然是语法中的一个错误。在真正的Scala语言中,case是可选的。

相关内容

  • 没有找到相关文章

最新更新