梢におけるCSS / HSSパーサおよびネストされたスタイルシートのルール
質問
私は樹上に新たなんだとCSS / HSSパーサを書き込もうとします。 HSSは、ネストされたスタイル、変数、ミックスイン機能の種類とCSSの基本的な機能を強化します。
パーサはCSSを扱うことができます - -私はかなり近いんだけど、それはの中ののスタイルスタイルを実装するに来るとき、私は落ちます。例えばます:
#rule #one {
#two {
color: red;
}
color: blue;
}
私は、それではない空白と1を扱うものを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
解決
私はあなたが左再帰の問題に実行していると仮定しますか?もしそうなら、ツリートップが生み出す心に留めておく再帰下降構文解析を、そのように、あなたは「できますtは本当にあなたの文法で左再帰を使用しています。 (私はまだその非常にセクシーな外観にもかかわらず、ツリートップの上にocamlyacc / ocamllex好む主な理由の一つ。)これは、あなたが右再帰を左再帰のフォームから変換する必要があることを意味します。あなたは間違いなくhref="http://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques,_and_Tools" rel="nofollow noreferrer">ドラゴンブックの(右?)左再帰除去チュートリアルでは、ANTLRの連中というの素敵な
あなたがツリートップを使用するつもりなら、 また、マイナーなコメントは、私の代わりにこれを行うことをお勧めします: あなたは今までに単一の空白文字を一致させる必要があり、加えて、ほぼすべての文法規則は、それは非常に短く、何かそれに名前を付けることは理にかなっていますので、それを必要としているとそうじゃありません。なお、が別字句ステップにの利点です。これはそのうちの一つです。def ws
[\t ]*
end
他のヒント
が見えるます:
私は、彼らがパーサではなく、入力ファイルを解析する正規表現とはeval()を使用することがわかりますが。
編集:今、彼らはツリートップを使用!誰かが私のためにすべてのハードワークをしたようなものだ。