如何解决Scala Parser Combinator 词法分析器处理未终止的字符串
我想知道如何在使用 Scala Parser Combinator library 编写的词法分析器/扫描器中处理未终止的字符串。 scala.util.parsing.combinator.lexical.StdLexical
类中的示例似乎不起作用。
主要的令牌解析器是:
def token: Parser[Token] =
( identChar ~ rep( identChar | digit ) ^^ { case first ~ rest => processIdent(first :: rest mkString "") }
| digit ~ rep( digit ) ^^ { case first ~ rest => NumericLit(first :: rest mkString "") }
| '\'' ~ rep( chrExcept('\'','\n',EofCh) ) ~ '\'' ^^ { case '\'' ~ chars ~ '\'' => StringLit(chars mkString "") }
| '\"' ~ rep( chrExcept('\"',EofCh) ) ~ '\"' ^^ { case '\"' ~ chars ~ '\"' => StringLit(chars mkString "") }
| EofCh ^^^ EOF
| '\'' ~> failure("unclosed string literal")
| '\"' ~> failure("unclosed string literal")
| delim
| failure("illegal character")
)
设置一个简单的测试词法分析器:
object Lexer extends App {
def lex(input: String) = {
val lexer = new StdLexical
var scanner: Reader[lexer.Token] = new lexer.Scanner(input)
while (!scanner.atEnd) {
println(scanner.first)
scanner = scanner.rest
}
}
}
现在,使用合法输入调用它是有效的,这里识别一个标识符和一个字符串文字:
> lex(""" hello "world" """)
identifier hello
"world"
传递非法字符也按预期工作:
> lex(""" hello € "world" """)
identifier hello
ErrorToken(illegal character)
"world"
但是,未终止的双引号字符串的规则似乎不起作用,词法分析器生成 ErrorToken(end of input)
而不是预期的 ErrorToken(unclosed string literal)
:
> lex(""" hello € "unterminated """)
identifier hello
ErrorToken(illegal character)
ErrorToken(end of input)
我猜问题是未终止字符串的规则使用允许回溯的 failure
解析器,但应该将我们发送到最后一个 failure("illegal character")
并且顺便插入一个剪切或使用 {{1 }} 而不是 err
不能解决问题。
知道这个例子有什么问题吗?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。