2016-04-01 14 views
1

は、私は次の規則があります。呼び出し式の再帰的降下構文解析プログラムを書くには?

factor ::= id | func | (expr) 
func ::= id (list) 
list ::= list , expr | expr 

私はシンプルな下降パーサ書く:

function factor() { 
    if (lookahead === "(") { 
    match("("); 
    expr(); 
    return match(")"); 
    } else { 
    id(); 
    } // How to understand what it can be a func here? 
}; 
​ 
function func() { 
    id(); 
    match("("); 
    list(); 
    match(")"); 
}; 

しかし、どのようにFUNCとidを組み合わせることを?このような文法要素を左

+0

多くの場合、最も長い一致がキャプチャされるように、パーズルーチンでテストを注文する必要があります。あなたがidを試す前に、factorで "func"を呼んでみてください。構文一致エンティティが失敗したときに入力ストリームをバックアップするためのサポートが必要になるか、ルールの共通部分を左寄せする必要があります。代替:funcルールの内容をfactorルールに持ち上げます。 –

+0

あなたのパーサには、構文エラーを処理するための多くのサポートがありません。再帰的な降下パーサーを書く方法については私の答えを参照してください:http://stackoverflow.com/questions/2245962/is-there-an-alternative-for-flex-bison-that-is-usable-on-8-bit-埋め込みシステム/ 2336769#2336769 –

+0

私はできる限り左翼をしようとしています。ここでそれを行う方法?それとも2のための先読みが必要ですか?または、funcルールのトークンをプッシュバックできませんか? –

答えて

1

factor ::= id ('(' list ')')? | '(' expr ')' 
list ::= expr (',' expr); 

リテラルの括弧の注意慎重に区別「(」と「)」 と構文グループ化括弧(...)

読者に左コーディング

: - }

詳細については、再帰的なパーサの書き方についての私の答えをチェックしてください。

+0

これはまだ同じです。私は回復が最良の解決策になると思います。 –

+0

ここで「同じ」とは何を意味するのか分かりません。この形式では、REパーサーは入力ストリームをバックアップする必要はありません。入力のストリームをリカバリポイント(たとえば、認識ルーチンが入力されたときの場所)に巻き戻すことは、表現の利便性または元の文法への忠実さを望む場合には、トークンをトラッキングすることでより多くのオーバーヘッドが発生する巻き戻しが発生する。 –

関連する問題