2011-12-15 9 views
2

私はF#とFParsecで新しいので、これまでに得たものを示して自分自身を恥ずかしくすることさえしたくありません。複合型への構文解析

FParsecの例では、ASTのすべての型は、単一の値、リスト、またはタプルの型略称です。

構文解析された関数名とそのパラメータを保持すると思われる複合型がある場合はどうなりますか?

そこで、f(a, b, c)は紐状部材NamePParameterリスト部材Parametersを有するタイプPFunctionのオブジェクトに解析されるであろう。 f(a, b, c)|>>に一致するパーサーからPFunctionに移動するにはどうすればよいですか?

私がこれまで行うことができるのは、コンポーザーを作成することですが、それを何かにすることはできません。 Calculatorの例は、Termのような型を含むASTを作成した場合に似ていますが、代わりにパーサーではなくインタープリタであるように見えますので、ASTはありません。さらに、Termは他のタイプの省略されたコンポーネントのタプルにすぎないでしょう。

ありがとうございます!

+1

私はFParsecを使用していないが、fsyaccにあなたは一般的に区別組合として、それをモデル化するでしょう。例: 'Func = stringのFunc *パラメータリスト' – Daniel

+0

ありがとう。 1)これは、私が、CalcがASTを生成した場合、Termが見えると仮定していることです - そして、パーサーからそのようなタプルを返す方法についても混乱していますが、2)私のモチベーションであるC#にインポートするときに親しみやすいものではありません。 –

+0

私はpipe2を使う必要があると思います。しかし、私は、たとえば、かっこを破棄することができる必要があります。おそらくpipe4を使用して、パイプ関数に入力されている2つ(2番目と4番目)のかっこ文字を破棄することができますが、それ以上の破棄がある場合はどうなりますか?私は '。>>'と '。<<'で時間を短縮していますか? –

答えて

3

私は、これはあなたが探しているものだと思う:

let pIdentifier o = 
    let isIdentifierFirstChar c = isLetter c || c = '_' 
    let isIdentifierChar c = isLetter c || isDigit c || c = '_' 
    many1Satisfy2L isIdentifierFirstChar isIdentifierChar "identifier" <| o 

let pParameterList p = 
    spaces >>. 
     pchar '(' >>. spaces >>. sepBy (spaces >>. p .>> spaces) (pchar ',') 
      .>> spaces .>> pchar ')' 

type FunctionCall(Name: string, Parameters: string list) = 
    member this.Name = Name 
    member this.Parameters = Parameters 

let pFunctionCall o= 
    pipe2 (pIdentifier) (pParameterList pIdentifier) (fun name parameters -> FunctionCall(name, parameters)) <|o 
0

これは完全に不自然ですが、ここで私はそれがPIPE2を使用しての代わりに、以下のように見えると思うものだ| >>

type FunctionCall(Name: string, Parameters: string list) = 
    member this.Name = Name 
    member this.Parameters = Parameters 

let pFunctionCall = 
    pipe2 (pIdentifier) (pstring "(" >>. pParameterList .>> pstring ")") (fun name parameters -> FunctionCall(name, parameters)) 
0

機能的な答えは、ダニエルが述べたように、弁別された組合を使用することです。 FParsecには、状態モナドのように使用できるUserStateもあります。したがって、実際に複雑な型に直接解析したい場合は、それを使用できます。 [1]

[1] http://cs.hubfs.net/topic/None/60071