Pergunta

Eu sou novo para Treetop e tentando escrever um analisador CSS / HSS. HSS aumenta a funcionalidade básica do CSS com estilos aninhados, variáveis ??e um tipo de funcionalidade mixin.

Estou bastante perto - o analisador pode lidar com CSS - mas eu caio quando se trata de implementar um estilo em um estilo. por exemplo:

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

Eu tomei dois tiros nele, um que lida com espaços em branco e um que não o faz. Eu não consigo obter qualquer ao trabalho. A documentação copa de árvore é um pouco escassa e eu realmente sinto que estou perdendo algo fundamental. Esperemos que alguém pode me definir reta.

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 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
Foi útil?

Solução

Eu suponho que você está correndo em problemas recursão esquerda ? Se assim for, tenha em mente que TreeTop produz recursiva descida analisadores , e como tal, você pode' t realmente usar recursão esquerda em sua gramática. (Uma das principais razões que eu ainda preferem ocamlyacc / ocamllex sobre TreeTop apesar de sua aparência muito sexy.) Isso significa que você precisa para converter de forma recursiva esquerda para recursão direita. Desde você possui, sem dúvida, o Dragão Livro (certo?), I' vai direcioná-lo para seções 4.3.3, 4.3.4 e 4.4.1, que abrangem a questão. Como é típico, é difícil de entender, mas analisadores não obter a sua reputação de nada. Há também uma boa eliminação recursão esquerda tutorial que os caras ANTLR colocar-se sobre o assunto. É um pouco ANTLR / ANTLRworks específico, mas é um pouco mais fácil de entender do que o que está contido no Livro do dragão. Esta é uma daquelas coisas que simplesmente não sempre fazer um monte de sentido para alguém que não tenha feito isso, pelo menos algumas vezes antes.

Além disso, menor comentário, se você estiver indo para usar TreeTop, eu recomendo fazer isso em vez disso:

def ws
  [\t ]*
end

Você não é provável que nunca precisa corresponder a um único espaço em branco, além de quase todas as regras da gramática vai precisar dele, por isso faz sentido para nomeá-la algo muito curto. Aliás, há são vantagens para um passo lexing separado. Este é um deles.

Outras dicas

Parece que alguém chegou antes de mim:

http://lesscss.org/

Apesar de eu perceber que eles usam expressões regulares e um eval () para analisar o arquivo de entrada, em vez de um analisador.

Edit: Agora eles usam TreeTop! É como se alguém fez todo o trabalho duro para mim.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top