2012-06-10 63 views
2

這是一階微分方程的系統語法:與StandardTokenParsers Scala的解析浮點數

system ::= equation { equation } 

equation ::= variable "=" (arithExpr | param) "\n" 

variable ::= algebraicVar | stateVar 

algrebraicVar ::= identifier 

stateVar ::= algebraicVar' 

arithExpr ::= term { "+" term | "-" term } 

term ::= factor { "*" factor | "/" factor } 

factor ::= algebraicVar 
      | powerExpr 
      | floatingPointNumber 
      | functionCall 
      | "(" arithExpr ")" 

powerExpr ::= arithExpr {"^" arithExpr} 

注:

  • 的標識符應當是一個有效的Scala標識符。
  • 甲stateVar是algebraicVar後跟一個撇號(x」表示x的一階導數--with相對於時間 - )
  • 我尚未爲functionCall編碼任何東西,但我的意思是這樣Cos[Omega]

這是我已經

package tests 

import scala.util.parsing.combinator.lexical.StdLexical 
import scala.util.parsing.combinator.syntactical.StandardTokenParsers 
import scala.util.parsing.combinator._ 
import scala.util.parsing.combinator.JavaTokenParsers 
import token._ 

object Parser1 extends StandardTokenParsers { 

    lexical.delimiters ++= List("(", ")", "=", "+", "-", "*", "/", "\n") 
    lexical.reserved ++= List(
    "Log", "Ln", "Exp", 
    "Sin", "Cos", "Tan", 
    "Cot", "Sec", "Csc", 
    "Sqrt", "Param", "'") 

    def system: Parser[Any] = repsep(equation, "\n") 
    def equation: Parser[Any] = variable ~ "=" ~ ("Param" | arithExpr) 
    def variable: Parser[Any] = stateVar | algebraicVar 
    def algebraicVar: Parser[Any] = ident 
    def stateVar: Parser[Any] = algebraicVar ~ "\'" 
    def arithExpr: Parser[Any] = term ~ rep("+" ~ term | "-" ~ term) 
    def term: Parser[Any] = factor ~ rep("*" ~ factor | "/" ~ factor) 
    def factor: Parser[Any] = algebraicVar | floatingPointNumber | "(" ~ arithExpr ~ ")" 
    def powerExpr: Parser[Any] = arithExpr ~ rep("^" ~ arithExpr) 


    def main(args: Array[String]) { 
    val code = "x1 = 2.5 * x2" 
    equation(new lexical.Scanner(code)) match { 
     case Success(msg, _) => println(msg) 
     case Failure(msg, _) => println(msg) 
     case Error(msg, _) => println(msg) 
    } 
    } 
} 

然而這行不工作:

def factor: Parser[Any] = algebraicVar | floatingPointNumber | "(" ~ arithExpr ~ ")" 

因爲我沒有定義什麼是floatingPointNumber。首先,我嘗試在JavaTokenParsers中混合使用,但後來出現衝突的定義。我想,而不是使用JavaTokenParsers StandardTokenParsers的原因是使用能夠使用一組預定義關鍵詞與

lexical.reserved ++= List(
    "Log", "Ln", "Exp", 
    "Sin", "Cos", "Tan", 
    "Cot", "Sec", "Csc", 
    "Sqrt", "Param", "'") 

我問這個斯卡拉用戶郵件列表(https://groups.google.com/forum/?fromgroups#!topic/scala-user/KXlfGauGR9Q)上,但我還沒有收到足夠的答覆。非常感謝您的幫助。

回答

1

鑑於JavaTokenParsers中的混合不起作用,您可以嘗試混合RegexParsers而不是複製源JavaTokenParsersfloatingPointNumber的定義。

該定義,至少在this version是一個簡單的正則表達式:

def floatingPointNumber: Parser[String] = 
    """-?(\d+(\.\d*)?|\d*\.\d+)([eE][+-]?\d+)?[fFdD]?""".r 
+0

'對象DynamicalSystemParser延伸與RegexParsers' StandardTokenParsers提供了以下錯誤: 壓倒一切類型ELEM在性狀TokenParsers,其等於tests.Parser1.lexical .Token; 在特徵RegexParsers中鍵入Elem,它等於Char需要'override'修飾符。 混合JavaTokenParsers給出了類似的錯誤。 – oscarvarto

+0

好吧,猜猜你真的不能混合這些層次太多。 –

+0

我有一些進展(尚未完成)。請訪問(https://groups.google.com/forum/?fromgroups#!topic/scala-user/KXlfGauGR9Q)查看附件pdf parsingODEs.pdf。 – oscarvarto