4

HaskellでAlex/Happyを使用して単純なレクサー/パーサーを構築しようとしています。テキストファイルのローカリゼーション情報を最終的なASTに保持したいと思います。

ローカリゼーションを使用してトークンのリストを作成するAlexを使用してレクサーを作成することができました。

data Token = Token AlexPosn Foo Bar
lexer :: String -> [Token]

Happyファイルで、%token部分を宣言するときに、$$記号を使用してトークンのセマンティック部分を宣言できます。

%token FOO  { Token _ $$ _ }

解析ルールでは、$iはこの$$を参照します。

foo_list: FOO  { [$1] }
        | foo_list FOO { $2 : $1 }

AlexPosn部分FOOトークンのFoo部分を参照する方法はありますか?今のところ、私はそれらのうちの1つだけを参照する方法しか知りません。''いくつかの$$を追加する''方法に関する情報を見つけて、後でそれらを参照することができます。

そうする方法はありますか?

V。

4

2 に答える 2

4

結局、私は2つの解決策を見つけました:

  • $$ がこのタプルを指すように、すべての意味データをタプルにパックし、射影によってデータを抽出します。

    data Token = Token (AlexPosn,Foo) Bar
    %token FOO { Token $$ some_bar }
    rule : FOO  { Ast (fst $1) (snd $1) }
    
  • $$ はまったく使用しないでください: $$ を使用しない場合、解析中に happy が完全なトークンを提供するため、このトークンから本当に必要なものを抽出するのはあなた次第です:

    data Token = Token AlexPosn Foo Bar
    %token FOO = { Token _ _ some_bar }
    rule : FOO  { Ast (get_pos $1) (get_foo $1) }
    
    get_pos :: Token -> AlexPosn
    get_foo :: Token -> Foo
    

    ...

私は最初のものは最もエレガントだと思います。2 番目のものは、大量の情報を運ぶ場合、コード行の点で非常に重くなる可能性があります。手動で「プロジェクション」を構築する必要があり (パターン マッチングなど)、安全な方法でこれを行うのは難しい場合があります。トークンの種類が非常に大きい場合。

于 2010-07-28T08:32:31.200 に答える