2

私はある種のプログラムのフロントエンドを作ろうとしています...2つの特殊性があります:

1)で始まる文字列に出会ったとき、文字列の残りの部分を文字列値で=はなく読み取りたい。formulaたとえば、、、は"123"タイプとして持っていると見なされ"TRUE"、、、はタイプとして持っていると見なされます。ところで、"TRUE+123"string"=123""=TRUE""=TRUE+123"Syntax.formula

(* in syntax.ml *)
and expression =
  | E_formula of formula
  | E_string of string
  ...

and formula =
  | F_int of int  
  | F_bool of bool
  | F_Plus of formula * formula
  | F_RC of rc

and rc =
  | RC of int * int

2)数式の内部では、一部の文字列は外部とは異なる方法で解釈されます。たとえば、実際には変数であるコマンドR4C5 := 4R4C5は、と見なされますがidentifier"=123+R4C5"数式に変換しようとすると、R4C5として変換されRC (4,5): rcます。

したがって、1つまたは2つのレクサー、および1つまたは2つのパーサーを使用してこれを実現する方法がわかりません。

現時点では、1つのレクサーと1つのパーサーですべてを実現しようとしています。これは機能しないコードの一部ですが、それでも:ではなくと見なさR4C5れます:identifierrc

(* in lexer.mll *)
let begin_formula =  double_quote "=" 
let end_formula = double_quote
let STRING = double_quote ([^ "=" ])* double_quote

rule token = parse
  ...
  | begin_formula { BEGIN_FORMULA }
  | 'R'      { R }
  | 'C'      { C }
  | end_formula { END_FORMULA }
  | lex_identifier as li
      { try Hashtbl.find keyword_table (lowercase li)  
        with Not_found -> IDENTIFIER li }
  | STRING as s { STRING s }
  ...

(* in parser.mly *)
expression:
| BEGIN_FORMULA f = formula END_FORMULA { E_formula f }
| s = STRING { E_string s }
...

formula:
| i = INTEGER { F_int i }
| b = BOOL { F_bool b }
| f0 = formula PLUS f1 = formula { F_Plus (f0, f1) }  
| rc { F_RC $1 }

rc:
| R i0 = INTEGER C i1 = INTEGER { RC (i0, i1) }

誰か助けてもらえますか?

新しいアイデア: 1つのレクサー+ 1つのパーサーに固執することを考えており、通常のようにレクサーで数式のエントリポイントcommentを作成します...ここにいくつかの更新がlexer.mllありますparser.mly

(* in lexer.mll *)
rule token = parse
...
| begin_formula { formula lexbuf }
...
| INTEGER as i { INTEGER (int_of_string i)  }
| '+'      { PLUS }
...

and formula = parse
| end_formula { token lexbuf }
| INTEGER as i { INTEGER_F (int_of_string i)  }
| 'R'      { R }
| 'C'      { C }
| '+'      { PLUS_F }
| _        { raise (Lexing_error ("unknown in formula")) }

(* in parser.mly *)
expression:
| formula { E_formula f }
...

formula:
| i = INTEGER_F { F_int i }
| f0 = formula PLUS_F f1 = formula { F_Plus (f0, f1) }  
...

私はいくつかのテストを行いました、例えば解析するため"=R4"に、問題はそれがうまく解析できるということですR、しかしそれは4代わりINTEGERに、エントリポイントの本体に時々追加される必要があるINTEGER_Fように思われます(私は理解していませんがエントリポイントの本体での解析が常に言及せずに機能する理由)。私はいくつかの可能性を試しました:、 など。しかしそれはうまくいきませんでした... ...誰か助けてもらえますか?formula lexbufformulatokentoken lexbuf| 'R' { R; formula lexbuf }| 'R' { formula lexbuf; R }

4

1 に答える 1

1

最も簡単な選択は、2つの異なるレクサーと2つの異なるパーサーを使用することだと思います。グローバルパーサー内から数式のレクサー&パーサーを呼び出します。事後、2つの文法間でどれだけ共有されているかを確認し、可能な場合は因数分解することができます。

于 2012-12-20T19:40:43.287 に答える