2017-01-17 6 views
1

私は、リンカスクリプトに私はどのようにバイソン/フレックスと解析するのですか?

example.ldを解析することにより、以下の例をしたいと思っ

MEMORY 
{ 
    INCLUDE example_include.ld 
} 

私はこれを行うことができますいくつかのコードを発見した

rom : ORIGIN = 0, LENGTH = 256K 

example_include.ld、それc flex/bisonであり、私はC++ flex/bisonを使用しています。私はyyFlexLexer lexer;私を提供 使用できることを考え出しまし

このようにyy_create_buffer()とは...私はbinutilsの/ LD/ldlex.lで見つけましたコードです。多分それが私を助けるかもしれない。

void 
lex_push_file (FILE *file, const char *name, unsigned int sysrooted) 
{ 
    if (include_stack_ptr >= MAX_INCLUDE_DEPTH) 
    { 
     einfo ("%F:includes nested too deeply\n"); 
    } 
    file_name_stack[include_stack_ptr] = name; 
    lineno_stack[include_stack_ptr] = lineno; 
    sysrooted_stack[include_stack_ptr] = input_flags.sysrooted; 
    include_stack[include_stack_ptr] = YY_CURRENT_BUFFER; 

    include_stack_ptr++; 
    lineno = 1; 
    input_flags.sysrooted = sysrooted; 
    yyin = file; 
    yy_switch_to_buffer (yy_create_buffer (yyin, YY_BUF_SIZE)); 
} 

私の問題は、良い例やドキュメント、C++ bison/flexの使い方が見つからないということですか?たとえば、保護されていて公開されていないため、yyinは使用できません。

答えて

2

最も簡単な解決策は、再帰的にパーサーを呼び出し、解析するファイルを渡すことです。外部パーサから内部パーサへの環境情報(解析の状態)の伝達方法に関する詳細は、内部データ構造の性質に大きく依存するため、推測。あなたがやっているのは、一見すると決して魅力的ではないにもかかわらず、ほとんど常に最良の解決策であるASTを構築している場合、パーザがASTを呼び出し元に返すこと以外は何もする必要はありません。それは正常にファイルを解析します。

一般に、パーサー(またはそのマネージャ)は、提供された入力ファイルをスキャンするための新しいLexerオブジェクトを作成します。 C++スキャナは完全にリエントラントなので、2つのレクサーの共存によって問題は発生しません。これにより、バッファスタックの使用が回避され、通常はよりクリーンなソリューションになります。

これはbison/flexパーサーの "インクルード"を扱う際の古典的な問題を回避します。つまり、インクルードされたファイルからインクルードファイルに構文的コンテキストが漏れ出すことができます。インクルードされたファイルに未終了ブロック(または終了していないコメント)が含まれている場合、その構文コンテキストはインクルードの最後にアクティブになり、直感的でなく、誤解を招く可能性のあるエラーメッセージが表示されることがあります。再帰的な方法では、インクルードされたファイルの最後に構文エラーが発生し、エラーリカバリが容易になります。

免責事項:私はflexとbisonによって生成されたスキャナとパーサのC++インターフェイスのファンではありません。多分いつか私は私の心を変えるでしょう。私はそれがちょうど知的怠惰かもしれないということを自由に認めます。いずれにしても、私が作った唯一のパーサーは、C++でアクションを記述していても、C APIを使用しています(多くの場合)。だから私はここでサンプルコードを提供していないが、私はそれが特に難しいとは思わない。

+0

私はドキュメンテーションに従い、そのようにしました。 BEGIN(incl)と一緒に。それはまだ非常に緩んでおり、私はここでさらに具体的に尋ねるかもしれません。 – j35t3r

関連する問題