代码之家  ›  专栏  ›  技术社区  ›  toothygoose

树顶和嵌套样式表规则中的CSS/HSS解析器

  •  5
  • toothygoose  · 技术社区  · 17 年前

    我是Treetop的新手,正在尝试编写一个CSS/HSS解析器。HSS通过嵌套样式、变量和一种混入功能增强了CSS的基本功能。

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

    我拍了两张照片,一张处理空白,一张不处理空白。我都不能很好地工作。树梢文档有点稀疏,我真的觉得我错过了一些基本的东西。希望有人能纠正我。

    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
    

    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
    
    2 回复  |  直到 17 年前
        1
  •  3
  •   Bob Aman    17 年前

    我想你会遇到 left recursion 问题?如果是这样,请记住TreeTop会产生 recursive descent parsers 因此,你不能在语法中真正使用左递归。(尽管外观非常性感,但我仍然更喜欢ocamlyacc/ocamllex而不是TreeTop的主要原因之一。)这意味着你需要从左递归形式转换为右递归形式。既然你无疑拥有 Dragon Book (对吗?),我将指导您阅读第4.3.3、4.3.4和4.4.1节,其中涵盖了这个问题。通常,这很难理解,但解析器并没有无缘无故地获得声誉。还有一个不错的 left recursion elimination tutorial ANTLR的人在这个问题上提出的。它有点ANTLR/ANTLRworks的特定性,但它比龙书中的内容更容易理解。对于那些以前至少几次没有做过的人来说,这是一件没有多大意义的事情。

    def ws
      [\t ]*
    end
    

    是

        2
  •  1
  •   toothygoose    17 年前

    看起来有人打败了我:

    http://lesscss.org/

    虽然我注意到他们使用正则表达式和eval()来解析输入文件,而不是解析器。

    编辑:现在他们使用TreeTop!就像有人为我做了所有的艰苦工作。

    推荐文章