2017-01-12 15 views
2

私は式の文字列をトークンに分割しようとしています。 Iveは良い出発点を見つけました」([A-Za-z] + | [0-9。] + | [& => < \ |!] + | \ S) ' しかし、これは負の数に問題があります。正規表現を使ったトークン化の数式

turns: '5--4=sin(2+3)' 
into: ['5','-','-','4','=','sin','(','2','+','3',')'] 
want: ['5','-','-4','=','sin','(','2','+','3',')'] 

とも

turns: -3+3 
into: ['-','3','+','3'] 
want: ['-3','+','3'] 

数がある場合、私の正規表現はの左側にチェックし、何かを使用することができますように見えます「 - 」場合次の数字でそれを保持しないでください(「-3」は左に何もしません)。それは正規表現を使用して行うことができますか?または、これを.NETで分割するための優れたツールがありますか?

答えて

1

正規表現は、すべてのコンテキストで必要な処理を実行するのに十分強力ではありません。正規表現を整数リテラルの一部として+または-と認識させることはできますが、たとえば数字シーケンスの前にオプションの[+-]?を追加すると、結果の正規表現は'-3+3'['-3', '+3']demo)としてトークン化します。

レクサージェネレータを使用するとこの問題は解決されます。代わりに、パーサの単項演算子をオペランドで "束ねる"ことができます。

+0

ああ、正規表現は完全にレキシングに適しています - それはChomskyタイプ3の問題です。 OPは彼が得た結果が実際に彼が必要とするものであることを認識しません。 ' - ' '3'では、' - 'は実際には単項否定演算子です。 –

+0

@LucasTrzesniewskiもちろん、正規表現は完全にレキシングに適していますが、OPは彼のレキシングを文脈依存にしたいと考えています。彼は、彼が望むものでも正規表現が提供できるものでもない、「-3-3」の2つのマイナスが異なって扱われることを望んでいる。 – dasblinkenlight

+0

はい、あなたの答えをもう一度読み終えたら、あなたが意味するものが得られます。ところで、レクサージェネレータは "問題"を魔法のように修正するだけではなく、ほとんどの場合正規表現をフードの下で使用します;) –

2

問題に正しく近づいていません。あなたが実際にを得た結果はです。

-3+3がに解析する必要があります:それは

operator binary + 
| 
+-- operator unary - 
| | 
| +-- 3 
| 
+-- 3 

あなたは多くあいまいさを避けるためだろう、数学の表現について、このように推論する方がはるかに簡単になります。ただ-を常にトークンにして、それをバイナリマイナスまたは単項否定演算子として使用してください。

このように問題に近づく私の関連する回答については、hereを参照してください(ANTLRを使用しますが、レキシングパスは私があなたにアドバイスしているとおりです)。

関連する問題