2012-06-10 39 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