1

学校では、言語を設計してから実装するように割り当てられました (私はそれを実装するのがとても楽しいです =))。先生は yacc/lex を使うように言いましたが、私は Java + regex API を使うことにしました。私が設計した言語は次のようになります。

Program "my program"
var yourName = read()
if { equals("guy1" to yourName) }
  print("hello my friend")
else
 print("hello extranger")
end
Program End

ご覧のとおり、かなり基本的な言語です =)。

抽象クラスを作成してからなどのSentenceサブクラスを作成し、文の集まりだけのクラスを作成するなど、非常に OOP の方法で実装できると思いました。次に、すべての s で抽象メソッドを呼び出すため、言語に準拠するための最初のアプローチは 2 つのフェーズのみで構成されていました。VariableAssignmentIfSentenceProgramevalSentence

  1. 検索行の構文を特定する
  2. 各行に対応するクラスを作成する

もちろん、フェーズ Ii で何か問題が発生した場合、エラーが発生する可能性があります。

私の質問は、私はそれを間違っていますか?理論が言うように、すべての段階 (字句、構文、意味) を検討する必要がありますか? 単純な 2 フェーズ コンパイラを続行する必要がありますか?

4

5 に答える 5

5

多くの賢明な人々がこれについて考え、私が取ったあなたの投稿から、彼らはすべての段階が必要であるという結論に達しました.

したがって、コンパイラを機能させたい場合は、理論が指示する方法で行ってください。

なぜそれがフェーズを決定するのかを理解したい場合は、近道を試してください。おそらくもっと時間がかかります。


免責事項:コンパイラ理論についてはまったくわかりません


別のメモ: 問題があります。正規表現を使用して解決することにしました。今、あなたには2つの問題があります

于 2009-11-11T15:41:17.357 に答える
5

なぜインストラクターのアドバイスに従わず、yacc/lex を使用しないのかという明白な質問はしません。答えはわかっているからです。あなたは外に出て、クールだと思って学ぶのに役立つと思ったことをしたいと思っていました。残念ながら、そのアプローチはあなたの教授によって推奨されました。別の投稿が述べたように、多くの非常に賢い人々が、複数のアプローチを検討し、優れた解決策を見つけるために膨大な時間を費やしてきたからです。

2 フェーズ コンパイラを機能させることはできますが、エラーを検出するのが難しいため、完全なプロセスを実行するほどうまくいかないことを受け入れる必要があります。実際にはもっと難しい。場合によっては、手遅れになるまでエラーが発生したことさえわからないことがあります。つまり、すでにコンパイルされ、実行しようとしています。

それについてもっと知りたい場合は、2 段階のアプローチを使用すると、以前に遭遇した人々と同じ問題に遭遇することになります。ただし、最終的な解決策に到達するまでにはさらに長い時間がかかること、プロジェクトのポイントがドッキングされている可能性があり、正しく機能しない可能性があることを理解しておいてください。

とはいえ、クラスの他の誰よりも、あなたはそれについてもっと学ぶことになるでしょう。時間に余裕があれば、今のやり方でやりたいです。その知識は将来役に立つかもしれません。また、私はあなたの教授と話をして、あなたはより完全な理解を得たいので、彼の勧告に反して別の方法でそれを行うつもりだと彼に伝えます. おそらく、彼はあなたのプロジェクトが野心的であるという理由で、たとえそれが間違っていたとしても、あなたのプロジェクトを否定することはないでしょう。

結局のところ、大学でプロジェクトを行う目的は学ぶことです。

于 2009-11-11T15:50:03.967 に答える
1

正規表現のみを使用して言語を解析したい場合、言語は正規表現のみにすることができます。これは大きな制約です。たとえば、パーサーに各ネストの組み合わせを個別に教える必要があるため、任意の深いネストは不可能です。チューリング完全な正規言語を構築できるかどうかはわかりません。

于 2009-11-11T16:32:38.877 に答える
1

正規表現を使用して各行を解析すると、言語の構文が非常に制限されます。

構文がより複雑になると、正規表現 API だけを使用して各行を解析することはできなくなります。AND演算子とOR演算子を追加し始めると、正規表現で解析することさえif { equals("guy1" to yourName) }できなくなります。また、文字列リテラルのようにエスケープ文字をサポートし始めるとどうなりますか?\n

Java Regex API は語彙アナライザーを支援することができますが、そこからパーサーを作成する必要があります。いくつかのアプローチのいずれかを取ることができます。

  • Java を使用している場合は、Antlrを調べることができます(これにより、Java の正規表現ライブラリを使用して語彙呼び出しアナライザーを作成する必要がなくなります)。
  • 再帰降下パーサーを手で書くことができます

とりわけ

(また、「ステートメント」は、コンパイラテキストでより一般的な「文」の同義語です)

于 2009-11-11T15:51:29.037 に答える
0

本当に手を汚したい場合は、再帰降下パーサーをコーディングしてください。コンパイラの理論を理解したい場合は、antlr を使用して原則に集中し、実装をパーサー ジェネレーターに任せます。ところで、なぜあなたの人生を正規表現で複雑にするつもりですか?!

于 2009-11-11T16:16:21.670 に答える