使用 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/