Happy/Haskell で解析中に複数の意味値を保持するにはどうすればよいですか
-
28-09-2020 - |
質問
HaskellでAlex/HappyでシンプルなLexer/Parserを構築しようとしています。テキストファイルから最終的なASTにいくつかのローカリゼーション情報を保持したいと思います。
Alex を使用して、ローカリゼーションを備えたトークンのリストを構築するレクサーを構築することができました。
data Token = Token AlexPosn Foo Bar
lexer :: String -> [Token]
私の幸せなファイルでは、%トークンパーツを宣言するときに、$$シンボルでトークンのセマンティック部分を宣言できます
%token FOO { Token _ $$ _ }
解析ルールでは、$i はこの $$ を参照します。
foo_list: FOO { [$1] }
| foo_list FOO { $2 : $1 }
AlexPosn 部分を参照する方法はありますか? そして FOO トークンの Foo 部分に ?今のところ、そのうちの 1 つだけを参照する方法しかわかりません。「いくつかの $$ を追加する」方法に関する情報を見つけることができ、後で参照することができます。
そうする方法はありますか?
V.
解決
最後に、私は2つの解を見つけました:
-
タプルのすべての意味データをパックするので、このタプルを指すように$$を抽出します。 投影によるデータ:
data Token = Token (AlexPosn,Foo) Bar %token FOO { Token $$ some_bar } rule : FOO { Ast (fst $1) (snd $1) }
-
はまったく$$を使用しないでください。$$を使用しない場合は、解析中にフルトークンをお願いしますので、このトークンから本当に必要なものを抽出するのはあなた次第です。
.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番目のコードはコード行の間かなり重いかもしれません:あなたは手で「予測」を構築する必要があります(パターンマッチングなど)、安全な方法でそうすることができますあなたのトークンタイプがかなり大きい場合は
他のヒント
次のように複数の値を保持することも可能です。
data Token = Token AlexPosn Foo Bar
%token FOO { Token pos foo some_bar }
rule : FOO { Ast pos foo }
ただし、Happy が実際にこれが常に機能することを保証しているかどうかはわかりません。これが(おそらく)機能する理由は、happy がパターンに一致するコードを生成するためです。 Token pos foo some_bar
, 、作る pos
そして foo
で利用可能 Ast pos foo
.