Scala 解析器组合器替换模式
Scala Parser Combinator Replace Patterns
我有一个下面的程序,我可以将 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))
我不完全确定 "there are expressions like this hence I don't want to do that way" 是什么意思,但您可以使用 ^^
运算符转换解析器函数的结果。
您的解析器的转换函数可以是:
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 组合器解析的更多信息,请参阅 Programming in Scala, 1ed.
的 chapter
我有一个下面的程序,我可以将 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))
我不完全确定 "there are expressions like this hence I don't want to do that way" 是什么意思,但您可以使用 ^^
运算符转换解析器函数的结果。
您的解析器的转换函数可以是:
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 组合器解析的更多信息,请参阅 Programming in Scala, 1ed.
的 chapter