8

ペット プロジェクトとして、Web スクリプト言語として使用できる、独自の設計による基本的な言語の実装を試みたいと考えています。C++ プログラムを Apache CGI として実行するのは簡単なので、実際の作業は、非コード (HTML/CSS マークアップ) とサーバー側コードを含む入力ファイルを解析する方法にあります。

学部生のコンパイラ コースでは、FlexBisonを使用して、単純な言語のスキャナーとパーサーを生成しました。私たちは文法のコピーを受け取り、単純な言語を仮想マシン用の単純なアセンブリに変換するパーサーを作成しました。flex スキャナーは入力をトークン化し、トークンを Bison パーサーに渡します。

それと私がやりたいことの違いは、PHP のように、この言語にはプレーンな HTML マークアップと、次のように散在するスクリプト言語を含めることができるということです。

<p>Hello,
<? echo "World ?>
</p>

次のように入力ファイルを解析するのが効率的であると仮定するのは間違っていますか?

  1. スクリプト開始タグが見つかるまで入力をスキャンします ('
  2. 2 番目のスキャナーは、入力ファイルのサーバー側スクリプト セクションを (開始タグ: '' から) トークン化し、そのトークンをパーサーに渡します。パーサーは、ファイル内のマークアップについて知る必要はありません。
  3. 制御は、この一般的なパターンを継続する最初のスキャナーに戻されます。

基本的に、最初のスキャナーは、マークアップ (変更されずにブラウザーに直接返される) と、2 番目のスキャナーに渡されるコードのみを区別します。2 番目のスキャナーは、コードをトークン化し、トークンをパーサーに渡します。

これが堅実な設計パターンでない場合、PHP などの言語はどのようにして入力のスキャンとコードの解析を効率的に処理するのでしょうか?

4

2 に答える 2

7

開始条件を確認したい。例えば:

"<?"            { BEGIN (PHP); }
<PHP>[a-zA-Z]*  { return PHP_TOKEN; }
<PHP>">?"       { BEGIN (0); }
[a-zA-Z]*       { return HTML_TOKEN; }

状態 0 から開始し、BEGIN マクロを使用して状態を変更します。特定の状態にある場合にのみ RE を一致させるには、RE の前に山かっこで囲まれた状態名を付けます。

上記の例では、「PHP」が状態です。「PHP_TOKEN」と「HTML_TOKEN」は、yacc ファイルで定義された _%token_s です。

于 2008-09-21T15:23:08.113 に答える
2

PHPは、スキャンとマークアップを区別しません。マークアップモードの場合は単にバッファに出力し、コードモードの場合は解析に切り替えます。2パススキャナーは必要ありません。これは、1つのフレックスレクサーで実行できます。

PHP自体がどのように機能するかに興味がある場合は、ソースをダウンロードしてください(PHP4ソースを試してみてください)。あなたが見たいのはZendDirectoryにありzend_language_scanner.lます。

自分と似たようなものを書いたので、フレックスとバイソンのルートを考え直して、Antlrのようなモダンなものを使うことを強くお勧めします。はるかに簡単で理解しやすく(lex文法で使用されるマクロは非常に混乱し、読みにくくなります)、デバッガー(AntlrWorks)が組み込まれているため、3Megのデバッグファイルを見るのに何時間も費やす必要はありません。 。また、多くの言語(Java、c#、C、Python、Actionscript)をサポートし、優れた本と非常に優れたWebサイトを備えており、すぐに稼働させることができます。

于 2008-09-19T20:06:15.517 に答える