1

Eclipse プラグイン用の JAVACC を使用して、単純な Verilog HDL パーサーを作成しています。

このプラグインでは、すべてのパラメータとワイヤがアウトライン ビューに登録されます。この機能により、インクルード ファイルに多くの宣言がある場合、アウトライン ビューで目的の信号を見つけるのが難しくなります。概要リストを短くするために、インクルード ファイルからサブフォルダーにパラメーター (およびその他の信号) を収集します。

パーサーは実際には 2 つのパスで動作します。これは、すべてのコンパイラ派生物が最初に解決され、結果の文字列が Verilog パーサー (JAVACC) に渡されることを意味します。

このため、JAACC パーサーはインクルード ファイルの開始位置と終了位置を認識できません。

この問題を解決するために、include 関連の情報を持つ SPECIAL_TOKEN を追加しました。

Lexer は SPECIAL_TOKEN を正しく検出しますが、SPECIAL_TOKEN の前処理本体からパーサーの関数を呼び出す方法が見つかりませんでした。(実は、クラスが違うので合理的です)

ページの最後のセクション ( https://javacc.java.net/doc/tokenmanager.html )で説明されているソリューションを使用できると思います。ただし、通常のトークンのすべての発生にそのようなコードを追加する必要がありますね。ご存じのとおり、Verilog の文法は非常に複雑で、上記の解決策を受け入れることができませんでした。

この問題を解決する良い解決策はありますか?

4

1 に答える 1

1

パーサーが静的である場合は、パーサー関数を静的にします。

パーサーが静的でない場合は、トークン マネージャーがそのパーサーに戻るポインターを持つように調整できます。このポインターを次のように宣言します。

TOKEN_MGR_DECLS : { VerlilogParser myParser ; }

次に、パーサーが解析を開始する前に、このフィールドを設定してください

VerilogParserTokenManager tokMan = new VerilogParserTokenManager(in) ;
VerlilogParser parser = new VerlilogParser(tokMan) ;
tokMan.myParser = parser ;
parser.start() ;

先読みによって、トークン マネージャーがパーサーよりもはるかに先を行く可能性があることに注意してください。したがって、トークン マネージャーからパーサーを呼び出す場合は、十分に注意する必要があります。前処理後の行番号を C++ で前処理前の行番号とファイル名に関連付けるという問題を解決した方法は、一方から他方へのマッピングを表すテーブルを作成したことです。これはhttps://code.google.com/p/the-teaching-machine-jhigraph-and-webwriter-plus-plus/source/browse/trunk/trunk/tm/src/tm/cpp/parserで確認できます/cplusplus.jj . ここにいくつかの抜粋があります:

パーサーが次のトークンの元の座標を知る必要がある場合、次のように定義された getCoords(0) を呼び出します。

 // Coordinates
 SourceCoords getCoords(int offset ) {
     return pc.line_map.getCoords(getToken(offset).beginLine) ; }

line_map テーブルは、次のコードを使用してトークン マネージャーによって埋められます。

SPECIAL_TOKEN :
{
    // Line directives should have the form
    // #line linenum filename
    // or
    // #line linenum
    // In the latter case the previous file name is kept.
    "#line" : LINE_DIRECTIVE
}

<LINE_DIRECTIVE> SPECIAL_TOKEN :
{
    <LINE_NO : (["0"-"9"])+>
    { tokenLine = matchedToken.beginLine+1 ;
      sourceLine = Integer.parseInt (matchedToken.image.trim()); }
|
    <FILE_NM : "\"" (["0"-"9"])+ "\"">
    { file = fileMap.get( new Integer(matchedToken.image.substring(1, matchedToken.image.length()-1) ) );}
|
    " "
|
    "\n" { pc.line_map.add (tokenLine, sourceLine, file); } : DEFAULT
}
于 2013-06-27T13:53:08.170 に答える