问题描述
我想知道如何在使用 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 (将#修改为@)