2

gawkスクリプト用のフレックスパーサーを書いています。スラッシュ(/)文字の用途を区別する際に問題が発生しています。

明らかに、単一の/は除算の演算子になりますが、2つのスラッシュは正規表現または除算の両方である可能性があります。今、それは解析します

int((r-1)/3)*3+int((c-1)/3)+1

正規表現を持つように

/3)*3+int((c-1)/

意図した除算演算の代わりに。フレックスに数式として認識させるにはどうすればよいですか?

今のところ、これはgawkの正規表現を認識するための私のフレックス正規表現です。

EXT_REG_EXP "\/"("\\\/"|[^\/\n])*"\/"

除算演算子は、私の演算子リストに含まれている必要があります。

OPERATOR "+"|"-"|"*"|"/"|"%"|"^"|"!"|">"|"<"|"|"|"?"|":"|"~"|"$"|"="

しかし、フレックスの正規表現は貪欲なので、2つの除算を正規表現として扱うと思います。

4

1 に答える 1

3

正規表現を明確に識別するための単純なトークン式を定義することは不可能だと思います。AwkのPosix仕様は、このようにあいまいさを指摘しています。

状況によっては、EREを囲むために使用されるスラッシュ('/')も除算演算子になる場合があります。これは、除算演算子が表示される可能性がある場合は常に、スラッシュが除算演算子であると見なされるように解決する必要があります。(単項除算演算子はありません。)

以降:

トークンEREとトークン'/'およびDIV_ASSIGNの間には、字句のあいまいさがあります。トークン'/'またはDIV_ASSIGNが有効なプログラムの次のトークンとして表示される可能性がある構文コンテキストで、入力シーケンスがスラッシュ文字で始まる場合、認識できる2つのトークンのうち長い方が認識されます。トークンEREが有効なプログラムの次のトークンとして表示される可能性があるその他の構文コンテキストでは、トークンEREが認識されます。

(「ERE」は「拡張正規表現」の略です。)このことから、Awkのトークナイザーは構文コンテキストを認識している必要があるため、正規表現を正常に識別できる可能性のある正規表現はないと安全に結論付けることができます。トークン。

正規表現を解析するためにAwk自体(または少なくとも1つの実装)がどのように定義されているかも確認する価値があります。元のAwk(One True Awkと呼ばれることもあります)では、正規表現の識別はパーサーの仕事です。パーサーは、正規表現の読み取りを期待する必要があると判断したときに、レクサーを明示的に「正規表現モード」に設定します。

reg_expr:
      '/' {startreg();} REGEXPR '/'     { $$ = $3; }
    ;

(これはlex.cstartreg()で定義されている関数です。)ルール自体は、除算演算子が無効になるコンテキストでのみ一致します。reg_expr

がっかりさせて申し訳ありませんが、それでもこれがお役に立てば幸いです。

于 2012-10-01T01:26:00.380 に答える