1

PHP で基本的なトークナイザーを作成しました。現在、ステートメントを区切るためにセミコロンは必要ありませんが、javascript に似たものを解析します。

a = 1
b = a + 1
echo b

T_IDENTIFIER  a
T_EQUAL       =
T_NUMBER      1
T_IDENTIFIER  b
T_EQUAL       =
T_IDENTIFIER  a
T_NUMBER      1
T_IDENTIFIER  echo
T_IDENTIFIER  b

これは私の最初のコンパイラなので、解析に進む準備ができているかどうかわかりません。レクサーでは改行を無視しているため、ステートメント間に区切りはありませんが、DSL ではセミコロンの代わりに改行を使用できます。

私の質問は、レクサーでステートメントを分離することについて心配し始めるべきですか、それともトークナイザーを変更して改行を含める必要があるのでしょうか?

4

4 に答える 4

1

改行が言語の一部である場合 (たとえば、ステートメントが行境界で終了することがあります)、おそらく ENDOFLINE をトークンとして生成する必要があります。この種はあなたのケースのように聞こえます。

改行が常に空白である場合、レクサーはそれらを空白として処理する必要があります。

改行が役立つ場合とそうでない場合があります (たとえば、ブロック スタイルの THEN 句が "THEN newline " によって導入される場合)、おそらく2 つの THEN トークンを生成する必要があります。1 つはTHENで、もう 1 つはTHENnewlineです。

レクサーは簡単に修正できるので、最初の試行でレクサーを正しく取得する方法を心配して自殺することはありません。ある程度正しく理解してから (たとえば、上記の経験則を使用して)、パーサーの作成に取り掛かります。パーサーがぎくしゃくするにつれて、字句解析器が改行または特別なトークンを生成することによってさらに支援する必要があるかどうかが明らかになるので、戻ってそれに応じて修正することができます。

于 2013-02-22T17:38:28.400 に答える
1

あなたが言語デザイナーなら、選択はあなた次第です。改行を特別なものとして扱う言語は厄介であり、改行を特別なものとして扱う言語 (Scala、Haskell、Icon) は面倒です。構文の詳細によっては、Euclid や Turing で行われているように、パーサーでステートメントを簡単に分離できる場合があります。例えば

<Statement> ::= <Var> = <Expression>
              | echo <Expression>
              | { Block }
              | if <Expression> <Statement> else <Statement>
              | while <Expression <Statement>
<Block> ::= <Statement> <Block>
         |  <Declaration> <Block>
         |  

ここまで曖昧さはありません。他の非終端記号に気をつけていれば、あいまいさはありません。

于 2013-02-22T18:10:04.430 に答える
1

「ステートメントを区切るのにセミコロンは必要ない」と言うとき、実際には「ステートメントを区切るのに改行が必要」であることを暗示しています。

トークンのフローでいくつかの T_ENDOFINSTRUCTION を生成することで、作業が楽になります。パーサーはそれを個別のステートメントで使用します。

于 2013-02-22T17:37:39.460 に答える
0

私はここ数週間で言語を設計しており、レクサーを手作業で作成しました。私の言語は NEWLINE をトークンとして扱いませんし、式の終わりを識別するのに SEMICOLON も必要ありません。式の構文自体が、ステートメントがいつ終了するかを定義します

これはほとんどの場合うまくいきますが、私の言語のすべてのステートメントは式でもあるため、いくつかのあいまいさがあります。

a(b) [メソッド呼び出し] vs a \n (b) [2 つの式] : 一部のトークンの前に NEWLINE を付けないことを明示的に要求します

4-2 [減算] 対 4 \n -2 [2 つの式] : また、単項演算子と同じトークンを使用する二項演算子では、それらの前に NEWLINE がないことが必要です。

それ以外に、ユーザーによる間違いを避けるために、2 つの式が同じ行にある場合は、それらをセミコロンで区切る必要があることを明示的に要求します。もちろん、あいまいさは関係ありません。次のようなタイプミスが検出されないようにするためです。

c = a adn b

これは、 b のみa adn bを返す単一のブロックとして理解されます。

于 2013-02-22T18:43:21.810 に答える