CSS / HSS Analizador de Cima del árbol y anidadas reglas de estilo
Pregunta
Soy nuevo en copa de árbol y el intento de escribir una CSS / HSS analizador. HSS aumenta la funcionalidad básica de CSS con estilos anidados, variables y un tipo de funcionalidad mixin.
Estoy bastante cerca - el analizador puede manejar CSS - pero me caigo cuando se trata de implementar un estilo en un estilo. por ejemplo:
#rule #one {
#two {
color: red;
}
color: blue;
}
Me he tomado dos veces contra él, uno que se ocupa de los espacios en blanco y uno que no lo hace. No acabo de obtener ya sea para trabajar. La documentación de los árboles es un poco escaso y realmente siento que estoy perdiendo algo fundamental. Espero que alguien me puede enderezar su rumbo.
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
Código Arnés:
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
Solución
Asumo que se está ejecutando en izquierda problemas de recursividad ? Si es así, tenga en cuenta que de TreeTop produce analizadores descendente recursivo , y como tal, se puede' t realmente usar recursión por la izquierda en su gramática. (Una de las principales razones por las que todavía prefieren ocamlyacc / ocamllex más de TreeTop pesar de su aspecto muy sexy.) Esto significa que necesita para convertir de forma recursiva izquierda a derecha recursividad. Ya que, sin duda, el propietario del Dragón libro (¿verdad?), I' ll usted dirige a las secciones 4.3.3, 4.3.4, 4.4.1 y que cubren el tema. Como es típico, es difícil de entender, pero analizadores no consiguió su reputación para nada. También hay un buen izquierda tutorial eliminación recursividad que los chicos ANTLR que se presente en el sujeto. Es un poco antlr / ANTLRworks específica, pero es un poco más fácil de entender que lo que se encuentra en el libro del dragón. Esta es una de esas cosas que simplemente no tiene que realizar un montón de sentido para alguien que no lo ha hecho al menos un par de veces antes.
Además, pequeño comentario, si se va a utilizar Cima del árbol, recomiendo hacer esto en su lugar:
def ws
[\t ]*
end
No es probable que alguna vez tiene que coincidir con un único carácter de espacio en blanco, además de casi todas las reglas de gramática se va a necesitar, así que tiene sentido para nombrar algo muy corto. Por cierto, hay son ventajas a un paso léxico separada. Este es uno de ellos.
Otros consejos
Parece que alguien se me adelantó:
A pesar de que noto que utilizan expresiones regulares y una eval () para analizar el archivo de entrada en lugar de un programa de análisis.
Edit: Ahora utilizan de TreeTop! Es como si alguien hizo todo el trabajo duro para mí.