3

パラメータをレクサーに渡すことができることを知っています:

rule tokenize scope = parse
  | whitespace       { tokenize scope lexbuf                       }
  | newline          { newline lexbuf; tokenize scope lexbuf       }

しかし、同様の方法でパーサー開始シンボルを定義することはできません。

私はそれを次のように定義しようとしました:(この質問のおかげで)

%type < (IScope, AST.Script) Fun > Script

// with the following definition in the head section of the parser:
type ('a,'b) Fun = 'a -> 'b

しかし、このようにすべての非終端記号を定義する必要があり、それらはすべてラムダを返します。scopeこれは私が達成しようとしているものではありませんが、いくつかの非端末内でパラメーターにアクセスし、解析中にそれらのアクションを実行できるようにしたいと考えています。

のみを含むIParseStateタイプに があることに気付きましたParserLocalStore(デバッグによってのみチェックされます)。私はすべての非ターミナルからアクセスできるので、そこにパラメータを保存できますか、それとも悪い考えでしょうか?LexBufferparseState

パーサーの head セクションで変更可能な変数を使用することを考えましたが、それらは静的であり (私が思うに?)、複数の入力を同時に解析することはできません...

編集:

scope現在、特定のトークンにパラメーターを保存します。

%token <string * IScope> IDENT

レキサーは、トークンをscope作成するときに関連するトークンにそれを埋め込みます... 私はこの解決策が本当に好きではありませんが、まだより良いものを思いつくことができませんでした.

4

1 に答える 1

0

には があり、Dictionary<string, obj>からLexBufferも入手できますparseState。より良い解決策が見つからなかったので、パラメータをそこに保存することになりました。

私は、これがそのような方法で使用されることを意図していない可能性が非常に高く、fsyacc の将来のバージョンでは使用できない可能性があることを認識していますが、今のところはそれに固執しています。誰かが同じことをする必要がある場合に備えて、よりクリーンな方法でパラメーターにアクセスするために作成した 2 つの拡張メソッドをここに残します。

type IParseState with
    member x.LexBuffer() = x.ParserLocalStore.["LexBuffer"] :?> LexBuffer<char>

type LexBuffer<'a> with
    member x.SomeParameter
        with get() = x.BufferLocalStore.["SomeParameter"] :?> SomeParamType
        and set(v) = x.BufferLocalStore.["SomeParameter"] <- v

まだ回答がありませんので、とりあえずこれで承認します。より良い解決策を提案してください。受け入れられた回答を変更します。

于 2012-10-24T06:55:03.723 に答える