基于级别编号的递归解析 [英] Recursive parsing based on level numbers

查看:104
本文介绍了基于级别编号的递归解析的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a tricky question (at least in my perspective), regarding Scalas parser combinators and recursive parsing. I currently building a small parser which should be able to parse PL/1 structures like this:

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

在这种情况下,我想按如下方式构建AST:

In this scenario I want to build a AST as follows:

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

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

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

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

Meaning that the parent element should be connected to its children. In my world this should result in a recursive parser in some way, however my problem is how to control when to stop going down in sublevels. For instance when parsing the the "3 subdata" record structure, it should stop when hitting a level number which is not lower in itself, in this case the line "3 subData2,".

有人可以帮助解决此问题,或为我指出正确的方向. 我目前的解决方案是在解析一个未连接的结构后解决此问题.

Can someone help with this issue, or point me in a good direction. My current solution is to solved this problem after I have parsed an unconnected structure.

谢谢.

关于斯蒂芬

推荐答案

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

Basically all you need is Parser.into (it has an alias >>), it creates a parser combinator that's based on the result of the current one.

我为您准备了一个简单的可替换示例

I've prepared a simple REPLable example for you

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())))

这篇关于基于级别编号的递归解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆