0

プロジェクトに CUP パーサー ジェネレーターを使用することを検討しています。コンパイルしようとしている言語のいくつかの構造を正しく解析するには、シンボル テーブル (解析テーブルではなく、格納するテーブルを意味します) からの情報を使用するために (JFlex によって生成された) レクサーが必要です。 next_token() メソッドが呼び出されたときに正しいトークン タイプを生成するためのパーサーの識別子に関する情報)。シンボル テーブルの情報はプログラム テキストに静的に依存するため、これは next_token() メソッドがパーサーと「ロックステップで」呼び出された場合にのみ機能します。つまり、パーサーが別のトークンを必要とするたびにレクサーを呼び出す場合、これは機能しますが、(たとえば) レクサーを呼び出してトークンをキューにバッファリングする並列スレッドがある場合は機能しません。

したがって、問題は次のとおりです。CUP はどのようにレクサーを呼び出しますか? 次のトークンが必要なときはいつでもそれを呼び出しますか? もちろん、CUP 文法仕様を記述し、生成されたパーサーのソース ファイルを検査して何が起こっているかを確認することもできますが、それは必要以上の作業になる可能性があります。関連するウェブサイトでこれに関する情報を見つけることができませんでした。

あなたが提供できる助けをありがとう!

4

3 に答える 3

2

少し前にパーサーとスキャナーの実装を完了しました。これが私が見つけたものです:

実際、CUP は必要に応じてスキャナーを呼び出します。これまでに認識されたトークン (先読みトークン) の前に、常にもう 1 つのトークンをバッファーに入れています。事前にトークンをバッファリングする必要はありません。

そうは言っても、構文解析中にレクサーの状態を設定するのは難しい場合があります。これにより、多くの文法上の競合が発生する可能性があるためです。これは、CUP がプロダクションに埋め込まれたセマンティック アクションを表す方法に関係していると思います。それにもかかわらず、これは最初の設計を放棄せざるを得ませんでしたが、私が恐れていた理由ではありません.

これが誰かを助けることを願っています!

于 2015-02-20T16:15:59.430 に答える
0

この質問に答えるのがどれくらい遅れているかわかりませんが、コースワークの一環として 1 つのパーサーを作成しています..レクサーとパーサーにはそれぞれ Lex と CUP を使用しています。get Token 呼び出しで必要なときにスキャンするパーサーを呼び出すメインクラスも含めているので、ドライバークラスは次のようになります。

// construct the lexer, 
Yylex lexer = new Yylex(new FileReader(filename));
// create the parser
Parser parser = new Parser(lexer);
// and parse

パーサーの内部呼び出し:

Parser.parse() {
    ...
    this.cur_token = this.scan();
    ...
}

public Symbol scan() throws Exception {
    Symbol sym = this.getScanner().next_token();
    return sym != null ? sym : this.getSymbolFactory().newSymbol("END_OF_FILE", this.EOF_sym());
}

parser.parse();
于 2016-10-09T17:49:14.593 に答える