我所知道的唯一方法不是"直接":
有关:
第二个链接建议调试向解析器添加隐式方法:
implicit def toLogged(name:String) = new {
def !! = log(p)(name)
}
Run Code Online (Sandbox Code Playgroud)
可能是AST会更可行/有用; 但问题仍然相似.
是否有任何现有的GLL算法实现,无论是以解析器组合器(首选)的形式,还是作为C或C++的解析器生成器?
我的要求是输出是一个共享打包解析林(SPPF),我以后可以使用语义和/或上下文规则消除歧义.还有其他解析算法,如GLR,它们能够处理一般的无上下文语法,但是,我可以找到的所有GLR解析器生成器要么返回第一个成功的解析树,要么在最后仍有任何歧义时失败.
是否有可能为无形'创建一个HList看起来如下的提取器.
val a ~ _ ~ b = 4 :: "so" :: 4.5 :: HNil
=> a == 4 && b == 4.5
Run Code Online (Sandbox Code Playgroud)
::为~,这应该不是问题.HNil.有没有可能出现的问题?经过多少汗水和泪水,我设法到达了以下代码的工作点:
for(
x1 :: _ :: x2 :: HNil <- (expInt ~ "+" ~ expInt).llE
) yield (x1 + x2)
Run Code Online (Sandbox Code Playgroud)
expInt解析Int一些monad E.类型(expInt ~ "+" ~ expInt).llE是E[Int :: String :: Int :: HNil].
我希望左边的模式在<-某种程度上类似于右边的组合子解析器的构造.
我熟悉fparsec的一些基础知识,但它似乎是面向文本文件或流.
还有其他F#库可以有效地解析二进制文件吗?或者可以轻松修改fparsec以便有效地使用二进制流?
我写了一个解析器如下:
class LogParser extends JavaTokenParsers {
def invertedIndex: Parser[Array[Array[(Int, Int)]]] = {
num ~> num ~> num ~> rep(postingsList) ^^ {
_.toArray
}
}
def postingsList: Parser[Array[(Int, Int)]] = {
num ~> rep(entry) ^^ {
_.toArray
}
}
def entry = {
num ~ "," ~ num ^^ {
case docID ~ "," ~ count => (docID.toInt, count.toInt)
}
}
def num = wholeNumber ^^ (_.toInt)
}
Run Code Online (Sandbox Code Playgroud)
如果我使用FileReader从(270MB)文件解析如下:
val index = parseAll(invertedIndex, new FileReader("path/to/file")).get
Run Code Online (Sandbox Code Playgroud)
我得到了Exception in thread "main" java.lang.StackOverflowError …
我正在编写一个Scala解析器组合语法,它读取换行符分隔的单词列表,其中列表由一个或多个空行分隔.给出以下字符串:
cat
mouse
horse
apple
orange
pear
Run Code Online (Sandbox Code Playgroud)
我想让它回来List(List(cat, mouse, horse), List(apple, orange, pear)).
我写了这个基本语法,将单词列表视为换行符分隔的单词.请注意,我必须覆盖默认定义whitespace.
import util.parsing.combinator.RegexParsers
object WordList extends RegexParsers {
private val eol = sys.props("line.separator")
override val whiteSpace = """[ \t]+""".r
val list: Parser[List[String]] = repsep( """\w+""".r, eol)
val lists: Parser[List[List[String]]] = repsep(list, eol)
def main(args: Array[String]) {
val s =
"""cat
|mouse
|horse
|
|apple
|orange
|pear""".stripMargin
println(parseAll(lists, s))
}
}
Run Code Online (Sandbox Code Playgroud)
这会错误地将空行视为空单词列表,即返回
[8.1] parsed: List(List(cat, mouse, horse), List(), List(apple, orange, pear))
Run Code Online (Sandbox Code Playgroud)
(注意中间的空列表.)
我可以在每个列表的末尾添加一个可选的行尾.
val …Run Code Online (Sandbox Code Playgroud) 我有以下要解析的EBNF:
PostfixExp -> PrimaryExp ( "[" Exp "]"
| . id "(" ExpList ")"
| . length )*
Run Code Online (Sandbox Code Playgroud)
这就是我得到的:
def postfixExp: Parser[Expression] = (
primaryExp ~ rep(
"[" ~ expression ~ "]"
| "." ~ ident ~"(" ~ repsep(expression, "," ) ~ ")"
| "." ~ "length") ^^ {
case primary ~ list => list.foldLeft(primary)((prim,post) =>
post match {
case "[" ~ length ~ "]" => ElementExpression(prim, length.asInstanceOf[Expression])
case "." ~ function ~"(" ~ arguments ~ ")" => CallMethodExpression(prim, function.asInstanceOf[String], …Run Code Online (Sandbox Code Playgroud) 我想知道是否有可能从下面的语法中获得匹配正则表达式生成的MatchData.
object DateParser extends JavaTokenParsers {
....
val dateLiteral = """(\d{4}[-/])?(\d\d[-/])?(\d\d)""".r ^^ {
... get MatchData
}
}
Run Code Online (Sandbox Code Playgroud)
一个选项当然是在块内再次执行匹配,但由于RegexParser已经执行了匹配,我希望它将MatchData传递给块,或者存储它?
我阅读了关于Scala的解析器组合器的教程,我想知道Java是否有"神奇"的东西.我能找到的最好的东西是JParsec.
我正在尝试为下面的命令定义语法.
object ParserWorkshop {
def main(args: Array[String]) = {
ChoiceParser("todo link todo to database")
ChoiceParser("todo link todo to database deadline: next tuesday context: app.model")
}
}
Run Code Online (Sandbox Code Playgroud)
第二个命令应该标记为:
action = todo
message = link todo to database
properties = [deadline: next tuesday, context: app.model]
Run Code Online (Sandbox Code Playgroud)
当我在下面定义的语法上运行此输入时,我收到以下错误消息:
[1.27] parsed: Command(todo,link todo to database,List())
[1.36] failure: string matching regex `\z' expected but `:' found
todo link todo to database deadline: next tuesday context: app.model
^
Run Code Online (Sandbox Code Playgroud)
据我所知,它失败了,因为匹配消息的单词的模式几乎与属性键的键的模式相同:值对,因此解析器无法分辨消息的结束位置和属性的开始.我可以通过坚持为每个属性使用开始令牌来解决这个问题,如下所示:
todo link todo to database :deadline: next tuesday …Run Code Online (Sandbox Code Playgroud)