scala - 从 Scala 解析器组合器中过滤标记

标签 scala parser-combinators

使用 Scala 解析器组合器时,如何过滤从词法分析器到解析器的标记序列?

让我解释一下 - 假设我有相当标准的词法分析器(扩展 StdLexical)和解析器(扩展 StdTokenParsers)模式。词法分析器将字符序列转换为标记序列,然后解析器将标记序列转换为抽象语法树(Expr 类型)。

我决定某些可能出现在流中任何位置的标记,我希望能够选择过滤掉,因此我想要一个适合词法分析器和解析器之间的函数来删除这些标记。例如,我可能希望词法分析器对注释进行标记,然后稍后过滤掉这些注释。

编写此过滤器的最佳方式是什么?这可以使用解析器组合器习惯用法,但不是必须的。

当前代码示例:

 val reader = new PagedSeqReader(PagedSeq.fromReader(reader))
 val tokens = new MyParser.lexical.Scanner(reader)
 val parse = MyParser.phrase(parser)(tokens)

我希望能够写出这样的东西:

 val reader = new PagedSeqReader(PagedSeq.fromReader(reader))
 val tokens = new MyParser.lexical.Scanner(reader)
 val parse = MyParser.phrase(parser)(filter(tokens))

最佳答案

我现在已经完成了,这是结果。关键的见解是解析器组合器中的解析器使用 scala.util.parsing.input.Reader 作为输入。因此,我们需要一个包装 Reader 的类,它本身就是一个 Reader ,它会在某些条件下过滤掉条目。

我编写了Reader,因此在构建时它会跳过所有不需要的条目,并在第一个好的条目或结尾处停止。然后每个调用都委托(delegate)给原始读者,除了 rest 依次构造另一个 TokenFilter。

import scala.util.parsing.input._

class Filter[T](parent : Reader[T], exclude : T=>Boolean) extends Reader[T] {
  private val start = nextOk(parent)
  def nextOk(r : Reader[T]) : Reader[T] =
    if(r.atEnd) r else (if (exclude(r.first)) nextOk(r.rest) else r)

  override def source = start.source
  override def offset: Int = start.offset
  override def first: T = start.first
  override def rest: Reader[T] = new Filter(start.rest, exclude)
  override def pos: Position = start.pos
  override def atEnd = start.atEnd
}

关于scala - 从 Scala 解析器组合器中过滤标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3297764/

相关文章:

scala - 使用 OFormat 序列化案例类时从 Play 应用程序收到警告

scala - 在Apache Spark中读取包含分隔符的CSV文件

parsing - 无法计算解析器的最小长度 - Haskell 中的 uu-parsinglib

scala 组合器解析器保留原始输入

rust - 使用 nom 从输入中识别 float

regex - 小于等于运算符 (<=) 的 Scala 正则表达式

scala - 为什么我们需要 flatMap(通常)?

scala - 为什么 javaBigDecimal2bigDecimal 隐式不适用?

scala - 解析器组合器未终止 - 如何记录正在发生的事情?

scala - 提升 `??` 结构