Анализатор CSS / HSS в правилах Treetop и вложенных таблиц стилей

StackOverflow https://stackoverflow.com/questions/785714

  •  16-09-2019
  •  | 
  •  

Вопрос

Я новичок в Treetop и пытаюсь написать анализатор CSS / HSS.HSS дополняет базовую функциональность CSS вложенными стилями, переменными и своего рода смешанной функциональностью.

Я довольно близок к этому - анализатор может обрабатывать CSS - но я падаю духом, когда дело доходит до реализации стиля внутри стиль.например, g:

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

Я сделал два снимка с этого, один из которых обрабатывает пробелы, а другой - нет.Я не могу заставить ни то, ни другое приступить к работе.Документация treetop немного скудна, и я действительно чувствую, что упускаю что-то фундаментальное.Надеюсь, кто-нибудь сможет наставить меня на путь истинный.

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

Код жгута проводов:

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
Это было полезно?

Решение

Я предполагаю, что вы сталкиваетесь с левая рекурсия проблемы?Если это так, имейте в виду, что верхушка дерева производит анализаторы рекурсивного спуска, и как таковой, вы действительно не можете использовать левую рекурсию в своей грамматике.(Одна из главных причин, по которой я все еще предпочитаю ocamlyacc / ocamllex TreeTop, несмотря на его очень привлекательный внешний вид.) Это означает, что вам нужно преобразовать леворекурсивные формы в праворекурсивные.Поскольку вы, несомненно, владеете Книга Дракона (верно?), я направлю вас к разделам 4.3.3, 4.3.4 и 4.4.1, которые охватывают проблему.Как это обычно бывает, это трудно понять, но парсеры не зря заслужили свою репутацию.Там также есть приятный руководство по устранению левой рекурсии что ребята из ANTLR высказались по этому поводу.Это несколько специфично для ANTLR / ANTLRWorks, но это немного легче понять, чем то, что найдено в книге Дракона.Это одна из тех вещей, которая просто не имеет особого смысла для тех, кто не делал этого хотя бы несколько раз раньше.

Кроме того, небольшой комментарий: если вы собираетесь использовать TreeTop, я рекомендую сделать это вместо:

def ws
  [\t ]*
end

Вряд ли вам когда-либо понадобится сопоставлять один пробельный символ, плюс это понадобится почти каждому правилу грамматики, поэтому имеет смысл назвать его как-нибудь очень коротко.Кстати, там являются преимущества отдельного этапа лексикации.Это один из них.

Другие советы

Похоже, кто- то опередил меня в этом:

http://lesscss.org/

Хотя я заметил, что они используют регулярные выражения и eval() для анализа входного файла, а не синтаксический анализатор.

Редактировать:Теперь они используют TreeTop!Как будто кто-то сделал всю тяжелую работу за меня.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top