parser combinator: how to terminate repetition on keyword

空扰寡人 提交于 2019-12-19 04:12:33

问题


I'm trying to figure out how to terminate a repetition of words using a keyword. An example:

class CAQueryLanguage extends JavaTokenParsers {
    def expression = ("START" ~ words ~ "END") ^^ { x =>
        println("expression: " + x);
        x
    }
    def words = rep(word) ^^ { x =>
        println("words: " + x)
        x
    }
    def word = """\w+""".r
}

When I execute

val caql = new CAQueryLanguage
caql.parseAll(caql.expression, "START one two END")

It prints words: List(one, two, END), indicating the words parser has consumed the END keyword in my input, leaving the expression parser unable to match. I would like END to not be matched by words, which will allow expression to successfully parse.


回答1:


Is this what you are looking for?

import scala.util.parsing.combinator.syntactical._

object CAQuery extends StandardTokenParsers {
    lexical.reserved += ("START", "END")
    lexical.delimiters += (" ")

    def query:Parser[Any]= "START" ~> rep1(ident) <~ "END"

    def parse(s:String) = {
       val tokens = new lexical.Scanner(s)
       phrase(query)(tokens)
   }   
}

println(CAQuery.parse("""START a END"""))       //List(a)
println(CAQuery.parse("""START a b c END"""))   //List(a, b, c)

If you would like more details, you can check out this blog post



来源:https://stackoverflow.com/questions/1528333/parser-combinator-how-to-terminate-repetition-on-keyword

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!