我尝试过快速解析、parboiled2和scala组合子。在定义词法分析器时,它们都有这个问题:
LET_KEYWORD ::= "let"
IDENTIFIER ::= "[a-zA-Z]+".r当我对输入"leto"运行它们时,它们会生成[LET_KEYWORD,IDENTIFIER(o)]。
我希望这些库中的一些会给我这样的行为:
如果输入是"let",那么它通过选择第一个定义的规则来解决歧义,因为它更相关。如果输入是"leto",那么就没有歧义,只生成IDENTIFIER(leto)。这就是here在ANTLR中描述的行为
发布于 2018-12-31 18:19:17
下面是我的代码片段
val identifierOrKeyword = letter ~ rep(letter | digit | '_') ^^ {
case x ~ xs =>
val ident = x :: xs mkString ""
keyword.getOrElse(ident.toLowerCase, IDENTIFIER(ident))
}keyword从字符串映射到令牌。
使用的定义:
sealed trait SqlToken
object SqlToken {
case class IDENTIFIER(value: String) extends SqlToken
case object LET extends SqlToken
}
val keyword = Map(
"let" -> LET
}发布于 2018-12-31 19:18:28
您的情况不能与ANTLR情况相比较,在ANTLR情况中,词法分析器在解析器之前进行。在这种情况下,您会看到词法分析器的最长匹配规则优先,因为它首先被执行,生成解析器随后可以使用的唯一令牌。
在您的例子中,使用您使用的解析技术,它们在您试图识别的当前非终端上下文中“按需”执行正则表达式。这使得在两种不同的词汇解释之间的选择变成了与上下文无关的选择。你必须在你的定义中加入这个选择。
我猜源代码中规则的顺序与这些技术无关,您必须在某个地方使用声明性有序选择(而不是|),或者重写语法使其不再模棱两可。
https://stackoverflow.com/questions/53986204
复制相似问题