我通过扩展
scala.util.parsing.combinator.syntactical.StandardTokenParser来使用
Scala组合解析器.该类提供以下方法
def ident:用于解析标识符的解析器[String]
def numericLit:用于解析数字的解析器[String](我猜想小数)
我正在使用scala.util.parsing.combinator.lexical.Scanners来自scala.util.parsing.combinator.lexical.StdLexicalfor lexing.
我的要求是解析一个十六进制数字(不带0x前缀),可以是任意长度.基本上是一个语法,如:([0-9] | [a-f])
我尝试集成Regex解析器,但那里有类型问题.扩展词法分隔符和语法规则定义的其他方法导致找不到令牌!
解决方法
我认为这个问题可以通过扩展Lexer而不是Parser的行为来解决.标准词法分析器只取十进制数字,所以我创建了一个新的词法分析器:
class MyLexer extends StdLexical { override type Elem = Char override def digit = ( super.digit | hexDigit ) lazy val hexDigits = Set[Char]() ++ "0123456789abcdefABCDEF".toArray lazy val hexDigit = elem("hex digit",hexDigits.contains(_)) }
我的解析器(必须是StandardTokenParser)可以扩展如下:
object ParseAST extends StandardTokenParsers{ override val lexical:MyLexer = new MyLexer() lexical.delimiters += ( "(",")",","@") ... }
由数字构造的“数字”由StdLexical类来处理:
class StdLexical { ... def token: Parser[Token] = ... | digit~rep(digit)^^{case first ~ rest => NumericLit(first :: rest mkString "")} }
因为StdLexical只将解析后的数字作为字符串给出,所以对我来说不是问题,因为我对数值也不感兴趣.