我正在尝试使用解析器组合器,我经常遇到无限递归.这是我遇到的第一个:
import util.parsing.combinator.Parsers
import util.parsing.input.CharSequenceReader
class CombinatorParserTest extends Parsers {
type Elem = Char
def notComma = elem("not comma", _ != ',')
def notEndLine = elem("not end line", x => x != '\r' && x != '\n')
def text = rep(notComma | notEndLine)
}
object CombinatorParserTest {
def main(args:Array[String]): Unit = {
val p = new CombinatorParserTest()
val r = p.text(new CharSequenceReader(","))
// does not get here
println(r)
}
}
Run Code Online (Sandbox Code Playgroud)
如何打印正在发生的事情?为什么没有完成?
如何使用解析器来解析跨越多行的记录?我需要解析树数据(并最终将其转换为树数据结构).我在下面的代码中遇到了难以跟踪的解析错误,但不清楚这是否是Scala解析器的最佳方法.问题更多的是解决问题的方法,而不是调试现有的代码.
EBNF-ish语法是:
SP = " "
CRLF = "\r\n"
level = "0" | "1" | "2" | "3"
varName = {alphanum}
varValue = {alphnum}
recordBegin = "0", varName
recordItem = level, varName, [varValue]
record = recordBegin, {recordItem}
file = {record}
Run Code Online (Sandbox Code Playgroud)
试图实现和测试语法:
import util.parsing.combinator._
val input = """0 fruit
1 id 2
1 name apple
2 type red
3 size large
3 origin Texas, US
2 date 2 aug 2011
0 fruit
1 id 3
1 name apple
2 type green …Run Code Online (Sandbox Code Playgroud) 我正在读取文件中的行
for (line <- Source.fromFile("test.txt").getLines) {
....
}
Run Code Online (Sandbox Code Playgroud)
我基本上想要最后得到一个段落列表.如果一行为空,则以新段落开头,我可能希望将来解析一些关键字 - 值对.
文本文件包含这样的条目列表(或类似的东西,如Ini文件)
User=Hans
Project=Blow up the moon
The slugs are going to eat the mustard. // multiline possible!
They are sneaky bastards, those slugs.
User=....
Run Code Online (Sandbox Code Playgroud)
我基本上想要一个List [Project] Project看起来像
class Project (val User: String, val Name:String, val Desc: String) {}
Run Code Online (Sandbox Code Playgroud)
而描述是大块的文本,不是以a开头<keyword>=,而是可以延伸到任意数量的行.
我知道如何以迭代的方式做到这一点.只需对关键字进行检查列表,然后填充类的实例,并将其添加到列表中以便稍后返回.
但我认为应该可以以适当的函数样式执行此操作,可能使用match case, yield和递归,从而生成包含字段的对象列表User,Project依此类推.使用的类是已知的,所有关键字都是已知的,并且文件格式也不是一成不变的.我主要是想学习更好的功能风格.