0

私の C ライクなプログラミング言語では、コンパイラに If-Else ブラケットを解析させたいと考えています。次のようなコードがあります。

if( varA == varB ) {
  if ( varB == varC ) {
   varA = 1;
  } else {
   varB = 1;
  }
};

これに解析する必要があります(架空のアセンブラ):

compare varA with varB
jump if equal to condition_2
jump to else_condition2  ; gets only executed if statement above does not get executed -> else

label condition_2:
compare varB with varC
jump if equal to if_bracket_1
jump to else_bracket_1

label if_bracket_1:
varA = 1;
jump to back_label

label else_bracket_1:
varB = 1;
jump to back_label 

label else_condition2: 
; nothing, because there is no else

label back_label:
nop ; continue main program here

条件を jump-if-equal などに解析する方法を知っています。また、解析方法が再帰的であることも知っています..しかし、この解析方法を実装する方法がわかりません..コードは必要ありません。アイデア、これを管理する方法。

ご協力いただきありがとうございます。

4

1 に答える 1

2

あなたが何を求めているのかははっきりしていません。私が理解していることから、ソースの解析またはコードの生成に問題があります。

解析部分については、手動で記述したい場合は、再帰降下法を簡単に使用できます。基本的に、式、ブロック、if、while、for などのステートメントなど、各構文クラスを解析する関数を作成します。再帰的にお互いを呼び出すようにします。通常、パーサー関数は AST ノードを返し、呼び出し元はそれらをより大きなノードで構成します。

あなたの例では、論理式、ifステートメント、式/ステートメントのブロック、およびifステートメントを解析するための関数があります。トークン ストリームにが表示ifされたら、if ステートメントが続くことがわかるので、適切な解析関数を呼び出しますparse_if。文法のおかげで、parse_ifandifステートメントは次のように見える必要がありますif (<logical expression>) <block> [else <block>]--角括弧はオプションのブロックを表し、角括弧は必須です。したがって、最初に論理式を解析する関数を再帰的に呼び出しますparse_logical_exp。これにより、後で最終的な AST にプラグインできる if ステートメントの論理式の AST ノードが返されます。then ブロックについても同様です。then ブロックを使用した後で、elseトークン ストリームで、ブロック解析関数を再度呼び出します。どのサブ関数もエラーを通知しなかった場合は問題ないので、最終的に if ステートメントの AST を構築し、それを呼び出し元に返すことができます。(Python) 擬似コード:

def parse_if(tokens):
    # Skip over the if token or signal an error if the current token is not an "if"
    tokens.expect("if")
    logical_condition = parse_logical_exp(tokens)
    if logical_condition is Error:
        raise ParseError(logical_condition.message)
    then_block = parse_block(tokens)
    if then_block is Error:
        raise ParseError(then_block.message)
    else_block = None
    if tokens.current() == "else":
        # Skip over the else token or signal an error
        tokens.expect("else")
        else_block = parse_block(tokens)
        if else_block is Error:
            raise ParseError(else_block.message)
    return IfNode(logical_condition, then_block, else_block)

これは単なる疑似コードであり、別の方法でエラー チェック/レポートを実行したい場合があることに注意してください。

あなたが言及しているかもしれない問題は、「dangling else problem」と呼ばれます。基本的に、else がどちらに属しているかはわかりません。ウィキペディアの記事から引用するには:

ぶら下がっているelseを扱うときの慣例は、elseを近くのifステートメントに付けることであり、特に、明確な文脈自由文法を可能にします。Pascal や C などのプログラミング言語はこの規則に従っているため、言語のセマンティクスにあいまいさはありません。

コード生成部分については、次の質問への回答に興味があるかもしれません:バイトコード コンパイラでジャンプ アドレスを計算するためのインテリジェントなソリューションは? .

于 2012-11-04T07:07:02.520 に答える