我創建了一個Scala的解析器組合基於我到前面的問題How to parse a string with filter citeria in scala and use it to filter objectsScala的解析器組合基於計算器,也可以採取dataRecord
我想從加計算器解析器組合的回答來過濾數據記錄這個問題的答案 Operator Precedence with Scala Parser Combinators 到基於第一個問題創建的解析器組合器的底部。因此,計算器分析程序組合器需要接受一個dataRecord,以便像「(doubleValue1/10)* 2 + doubleValue2」這樣的表達式可以被解析爲一個隨後可以接受dataRecord的函數。
這就是我想到的,但加號,減號,除法分析器組合因爲+ - * /運算符是Double的成員而不是函數DataRecord => Double而被破壞。我怎樣才能修復這些解析器組合器,以便像「(doubleValue1/10)* 2 + doubleValue2」這樣的表達式能夠被成功地解析併產生一個可以接受dataRecord的函數?
import scala.util.parsing.combinator._
import scala.util.parsing.combinator.JavaTokenParsers
object Main extends Arith with App {
val dataRecord = new DataRecord(100, 75)
val input = "(doubleValue1/10 ) * 2 + doubleValue2"
println(parseAll(arithmicExpr, input).get(dataRecord)) // prints 95
}
class DataRecord( val doubleValue1 : Double, val doubleValue2 : Double)
class Arith extends JavaTokenParsers {
type D = Double
type Extractor[Double] = DataRecord => Double
//arithmic expression
def arithmicExpr: Parser[Extractor[D]] = term ~ rep(plus | minus) ^^ {case a~b => (a /: b)((acc,f) => f(acc))}
def plus: Parser[Extractor[D]=>Extractor[D]] = "+" ~ term ^^ {case "+"~b => _ + b}
def minus: Parser[Extractor[D]=>Extractor[D]] = "-" ~ term ^^ {case "-"~b => _ - b}
def term: Parser[Extractor[D]] = factor ~ rep(times | divide) ^^ {case a~b => (a /: b)((acc,f) => f(acc))}
def times: Parser[Extractor[D]=>Extractor[D]] = "*" ~ factor ^^ {case "*"~b => _ * (b) }
def divide: Parser[Extractor[D]=>Extractor[D]] = "/" ~ factor ^^ {case "/"~b => _/b}
def factor: Parser[Extractor[D]] = fpn | "(" ~> arithmicExpr <~ ")" | intExtractor
def fpn: Parser[Extractor[D]] = floatingPointNumber ^^ (s => Function.const(s.toDouble)_)
def intExtractor: Parser[Extractor[D]] = ("doubleValue1" | "doubleValue2") ^^ {
case "doubleValue1" => _.doubleValue1
case "doubleValue2" => _.doubleValue2
}
}
作爲一個快速提示:嘗試Functions.const(...)。這會將函數返回一個Double轉換爲需要參數的函數(例如DataRecord),忽略該參數並始終返回相同的Double。 –