2

これは、1 次 ODE 系の文法です。

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 の後ろに 1 つのアポストロフィが続きます (x' は x の 1 次導関数 (時間に関する) を示します)
  • 私は何もコーディングしていませんが、次の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", "'")

Scala ユーザーのメーリング リスト ( https://groups.google.com/forum/?fromgroups#!topic/scala-user/KXlfGauGR9Q ) でこれを尋ねましたが、十分な返信がありません。助けてくれてどうもありがとう。

4

1 に答える 1

1

JavaTokenParsers混合が機能しないことを考えると、代わりに混合して のソースからRegexParsersの定義だけをコピーしてみてください。floatingPointNumberJavaTokenParsers

その定義は、少なくともこのバージョンでは単なる正規表現です。

  def floatingPointNumber: Parser[String] =
    """-?(\d+(\.\d*)?|\d*\.\d+)([eE][+-]?\d+)?[fFdD]?""".r
于 2012-06-10T03:50:18.070 に答える