2009-04-24 7 views
5

Sono nuovo a Treetop e sto tentando di scrivere un parser CSS/HSS. HSS aumenta le funzionalità di base del CSS con stili nidificati, variabili e un tipo di funzionalità di mixin.Parser CSS/HSS in Treetop e Nested Stylesheet Rules

Sono abbastanza vicino - il parser può gestire i CSS - ma cado giù quando si tratta di implementare uno stile all'interno di uno stile. per esempio:

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

Ho preso due colpi a lui, quella che gestisce gli spazi e uno che non lo fa. Non riesco quasi nemmeno a lavorare. La documentazione sulle cime degli alberi è un po 'scarna e mi sento davvero come se mi mancasse qualcosa di fondamentale. Spero che qualcuno possa mettermi dritto.

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 

Codice 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

Puoi pubblicare l'errore/l'output che stai ottenendo? –

risposta

3

presumo si sta eseguendo in left recursion problemi? In tal caso, tieni presente che TreeTop produce recursive descent parsers e, in quanto tale, non puoi utilizzare la ricorsione sinistra nella grammatica. (Uno dei motivi principali per cui preferisco ancora ocamlyacc/ocamllex su TreeTop nonostante il suo aspetto molto sexy.) Ciò significa che è necessario convertire da forme ricorsive sinistre a ricorsione a destra. Dato che indubbiamente possiedi il numero Dragon Book (giusto?), Ti indicherò le sezioni 4.3.3, 4.3.4 e 4.4.1 che trattano il problema. Come è tipico, è difficile da capire, ma i parser non hanno ottenuto la loro reputazione per niente. C'è anche un bel left recursion elimination tutorial che i ragazzi di ANTLR mettono sull'argomento. È in qualche modo specifico per ANTLR/ANTLRworks, ma è leggermente più semplice da capire rispetto a ciò che si trova nel Libro del Drago. Questa è una di quelle cose che non ha mai molto senso per chiunque non l'abbia fatto almeno un paio di volte prima.

Inoltre, commento minore, se avete intenzione di utilizzare TreeTop, vi consiglio di fare questo, invece:

def ws 
    [\t ]* 
end 

Non molto probabile che mai bisogno per indicare un singolo carattere di spazio, oltre a quasi ogni grammatica la regola ne avrà bisogno, quindi ha senso chiamarla qualcosa di molto breve. Per inciso, i vantaggi sono in una fase di lexing separata. Questo è uno di loro.

+0

Ah, giusto! Supponevo che TreeTop fosse in grado di gestire la ricorsione a sinistra e mi mancava semplicemente qualcosa nella documentazione. Grazie mille per aver trovato il tempo per confermare questo. – toothygoose

1

sembra che qualcuno mi ha battuto ad esso:

http://lesscss.org/

Anche se mi accorgo che usano le espressioni regolari e un eval() per analizzare il file di input, piuttosto che un parser.

Modifica: ora usano TreeTop! È come se qualcuno abbia fatto tutto il duro lavoro per me.