使用Scala解析器组合器时,如何过滤从Lexer到我的Parser的令牌序列?
让我解释一下 - 假设我有一个相当标准的Lexer模式(扩展StdLexical
)和一个Parser(扩展StdTokenParsers
)。词法分析器将一系列字符转换为一系列标记,然后解析器将标记序列转换为抽象语法树(类型为Expr
)。
我决定一些令牌,它们可能出现在流中的任何地方,我想有过滤掉的选项,所以我想要一个适合Lexer和Parser之间移除这些令牌的函数。例如,我可能希望词法分析器标记注释,然后在以后过滤掉这些注释。
编写此过滤器的最佳方法是什么?这可以使用解析器组合器习语,但不必使用。
示例当前代码:
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))
答案 0 :(得分:2)
答案 1 :(得分:1)
您是否考虑过使用RegexParsers删除空格和注释?
修改强>
您可以制作一个简单的过滤器
import scala.util.parsing.input._
object ReaderFilter {
def filter[T](reader: Reader[T], check: T => Boolean): Reader[T] = {
new Reader[T] {
var orig = reader
def first = { trim; orig.first }
def atEnd = { trim; orig.atEnd }
def rest: Reader[T] = { trim; ReaderFilter.filter(orig.rest, check) }
def pos = orig.pos
private def trim = {
while (!orig.atEnd && !check(orig.first))
orig = orig.rest
}
}
}
}
以这种方式使用它(删除“#”的标记):
val tokens = ReaderFilter.filter(new MyParser.lexical.Scanner(reader),
{t:ExprParser.lexical.Token => t.chars != "#"})