我是新来的树顶,并试图写一个CSS / HSS解析器。 HSS增强与嵌套样式,变量和一种混入功能CSS的基本功能。

我很接近 - 解析器可以处理CSS - 但我倒下,当涉及到内实现风格的 的风格。 e.g:

#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

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在树顶尽管它很性感亮相)。这意味着你需要从左递归形式到右递归转换。既然你无疑拥有龙书(右?),我LL引导您到部分4.3.3,4.3.4,4.4.1和覆盖的问题。作为典型,这是很难理解的,但解析器没有得到他们的任何声誉。还有一个不错的左递归消除教程的是,ANTLR家伙竖起的主题。这有点ANTLR / ANTLRworks具体,但它是稍微容易比什么在龙书发现理解。这是说只是没有永远做一大堆的道理任何人那些事谁没有做之前至少几次之一。

此外,未成年人评论,如果你打算使用树顶,我建议不要做这样的:

def ws
  [\t ]*
end

你不可能永远需要匹配单个空格字符,再加上几乎每一个语法规则的人都需要它,所以它是有意义的命名它的东西很短。顺便提及,存在的以单独的步骤词法优点。这是其中的一种。

其他提示

看起来像有人打我给它:

http://lesscss.org/

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

编辑:现在,他们使用的树顶!这就像一个人做所有的辛勤工作为我。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top