Scala Parser Combinator替换模式

时间:2015-07-20 15:19:32

标签: scala parsing parser-combinators

我有一个下面的程序,我可以将convert(a.ACCOUNT_ID, string)这样的模式解析为表达式,但我想用CAST(a.ACCOUNT_ID AS VARCHAR)替换这个模式。我可以解析结果表达式并用上面的那个替换字符串但是有这样的表达式因此我不想这样做..有什么方法可以做模式替换吗?就像我找到convert(a.ACCOUNT_ID, string)模式一样,然后将其替换为CAST(a.ACCOUNT_ID AS VARCHAR)

import scala.util.parsing.combinator._
import scala.util.parsing.combinator.lexical._
import scala.util.parsing.combinator.syntactical._
import scala.util.parsing.combinator.token._
import scala.util.parsing.input.CharSequenceReader


trait QParser  extends RegexParsers with JavaTokenParsers  {
  def knownFunction: Parser[Any] = ident ~ "(" ~ ident ~ ("." ~ ident <~ "," ~ ident ~ ")")

  def parse(inputString: String): Any = synchronized {
    phrase(knownFunction)(new CharSequenceReader(inputString)) match {
      case Success(result, _) => result
      case Failure(msg,_) => throw new DataTypeException(msg)
      case Error(msg,_) => throw new DataTypeException(msg)
    }
  }

 class DataTypeException(message: String) extends Exception(message)

}

object Parser extends QParser {
  def main(args: Array[String]) {
     println(parse("convert(a.ACCOUNT_ID, string)"));
  }
}

输出:(((convert~()~a)~(.~ACCOUNT_ID))

1 个答案:

答案 0 :(得分:2)

我不确定你对&#34的意思是什么?有这样的表达因此我不想这样做&#34; ,但你可以改变结果您的解析器函数使用^^运算符。

解析器的转换函数可以是:

def knownFunction: Parser[String] = 
  ident ~ "(" ~ ident ~ "." ~ ident ~ "," ~ ident ~ ")" ^^ {
    case func ~ "(" ~ obj ~ "." ~ value ~ "," ~ castType ~ ")" =>
      val sqlFunc = Map("convert" -> "CAST")
      val sqlType = Map("string" -> "VARCHAR")
      s"${sqlFunc(func)}($obj.$value AS ${sqlType(castType)})"
  }

使用此更新的功能,您的应用程序的输出将是:

CAST(a.ACCOUNT_ID AS VARCHAR)

有关Scala Combinator Parsing的更多信息,请参阅Scala中的编程的chapter,1ed