Question

Je suis nouveau à arboricole et de tenter d'écrire un analyseur CSS / HSS. HSS augmente la fonctionnalité de base de CSS avec des styles imbriqués, variables et une sorte de fonctionnalité mixin.

Je suis assez proche - l'analyseur peut gérer CSS - mais je tombe quand il s'agit de mettre en œuvre un style dans les un style. par exemple:

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

J'ai pris deux coups de feu à elle, celui qui gère les espaces et qui ne fonctionne pas. Je ne peux pas tout à fait obtenir soit pour travailler. La documentation de la cime des arbres est un peu clairsemée et je me sens vraiment comme si je manque quelque chose de fondamental. Espérons que quelqu'un peut me détromper.

 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

Code de harnais:

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
Était-ce utile?

La solution

Je suppose que vous êtes en cours d'exécution dans gauche problèmes de récursion? Si oui, gardez à l'esprit que TreeTop produit parseurs descente récursive , et en tant que tel, vous pouvez » t vraiment utiliser la récursivité gauche dans votre grammaire. (L'une des principales raisons pour lesquelles je préfère encore ocamlyacc / ocamllex sur TreeTop malgré son apparence très sexy.) Cela signifie que vous devez convertir les formes récursives à gauche récursion droite. Puisque vous possédez sans doute le dragon Livre (droit?), Je ll vous direct aux sections 4.3.3, 4.3.4 et 4.4.1 qui couvrent la question. Comme il est typique, il est difficile à comprendre, mais parseurs n'a pas obtenu leur réputation pour rien. Il y a aussi une belle gauche tutoriel d'élimination de récursion que les gars ANTLR mettre en place sur le sujet. Il est un peu ANTLR / ANTLRworks spécifique, mais il est un peu plus facile à comprendre que ce qui se trouve dans le Dragon Book. C'est une de ces choses qui ne font pas tout simplement jamais beaucoup de sens pour quelqu'un qui n'a pas fait au moins quelques fois.

En outre, un commentaire mineur, si vous allez utiliser TreeTop, je recommande de faire ceci:

def ws
  [\t ]*
end

Vous n'êtes pas susceptible de jamais besoin de faire correspondre un seul caractère d'espace blanc, plus presque toutes les règles de la grammaire va en avoir besoin, il est donc logique de le nommer quelque chose de très court. Soit dit en passant, il y a sont des avantages à une étape de lexing séparée. C'est l'un d'entre eux.

Autres conseils

On dirait que quelqu'un me devança:

http://lesscss.org/

Bien que je remarque qu'ils utilisent des expressions régulières et un eval () pour analyser le fichier d'entrée plutôt que d'un analyseur.

Edit: Maintenant, ils utilisent TreeTop! Il est comme quelqu'un l'a fait tout le travail pour moi.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top