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 (将#修改为@)