2012-05-30 10 views
6

私はScalaパーサーが動作していますが、私が望むほどクリーンではありません。問題は、プロダクションのいくつかがトークンの一部として空白を考慮する必要がありますが、 "上位レベル"のプロダクションは空白を無視/スキップできることです。Scala時には空白をスキップして時々そうでないパーサー

下位レベルのパーサーを拡張する典型的なスカラーパーサーパターンを使用すると、skipWhitespace設定が継承され、非常に手早くなります。

私は、拡張アプローチを使用しないほうがよいと思うが、より高いレベルのパーサのクラスで利用可能な低レベルパーサーのインスタンスを持っている方がよいと思う。しかし、そのような作業を行う方法はわからない各インスタンスは入力文字列を1つしか表示しません。その後、私は

class NumberParser extends VulgarFractionParser with Positional { 

のようなことを伸ばすしかし、この時点でNumberParserが明示的にちょうどFractionParserのように空白処理しなければならない

class VulgarFractionParser extends RegexParsers { 
    override type Elem = Char 

override val whiteSpace = "".r 

- ここ

は最低レベルのパーサの一部です。 NumberParserの場合はまだかなり管理しやすいですが、次のレベルでは、実際には正規表現を定義することができます。通常のregexParserのように空白を区切り記号として使用します。第二値は時々、「/」で区切られた2つの部分があり、時には唯一のスラッシュの後に何も単一の部分を持っている(あるいはスラッシュを含まない

IBM 33.33/ 1200.00 
or 
IBM 33.33/33.50 1200.00 

例は次のようなものになるだろうまったく)。

def bidOrAskPrice = ("$"?) ~> (bidOrAskPrice1 | bidOrAskPrice2 | bidOrAskPrice3) 

    def bidOrAskPrice1 = number ~ ("/".r) ~ number ~ (SPACES) ^^ { 
    case a ~ slash ~ b ~ sp1 => BidOrAsk(a,Some(b)) 
    } 
    def bidOrAskPrice2 = (number ~ "/" ~ (SPACES)) ^^ { case a ~ slash ~ sp => BidOrAsk(a,None) } 
    def bidOrAskPrice3 = (number ~ (SPACES?)) ^^ { case a ~ sp => BidOrAsk(a , None)} 
+0

空白を考慮するプロダクションの例と、空白を考慮しないプロダクションの例を挙げてください。 – sarnold

+0

は、データの例と空白に敏感な要素の1つで質問を更新しました。 – malsmith

答えて

2

それは(実際には、レクサー)トークンパーサに最初のパーサを回すために多くの意味がありませんが、その代わりに、第二のパーサーの読み取りを行いますプレーンCharの?

+1

私はこのアプローチの例を見たことがありませんが、私が望むもののように聞こえます。 – malsmith

関連する問題