Parsing Scala:使用StandardTokenParser解析十六进制数字
我通过扩展Parsing Scala:使用StandardTokenParser解析十六进制数字,parsing,scala,Parsing,Scala,我通过扩展Scala.util.parsing.combinator.syntactic.StandardTokenParser来使用Scala组合解析器。此类提供以下方法 def ident:Parser[String]用于解析标识符和 def numericLit:Parser[String]解析数字(我想是十进制的) 我正在使用scala.util.parsing.combinator.lexical中的scala.util.parsing.combinator.lexical.StdLe
Scala.util.parsing.combinator.syntactic.StandardTokenParser
来使用Scala组合解析器。此类提供以下方法
def ident:Parser[String]
用于解析标识符和
def numericLit:Parser[String]
解析数字(我想是十进制的)
我正在使用scala.util.parsing.combinator.lexical
中的scala.util.parsing.combinator.lexical.StdLexical
进行词法分析
我的要求是解析任意长度的十六进制数(不带0x
前缀)。基本上是这样的语法:([0-9]|[a-f])+
我尝试集成Regex解析器,但存在类型问题。扩展lexer分隔符定义和语法规则的其他方法会导致找不到标记 您可以将
RegexParsers
与相关令牌关联的操作一起使用
import scala.util.parsing.combinator._
object HexParser extends RegexParsers {
val hexNum: Parser[Int] = """[0-9a-f]+""".r ^^
{ case s:String => Integer.parseInt(s,16) }
def seq: Parser[Any] = repsep(hexNum, ",")
}
这将定义一个解析器,该解析器读取逗号分隔的十六进制数,而不使用前面的0x
。它实际上会返回一个Int
val result = HexParser.parse(HexParser.seq, "1, 2, f, 10, 1a2b34d")
scala> println(result)
[1.21] parsed: List(1, 2, 15, 16, 27439949)
没有办法区分十进制数字。另外,我使用的是
Integer.parseInt
,它仅限于Int
的大小。要获得任何长度,您可能需要制作自己的解析器并使用biginger
或数组 正如我所想,这个问题可以通过扩展Lexer而不是解析器的行为来解决。标准lexer只接受十进制数字,因此我创建了一个新的lexer:
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只将解析后的数字作为字符串给出,因此这对我来说不是问题,因为我对数值也不感兴趣。如果我只解析十六进制数字,这将适合我。整体实现比正则表达式解析要大得多。我的目标是使用StandardTokenParser,在StandardTokenParser中调用parse(HexParser.seq)时,在其内部使用regex解析器会给出类型错误“found:HexParser.parser[Any]required:scratch.parser[?]”。我认为解决方案将涉及更改正在使用的lexer。可能,特别是如果它应该是上下文敏感的。我刚刚提供了一种将十六进制字符串转换为Int的方法。您正在解析什么类型的文件?也许你可以对它进行预处理,使它更易于Lexer。这个答案很有用-我需要了解如何处理hex和类似的构造。添加关于lexical.delimiters的注释特别有用。