2012-03-31 6 views
2

私はJavaのような言語のような "擬似コード"のための単純なパーサを作りたいと思っていました。擬似コードは次のようになり サンプル - 上記のコードは、その中に堅固であることをシンプルな疑似コード言語用のパーサーを作成していますか?

//This is a comment 
$x1 = readint 
$x2 = readint 

$dx = $x2 - $x1 
#f = $dx/2 

if ($dx > 0) 
{ 
    loop while(#f > 1) 
    { 
    print(#f) 
    #f = #f/2 
    } 
} 

注意が、ライン上に複数の文があることができない、整数は$で始まり、山車等#で始まる

このようなコードを解析するには、最初にStringTokenizerを使用してから正規表現を使用して、整数変数、浮動小数点変数、またはキーワードと一致させることができます。

このアプローチは良いですか?ループ内のステートメントの場合、どのように式を格納できますか?各繰り返しでトークン化する必要はありませんか?

式(#f = #f/2のような)を表記法に変換し、スタックに格納すると思います。そして、各反復において、オペランドをポップしながら、私は各変数の値を置き換えることができました。しかし、これは十分に効率的ですか?

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

+0

[この質問の可能な重複](0120-18753) – nobeh

答えて

10

このような言語のパーサーを作成したいと思っていますが、これは見た目よりもはるかに難しいことです。解析は非常によく研究されている問題であり、使用できる優れたアルゴリズムが数多くありますが、手作業で実装することは非常に困難です。 RPNの変換のようなトリックを構文解析のような小さな例に使うことができますが、完全なプログラミング言語を構築するには、はるかに複雑なトリックが必要です。

この複雑さの言語を解析するには、手作業で作成するのではなく、パーサージェネレータを使用することをお勧めします。 ANTLRJava CUPは、あなたが達成しようとしていることを正確に行うための2つのよく知られたツールです。そのうちの2つのうちの1つを使用することを強くお勧めします。

希望すると便利です。

+0

これらのいくつかを実装することは "実装するのが非常に難しいです。手作業のアルゴリズム(例えば、LL、L(AL)R、GLRなど)を実装し、単一のプロジェクトに使用しようと努力していると言えます。非常に難しいことではなく、仕事が少なくて済むので、できる限り市販のツールを手に入れなければならないということで合意しました。 –

+0

ありがとう!私は行って両者を見ていきますが、どちらかを選ぶことはできますか? :P私のサンプルコードを考えると、私はGPL、より小さなフットプリントなどの下で私のコードをリリースするだろうHehe、私は間違いなくパーサーを作るだろうが、おそらく他の日。 –

+0

@ VinayakGarg-私はどちらかの経験はあまりありませんが、ANTLRは広範なコミュニティ基盤を持っています。それは探検する価値があるかもしれません。 – templatetypedef

1

単純なケースでは、パーサを手動で書くことは意味があります。

しかし、StringTokenizerはすでにSIMPLEパーサーであるため、StringTokenizerを使用することは間違っていることを示す指標です。

通常、パーサーはcharを読み取り、そのcharの値に応じて状態を変更します。

単純なパーサ "b"は、 "大文字"の後に続く文字を小文字にします。 "" (これは審判の判定で、あなたが経験の浅いている場合は、正しくその電話をかけることができない場合があります)、簡単な言語では

String input = "aDDbcDDeaaef."; 

int pos = 0; 

int state = 0; 
while (pos < input.length()) { 
    char z = input.charAt (pos); 
    if (z == '.') break; 
    switch (z) { 
    case 'b': state = 1; break; 
    case 'e': state = 0; break; 
    default: 
     if (state == 0) { 
     System.out.print(Char.toLowerCase(z)); 
     } else { 
     System.out.print(Char.toUpperCase(z)); 
     } 
    } 
    pos ++; 
} 
+0

さて、あなたは "普通の言語のパーサー"という言葉をSIMPLEというパーサーに使っています。あなたの例は非常に単純な正規の言語パーサを示しています。元の質問では、字句のあいまいさがないため、その言語は単純であるとみなされました。しかし、言語そのものは文脈自由です。したがって、ここで実装した単純な有限状態オートマトンを使用して解析する方法はありません。 – dodecaplex

+0

whileループの最後の前に 'pos'のインクリメントがありません:) – loukios

2

を停止し、1は、多くの場合、十分にない手で再帰下降パーサを書くことができます。良いニュースはcoding a recursive descent parser is pretty straightforwardです。

確信が持てない場合は、得られる最も強力なパーサージェネレータの形で過剰使用してください。

+0

あなたのリンクはとても有益でした。その後、メタコンパイラ、そしてウェブサイト。おそらく、次の学期にはやってみたいと思います。しかし、現在私は時間と経験が不足しているので、私は過労に行くでしょう! –

関連する問題