gpt4 book ai didi

parsing - 基于层数的递归解析

转载 作者:行者123 更新时间:2023-12-02 16:26:48 24 4
gpt4 key购买 nike

我有一个棘手的问题(至少在我看来),关于 Scala 解析器组合器和递归解析。我目前正在构建一个小型解析器,它应该能够解析如下所示的 PL/1 结构:

  dcl 1 data,
3 subData,
5 tmp char(15),
5 tmp1 char(15),
3 subData2,
5 tmp2 char(10),
5 tmp3 char(5);

在这种情况下,我想构建一个 AST,如下所示:

Record(data)  -> (Record(subData),Record(subData2))

Record(subData) -> (Char(tmp),Char(tmp1))

Record(subData2) -> (Char(tmp2),Char(tmp3))

意味着父元素应该连接到它的子元素。在我的世界中,这应该以某种方式导致递归解析器,但是我的问题是如何控制何时停止子级别的下降。例如,当解析“3 subdata”记录结构时,它应该在遇到不低于其本身的级别编号时停止,在本例中为“3 subData2”行。

有人可以帮助解决这个问题,或者给我指出一个好的方向吗?我目前的解决方案是在解析完一个未连接的结构后解决这个问题。

提前致谢。

问候斯特凡

最佳答案

基本上,您所需要的只是 Parser.into (它有一个别名 >>),它会创建一个基于当前解析器组合器结果的解析器组合器。

我为您准备了一个简单的 REPLable 示例

import util.parsing.combinator.RegexParsers

case class Record(data: String, children: List[Record])

object RecordParser extends RegexParsers {
override def skipWhitespace = false

def ws = "\\s*".r
def numberGT(min: Int) = "\\d+".r ^^ { _.toInt } ^? {
case i if i > min => i
}

def subData(n: Int): Parser[Record] = ws ~> numberGT(n) ~ ws ~ ".*".r <~ "\n" >> {
case sub ~ _ ~ data => rep(subData(sub)) ^^ { new Record(data, _) }
}
}

val testData = """
1 data
2 subdata
3 child1
3 child2
2 sub2
"""

RecordParser.parse(RecordParser.subData(0),test)
res7: RecordParser.ParseResult[Record] = [7.1] parsed: Record(data,List(Record(subdata,List(Record(child1,List()), Record(child2,List()))), Record(sub2,List())))

关于parsing - 基于层数的递归解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8678228/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com