2009-04-24 2 views
5

Я новичок в Treetop и пытаюсь написать парсер CSS/HSS. HSS дополняет базовую функциональность CSS с вложенными стилями, переменными и своего рода функциональностью mixin.CSS/HSS Parser в правилах Treetop и вложенных таблиц стилей

Я довольно близко - синтаксический анализатор может обрабатывать CSS - но я падаю, когда дело доходит до реализации стиля в пределах стиля. например:

#rule #one { 
    #two { 
    color: red; 
    } 
    color: blue; 
} 

Я взял два выстрела в него, один, который обрабатывает пробелы и тот, который не делает. Я не могу заставить работать. Документация на верхушке деревьев немного редки, и я действительно чувствую, что мне не хватает чего-то фундаментального. Надеюсь, кто-то может установить меня прямо.

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 

Harness Код:

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

Я предполагаю, что вы работаете в left recursion проблемы? Если это так, имейте в виду, что TreeTop производит recursive descent parsers, и поэтому вы не можете использовать левую рекурсию в своей грамматике. (Одна из основных причин, по которым я по-прежнему предпочитаю ocamlyacc/ocamllex над TreeTop, несмотря на его очень сексуальный внешний вид.) Это означает, что вам нужно преобразовать из левых рекурсивных форм в правильную рекурсию. Так как вы, несомненно, являетесь владельцем Dragon Book (справа?), Я направлю вас на разделы 4.3.3, 4.3.4 и 4.4.1, которые охватывают эту проблему. Как это обычно бывает, трудно понять, но парсеры не получили своей репутации ни за что. Там также хороший left recursion elimination tutorial, что парни ANTLR выставили на эту тему. Это несколько ANTLR/ANTLRworks, но это немного легче понять, чем то, что содержится в книге Дракона. Это одна из тех вещей, которые просто не имеют особого смысла для тех, кто еще не сделал этого, по крайней мере, несколько раз.

Кроме того, незначительный комментарий, если вы собираетесь использовать Treetop, я рекомендую делать это вместо:

def ws 
    [\t ]* 
end 

Вы вряд ли когда-нибудь должно соответствовать один символу пробела, а также почти каждая грамматика правило понадобится, поэтому имеет смысл называть его чем-то очень коротким. Кстати, там есть преимущества отдельного лексинга. Это одна из них.

+0

Ах, правильно! Я предположил, что TreeTop сможет обрабатывать левую рекурсию, и я просто что-то пропустил в документации. Большое спасибо за то, что нашли время, чтобы подтвердить это. – toothygoose

1

Похоже, кто-то меня опередил:

http://lesscss.org/

Хотя я заметил, что они используют регулярные выражения и в Eval() для разбора входного файла, а не парсер.

Редактировать: Теперь они используют TreeTop! Это похоже на то, что кто-то сделал для меня всю тяжелую работу.

 Смежные вопросы

  • Нет связанных вопросов^_^