Domanda

Sono nuovo di Cima di albero e il tentativo di scrivere un CSS / HSS parser. HSS aumenta le funzionalità di base di CSS con stili nidificati, variabili e una sorta di funzionalità mixin.

Sono abbastanza vicino - il parser in grado di gestire i CSS - ma cado giù quando si tratta di attuare uno stile di nel uno stile. per esempio:

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

Ho preso due colpi a esso, quella che gestisce gli spazi e uno che non lo fa. Non riesco a ottenere sia al lavoro. La documentazione cima d'albero è un po 'scarsa e mi sento come se mi manca qualcosa di fondamentale. Speriamo che qualcuno mi può impostare 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
È stato utile?

Soluzione

Presumo si sta eseguendo in sinistra problemi di ricorsività ? In tal caso, tenere a mente che produce TreeTop parser discesa ricorsiva , e come tale, si puo' t davvero usare la ricorsione sinistra nella tua grammatica. (Una delle principali ragioni per cui continuo a preferire ocamlyacc / ocamllex sopra TreeTop nonostante il suo aspetto molto sexy.) Questo significa che è necessario convertire da forme ricorsive sinistra a destra ricorsione. Dal momento che senza dubbio possiede il Drago libro (giusto?), I' ll dirigete alle sezioni 4.3.3, 4.3.4 e 4.4.1 che coprono il problema. Come è tipico, è difficile da capire, ma parser non ha ottenuto la loro reputazione per niente. C'è anche una bella sinistra esercitazione eliminazione ricorsione che i ragazzi ANTLR mettere sull'argomento. E 'un po ANTLR / ANTLRworks specifica, ma è leggermente più facile da capire di quello che ha trovato nel Libro Drago. Questa è una di quelle cose che proprio non mai fare un sacco di senso a chi non l'ha 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 di indicare un singolo carattere di spazio, oltre a quasi ogni regola grammaticale sta per bisogno, quindi ha senso chiamarlo qualcosa di molto breve. Per inciso, ci vantaggi ad un passo lexing separato. Questo è uno di loro.

Altri suggerimenti

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.

Edit: Ora usano TreeTop! E 'come se qualcuno ha fatto tutto il lavoro duro per me.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top