2009-04-24 4 views
5

Treetopを初めて使用し、CSS/HSSパーサーの作成を試みました。 HSSはネストされたスタイル、変数、一種のmixin機能を備えたCSSの基本機能を強化します。TreetopとネストされたスタイルシートルールのCSS/HSSパーサー

パーサーはCSSを処理できますが、スタイルを実装するにあたっては、のスタイルでになります。例:

空白を処理するショットと空でないショットを2回撮影しました。私はどちらかといえば働くことができません。ツリートップ文書は少し疎ですが、私は何か基本的なものを見逃しているような気がします。私は、

A:

grammar Stylesheet 

     rule stylesheet 
     space* style* 
     end 

     rule style 
     selectors space* '{' space* properties? space* '}' space* 
     end 

     rule properties 
     property space* (';' space* property)* ';'? 
     end 

     rule property 
     property_name space* [:] space* property_value 
     end 

     rule property_name 
     [^:;}]+ 
     end 

     rule property_value 
     [^:;}]+ 
     end 

     rule space 
     [\t ] 
     end 

     rule selectors 
     selector space* ([,] space* selector)* 
     end 

     rule selector 
     element (space+ ![{] element)* 
     end 

     rule element 
     class/id 
     end 

     rule id 
     [#] [a-zA-Z-]+ 
     end 

     rule class 
     [.] [a-zA-Z-]+ 
     end 
end 

B:

grammar Stylesheet 

    rule stylesheet 
    style* 
    end 

    rule style 
    selectors closure 
    end 

    rule closure 
    '{' (style/property)* '}' 
    end 

    rule property 
    property_name ':' property_value ';' 
    end 

    rule property_name 
    [^:}]+ 
    <PropertyNode> 
    end 

    rule property_value 
    [^;]+ 
    <PropertyNode> 
    end 

    rule selectors 
    selector (!closure ',' selector)* 
    <SelectorNode> 
    end 

    rule selector 
    element (space+ !closure element)* 
    <SelectorNode> 
    end 

    rule element 
    class/id 
    end 

    rule id 
    ('#' [a-zA-Z]+) 
    end 

    rule class 
    ('.' [a-zA-Z]+) 
    end 

    rule space 
    [\t ] 
    end 

end 

ハーネスコード:

require 'rubygems' 
require 'treetop' 

class PropertyNode < Treetop::Runtime::SyntaxNode 
    def value 
    "property:(#{text_value})" 
    end 
end 

class SelectorNode < Treetop::Runtime::SyntaxNode 
    def value 
    "--> #{text_value}" 
    end 
end 

Treetop.load('css') 

parser = StylesheetParser.new 
parser.consume_all_input = false 

string = <<EOS 
#hello-there .my-friend { 
    font-family:Verdana; 
    font-size:12px; 
} 
.my-friend, #is-cool { 
    font: 12px Verdana; 
    #he .likes-jam, #very-much {asaads:there;} 
    hello: there; 
} 
EOS 

root_node = parser.parse(string) 

def print_node(node, output = []) 
    output << node.value if node.respond_to?(:value) 
    node.elements.each {|element| print_node(element, output)} if node.elements 
    output 
end 

puts print_node(root_node).join("\n") if root_node 

#puts parser.methods.sort.join(',') 
puts parser.input 
puts string[0...parser.failure_index] + '<--' 
puts parser.failure_reason 
puts parser.terminal_failures 
+0

エラー/出力を投稿できますか? –

答えて

3

私はあなたが​​問題に実行していると仮定?その場合、TreeTopはrecursive descent parsersを生成することに注意してください。そのため、文法では左再帰を実際に使用することはできません。 (私はまだ非常にセクシーな外観にもかかわらず、私はまだTreeTop上のocamlyacc/ocamllexを好む主な理由の一つです。)これはあなたが左の再帰的なフォームから右の再帰に変換する必要があることを意味します。あなたは間違いなくDragon Bookを所有しているので(右か?)、問題を扱うセクション4.3.3,4.3.4、および4.4.1に案内します。典型的なように、理解しづらいですが、パーサーは何の評判も得ていませんでした。また、ANTLRの人たちがこの問題に取り組んでいるのは素敵なleft recursion elimination tutorialです。多少ANTLR/ANTLRworksのものですが、Dragon Bookに書かれているものよりも少しわかりやすいです。これは、少なくとも数回前にそれをやったことのない人には全く意味を持たないものの1つです。あなたがツリートップを使用するつもりなら

はまた、マイナーなコメントは、私の代わりにこれを行うことをお勧めします:

def ws 
    [\t ]* 
end 

あなたは今までに、単一の空白文字、プラスほぼすべての文法を一致させる必要はありそうじゃありませんルールはそれを必要とするため、非常に短い名前を付けるのが理にかなっています。ちなみに、は、別のレキシングステップに対しての利点があります。これはその一つです。誰かが私を打ち負かすよう

+0

ああ、そうです!私はTreeTopが左再帰を処理できると仮定しましたが、私はドキュメントで何かを見逃していました。これを確認する時間をとってくれてありがとう。 – toothygoose

1

はルックス:

http://lesscss.org/

私は、彼らが入力ファイルではなく、パーサーを解析する正規表現とはeval()を使用することがわかりますが。

編集:今はツリートップを使用しています!誰かが私のために大変な仕事をしたようなものです。

関連する問題