問題タブ [happy]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
haskell - Cabal ビルドでエラーが発生 - コードは手動で問題ないように見えますか?
私の開発中、alex/happy を手動で実行してパーサー ファイルを生成し、ghci を実行してコードをテストしてきました。これは問題なく動作し、GHCI に読み込まれますがcabal repl
、プログラムを実行するとファイルにエラーがスローされParser.hs
ます。
エラーは型エラーです:Couldn't match type '[a]' with 'Expression'
しかし、このコードを手動でテストしていたときはいつでもghci main
、コードは正常に動作しますか?
cabal がどのように機能するかを完全に理解していないかどうかはわかりませんが、happy から生成された haskell パーサーと cabal から生成された haskell パーサーがまったく異なることに気付きました。
以下に、cabal build コマンドのエラー メッセージの冒頭を添付しました。
編集
したがって、cabal ビルドが実行されるたびに Alec が指摘したように、それは-agc
フラグに満足して呼び出されますが、私はこれに気づいていなかったため、コードを微調整する必要がありました。
解決策は、フラグを使用して Happy パーサーをビルドし、-agc
そのようにコンパイルされるようにすることです。これにより、結果のパーサーがわずかに異なるため、パーサー内でいくつかの新しいエラーが発生する可能性がありますが、私の調査によるとcabal repl
、前述のフラグなしで幸せに実行する方法はありません。
parsing - 抽象構文ツリーのトラバースとパターン マッチング
Alex と Happy を使用して、構文解析している言語 (Solidity) の抽象構文ツリーを生成するパーサーとレクサーを作成しました。私の問題は、言語の特定の側面を適切にトラバースして一致させる方法です。目的は、結果の AST に対してコード分析を実行し、関数の不適切な使用、危険な呼び出し、特定の要素の欠落などの特定の問題をチェックするルール エンジンを作成することです。
これは私のデータのレイアウトで、AST として出力されます。(これは完全な AST ではなく、単なるスナップショットです)
私の現在の考え方は、[SourceUnit]
を関数に渡して特定のケースに一致させることで、パターン マッチングを使用することです。たとえば、次の関数はコードに一致し、状態変数宣言のデータ型を返します。
これにより、次のように出力されます。これは、必要なものの一部です。残念ながら、言語には複数のコントラクト宣言と複数の状態変数宣言が含まれている可能性があるため、この方法で完全に一致させることはできないと思います。
私はジェネリックプログラミングと「ボイラープレートを破棄する」についていくらか読んだことがありますが、それがどのように機能するか、またはそれを実装するための最良の方法が何であるかを正確には理解していません。
問題は、この方法でパターン マッチングに関して正しい軌道に乗っているか、それともより良い代替手段があるかということです。
bison - スペースで区切られた式リスト + if/then/else を使用して bison 文法の競合を解決する
次の yacc/bison/happy 文法があります。
bison -v
次の状況で2つの競合があることを教えてくれます:
で明示的な優先順位宣言を行うことで競合を解決しようとしまし%prec
たが、役に立ちませんでした。bison が必要に応じて競合を解決する (たとえば、削減ではなくシフトする) ことを考えると、これはそれほど悪くはありませんが、受け入れられた言語を変更せずに競合を取り除くにはどうすればよいでしょうか。
parsing - Haskell Parsec、MegaParsec、または Happy の単純な C 文法
私は、C ステートメントのサブセットを gcc _asm ステートメントにトランスパイルするプリプロセッサーを開発しています。このプロジェクトでは、一般的な Haskell テクノロジで記述された既存の C ステートメント パーサーを喜んで再利用するか、既存の作業のやり直しを避けるために単純な C サブセット パーサーから始めます。
残念ながら、これまでのところ、C 以外のすべての文法しか見つかりませんでした。また、Java/Go 用の Parsec 文法から始めることもできますが、MegaParsec の方が望ましい選択肢のように思われます。
小さな C サブセットの文法をすばやく開発できますが、より大きな C サブセットのすぐに使用できる文法を使用すると、C ステートメント パーサーの開発を完全にスキップして、プロジェクトの要である asm コード生成に集中することができます。
最終的には、C++ コードの一部をトランスパイルする LLVM パスに変わる可能性がありますが、すぐに使えるパーサーを見つけることができる場合は特に、迅速なプロトタイプを作成するために Haskell を好みます。