CSS / HSS المحلل في تريتوب وقواعد ورقة أنماط متداخلة
سؤال
أنا جديد على جيرتر أو محاولة كتابة محلل CSS / HSS. تعمل HSS على زيادة الوظيفة الأساسية ل CSS مع الأساليب المتداخلة والمتغيرات ونوع من وظيفة Mixin.
أنا قريب جدا - يمكن للمحلل التعامل مع CSS - لكنني أسقط عندما يتعلق الأمر بتنفيذ أسلوب داخل موضه. على سبيل المثال:
#rule #one {
#two {
color: red;
}
color: blue;
}
لقد اتخذت طلقتان في ذلك، والتي تتعامل مع المسافة البضجة وواحدة لا. لا أستطيع أن أحصل تماما على العمل. وثائق TreeTop هي قليلة قليلا وأشعر أنني حقا أفتقد شيئا أساسيا. نأمل أن يضعني شخص ما بشكل مستقيم.
أ:
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
ب:
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
المحلول
أفترض أنك تجري recursion اليسار مشاكل؟ إذا كان الأمر كذلك، ضع في اعتبارك أن تريتوب ينتج محلل النزول العودية, ، وبالتالي، لا يمكنك استخدام العودية المتبقية حقا في قواعد اللغة الخاصة بك. (أحد الأسباب الرئيسية التي ما زلت أفضل من ocamlyacc / ocamllex على جدرة reetop على الرغم من مظهرها مثير للغاية.) هذا يعني أنك بحاجة إلى التحويل من النماذج المتكررة اليسرى إلى العودية الصحيحة. منذ أن تملك بلا شك كتاب التنين (أليس كذلك؟)، سأوجهك إلى الأقسام 4.3.3 و 4.3.4 و 4.4.1 والتي تغطي القضية. كما هو نموذجي، من الصعب فهمه، لكن المحللين لم يحصلوا على سمعتهم مقابل لا شيء. هناك أيضا لطيفة اليسار العودية القضاء على البرنامج التعليمي أن رجال Antlr وضعوا على هذا الموضوع. إنها محددة من Antlr / Antlrworks إلى حد ما، لكنها أسهل قليلا في فهم ما هو موجود في كتاب التنين. هذه هي واحدة من تلك الأشياء التي لا تجعل الكثير من أي وقت مضى غير معروف لأي شخص لم يفعله مرة واحدة على الأقل عدة مرات من قبل.
أيضا، تعليق بسيط، إذا كنت ستستخدم Treetop، أوصي بهذا بدلا من ذلك:
def ws
[\t ]*
end
من غير المرجح أن تحتاج إلى تطابق حرف مسافة بيضاء واحدة، بالإضافة إلى أن كل قاعدة قواعدية تقريبا ستحتاج إليها، لذلك من المنطقي تسمية ذلك بشيء قصير جدا. بالمناسبة هناك نكون مزايا خطوة ليكسينغ منفصلة. هذا هو واحد منهم.
نصائح أخرى
يبدو أن شخصا ما فازني عليه:
على الرغم من أنني لاحظت أنهم يستخدمون التعبيرات العادية و eval () لتحليل ملف الإدخال بدلا من المحلل.
تحرير: الآن يستخدمون Treetop! انها مثل شخص ما فعل كل العمل الشاق بالنسبة لي.