3

Bison を使用してパーサーを生成するプロジェクトがあります。プロジェクト自体は SCons でビルドされており、私のコードはすべて C++ で書かれています。最初に決定したことの 1 つは、コードを 3 つの主要なディレクトリに分割することでした。includes、src、および test です。最初のディレクトリにはパブリックヘッダーのみを含めることができ、srcには実装とプライベートヘッダーの両方を含め、 testにはテストのみを含めることができます。

現在、この規則は 3 つのファイルによって破られています: stack.hhposition.hh、およびlocation.hh。Bison を C++ モードで使用しているため、これらは Bison によって自動的に生成されます。しかし、引数--defines=include/namespace/parser.hppを使用してパーサーのヘッダーを配置する場所を設定できますが、これらの 3 つのファイルを配置する場所を定義する方法が見つからないため、同じフォルダーに保存されます。src/namespace/parser.cpp .

きれいに処理する方法を知りたいです。これまでのところ、私は 2 つのアイデアを思いつきました。1 つ目は、%defineapi.locationを使用して、現在使用されているクラスに設定し (Bison がそれらのファイルを再度生成するのを防ぎます)、それらのファイルをそこに移動することです。もう 1 つは、自分で位置場所のクラスを再実装し、上記の API を使用してそれらを設定することです。1 つのアイデアは汚いハックのように聞こえますが、もう 1 つのアイデアは、このような単純なタスクのやり過ぎのように思えます。

パーサーによって使用されるヘルパーがインクルードディレクトリに配置され、 srcには実装のみが含まれていることを確認する他の (クリーンな) 方法はありますか?

編集:

これらのファイル (またはその代替ファイル) をパブリック ヘッダー フォルダーに配置する必要があるのは、 Bison によって生成されたparser.hppファイルに含まれているためです。その結果、parser.hpp を含むファイルを検索フォルダーのリストに追加せずにコンパイルすることはできません。現在、ソース フォルダーへのパスをインクルードに追加する必要があります。これにより、コンパイラーは、生成された parser.hpp ヘッダーの 1 か所でのみ必要な 3 つのファイルを見つけることができ、それを制御することはできません。意味不明で紛らわしいので、直していただきたいです。

4

2 に答える 2

1

あなたは自分のファイルをどこに置くべきかについて混乱しているようですが、少なくともあなたはを混乱させています. 一方で、include/ ディレクトリはパブリック ヘッダー用に予約されており、他のヘッダーは src/ の下に配置する必要があると言っています。一方、Bison のヘルパー クラスのヘッダー ファイル (これは確かに非公開です) は、実装コードではないため、include/ に入れる必要があると言っています。

Bison は、パーサーのメイン C++ ファイルと一緒にこれらのヘッダーをドロップする必要があり (そうであることを確認しているようです)、基準のセットの 1 つによると、それは適切な場所のようです。それでもそれらのヘッダーを別の場所に置きたい場合は、事後にそれらをコピーまたは移動する必要があると思います。私は SCons を気にしませんが、確かにそれを達成するためのルールを書くことができます。

于 2013-10-28T21:09:14.113 に答える
0

どうやら私が立ち往生している Bison のバージョン 2.5 では、多くの選択肢がありません。2.7以降、オプションを使用api.namespaceしてバイソンが生成されないposition.hhようにすることができますlocation.hh. 次に、これらのファイルを一度生成し、手動で移動して、このオプションを追加します。しかし、stack.hh の作成を防止したり、独自のものに置き換えたりするオプションは (現在の 3.0 でも) ありません。

したがって、現在適用できる唯一の解決策は、ビルダーによって bison が呼び出されるたびに、これらのファイルを必要な場所に移動することです。これは醜い汚いハックですが、システムの残りの部分で一貫性を保証するので、今のところそれを使用します。SCons では、次のように実装しました。

# Directories configuration

# Main directories
fnb      = 'f_n_b/'
include  = 'include/'
source   = 'src/'


###########################################################################

# Some modules and tests

###########################################################################

# Builds parser and scanner classes

Parser_yy_URI   = fnb    +'parser.yy'
Parser_cpp_URI  = source +'parser.cpp'
Parser_hpp_URI  = include+'parser.hpp'
Scanner_ll_URI  = fnb    +'scanner.ll'
Scanner_cpp_URI = source +'scanner.cpp'

Parser_cpp = env.CXXFile(
    source=Parser_yy_URI,
    target=Parser_cpp_URI,
    YACCFLAGS=['--defines='+Parser_hpp_URI, '--verbose']
)
Scanner_cpp = env.CXXFile(
    source=Scanner_ll_URI,
    target=Scanner_cpp_URI
)

CorrectBisonInstallation = [
    env.Command(
        include+WronglyPlacedBisonHelper_hh.name,
        WronglyPlacedBisonHelper_hh,
        Move("$TARGET", "$SOURCE")
    )
    for WronglyPlacedBisonHelper_hh in Glob(source+'*.hh')
    if  WronglyPlacedBisonHelper_hh.name in [
        'location.hh',
        'position.hh',
        'stack.hh'
    ]
]
Depends(
    CorrectBisonInstallation,
    [Parser_cpp, Scanner_cpp]
)

###########################################################################

# Some modules depending on Parser and Scanner classes

これは完璧な解決策とはほど遠い (moveビルド中に使用する!) が、より良い解決策が現れるまではこれを使用します。

于 2013-11-02T15:17:55.567 に答える