首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关键字和标识符在编写lexer时发生冲突?(scala库)

关键字和标识符在编写lexer时发生冲突?(scala库)
EN

Stack Overflow用户
提问于 2018-12-31 18:12:59
回答 2查看 262关注 0票数 0

我尝试过快速解析、parboiled2和scala组合子。在定义词法分析器时,它们都有这个问题:

代码语言:javascript
复制
LET_KEYWORD ::= "let"
IDENTIFIER  ::= "[a-zA-Z]+".r

当我对输入"leto"运行它们时,它们会生成[LET_KEYWORD,IDENTIFIER(o)]

我希望这些库中的一些会给我这样的行为:

如果输入是"let",那么它通过选择第一个定义的规则来解决歧义,因为它更相关。如果输入是"leto",那么就没有歧义,只生成IDENTIFIER(leto)。这就是here在ANTLR中描述的行为

EN

回答 2

Stack Overflow用户

发布于 2018-12-31 18:19:17

下面是我的代码片段

代码语言:javascript
复制
val identifierOrKeyword = letter ~ rep(letter | digit | '_') ^^ {
  case x ~ xs =>
    val ident = x :: xs mkString ""
    keyword.getOrElse(ident.toLowerCase, IDENTIFIER(ident))
}

keyword从字符串映射到令牌。

使用的定义:

代码语言:javascript
复制
sealed trait SqlToken
object SqlToken {
  case class IDENTIFIER(value: String) extends SqlToken
  case object LET extends SqlToken
}

val keyword = Map(
    "let" -> LET
}
票数 1
EN

Stack Overflow用户

发布于 2018-12-31 19:18:28

您的情况不能与ANTLR情况相比较,在ANTLR情况中,词法分析器在解析器之前进行。在这种情况下,您会看到词法分析器的最长匹配规则优先,因为它首先被执行,生成解析器随后可以使用的唯一令牌。

在您的例子中,使用您使用的解析技术,它们在您试图识别的当前非终端上下文中“按需”执行正则表达式。这使得在两种不同的词汇解释之间的选择变成了与上下文无关的选择。你必须在你的定义中加入这个选择。

我猜源代码中规则的顺序与这些技术无关,您必须在某个地方使用声明性有序选择(而不是|),或者重写语法使其不再模棱两可。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53986204

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档