0

私はこれについて何日も頭を悩ませてきましたが、検索しても結果が得られないようです。それが可能かどうか疑問に思います。例えば:

funct functionNAME (Object o) { o+1 };

ポイントは、ユーザーが中括弧内で識別子「o」を使用する必要があり、他の識別子を使用しないことです。もちろん、これは (Object o) 部分の入力によって指定されます。ここで、'o' は何でもかまいません。基本的に、中括弧内の識別子は、パラメーターで定義された識別子と同じでなければなりません。一致したトークンを保存して画面に出力できることはわかっていますが、それを字句トークン自体として使用することは可能ですか? ありがとう。

4

3 に答える 3

2

はい、これを行うより良い方法があります。シンボルテーブルが必要です。シンボル テーブルの役割は、プログラムの各ポイントでどの識別子を使用できるかを追跡することです。通常、シンボル テーブルには、識別子が何を表しているか (変数名や関数名など) やその型など、識別子に関するその他の情報も含まれています。

シンボル テーブルを使用すると、すべてではないが多くの言語の解析中にスコープ外の変数の使用を検出できます。たとえば、C と Pascal は、使用する前に識別子を宣言する必要がある言語です (いくつかの例外があります)。しかし、他の言語 (Java など) では、使用後に識別子を宣言することができます。その場合、プログラムが解析されるまで、宣言されていない変数の使用などのエラーを検出しようとしないことが最善です。(実際、Java では、識別子が別のファイルで宣言されている可能性があるため、すべてのファイルが解析されるまで待つ必要があります。)

ここでは、変数に関する情報のみを記録する必要があり、型情報はなく、使用前に宣言する必要があるという単純なシナリオを想定します。これで始められます。関数名をシンボル テーブルに追加することは気にしませんでした。

シンボル テーブルがフレームと呼ばれるもののスタックであるとします。各フレームは変更可能な一連の文字列です。(後で、文字列から追加情報への変更可能なマップに変更したい場合があります。)

void Start(): { }
{
    <FUNCTION>
    <IDENTIFIER>
    {symttab.pushNewFrame() ;}
    <LBRACKET> Parameters()  <RBRACKET> 
    <LBRACE> Expression() <RBRACE>
    {symtab.popFrame() ; }
}
void Parameters() : {}
{
     ( Parameter() (<COMMA>   Parameter() )* )?
}
void Parameter() : {  Token x ; }
    <OBJECT> x=<IDENTIFIER>
    { if( symtab.topFrame().contains(x.image) ) reportError( ... ) ; }
    { symtab.topFrame().add(x.image) ; }
}
void Expression() : {  }
{
    Exp1() ( <PLUS> Exp1() )*
}
void Exp1() : { Token y ; }
{
    y = <IDENTIFIER>
    { if( ! symtab.topFrame().contains(y.image) ) reportError( ... ) ; }
|
    <NUMBER>
}
于 2013-04-01T19:13:22.213 に答える
0

識別子 matchin の値を格納しo、識別子が同じ場合は中括弧をチェックインし、そうでない場合は例外をスローします。

于 2013-03-28T17:11:06.817 に答える
0

OPで示した例に基づいて、必要なものを取得する方法を考え出しました。これは、概念実証を行うために実装したソリューションの単純な変形です。簡単にするために、トークン定義などの些細なことは省略します。

void Start():
{
    Token x, y;
}
{
    <FUNCTION>
    <FUNCTION_NAME>
    <LBRACKET>
    <OBJECT>
    x = <PARAMETER>
    <RBRACKET>
    <LBRACE>
    y = <PARAMETER>
    {
        if (x.image.equals(y.image) == false)
        {
            System.out.println("Identifier must be specified in the parameters.");
            System.exit(0);
        }
    }
    <PLUS>
    <DIGIT>
    <RBRACE>
    <COLON>
}

これを行うより良い方法はありますか?

于 2013-03-31T15:56:10.240 に答える