문제
저는 Treetop을 처음 사용하고 CSS/HSS 파서를 작성하려고 합니다.HSS는 중첩된 스타일, 변수 및 일종의 믹스인 기능을 통해 CSS의 기본 기능을 강화합니다.
나는 거의 비슷합니다. 파서는 CSS를 처리할 수 있지만 스타일을 구현하는 데 있어서는 실패합니다. 이내에 스타일.예:
#rule #one {
#two {
color: red;
}
color: blue;
}
나는 공백을 처리하는 것과 그렇지 않은 것, 두 장의 사진을 찍었습니다.나도 일을 할 수가 없어요.나무 꼭대기 문서는 약간 드물고 근본적인 것을 놓치고 있는 것 같은 느낌이 듭니다.누군가가 나를 바로 잡을 수 있기를 바랍니다.
ㅏ:
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
해결책
나는 당신이 겪고 있다고 가정합니다 왼쪽 재귀 문제?그렇다면 TreeTop이 재귀 하강 파서, 따라서 문법에서 실제로 왼쪽 재귀를 사용할 수 없습니다.(매우 섹시한 외관에도 불구하고 내가 여전히 TreeTop보다 ocamlyacc/ocamllex를 선호하는 주된 이유 중 하나입니다.) 이는 왼쪽 재귀 형식에서 오른쪽 재귀 형식으로 변환해야 함을 의미합니다.당신은 의심할 여지없이 그 소유권을 갖고 있기 때문에 드래곤북 (맞죠?) 문제를 다루는 섹션 4.3.3, 4.3.4, 4.4.1로 안내해 드리겠습니다.일반적으로 이해하기 어렵지만 파서가 헛되이 명성을 얻은 것은 아닙니다.좋은 것도 있어요 왼쪽 재귀 제거 튜토리얼 ANTLR 사람들이 주제에 대해 언급했습니다.ANTLR/ANTLRworks에 따라 다소 다르지만 Dragon Book에 있는 것보다 이해하기가 약간 더 쉽습니다.이것은 이전에 적어도 몇 번 해본 적이 없는 사람에게는 전혀 이해가 되지 않는 것 중 하나입니다.
또한 사소한 의견입니다. TreeTop을 사용하려는 경우 대신 다음을 수행하는 것이 좋습니다.
def ws
[\t ]*
end
단일 공백 문자와 일치할 필요는 없으며 거의 모든 문법 규칙에서 이를 필요로 하므로 매우 짧은 이름으로 지정하는 것이 합리적입니다.그런데 거기에는 ~이다 별도의 렉싱 단계의 이점.이것은 그들 중 하나입니다.
다른 팁
누군가가 나를 때린 것 같습니다.
비록 파서가 아닌 정규식과 eval()을 사용하여 입력 파일을 구문 분석한다는 것을 알았습니다.
편집하다:이제 그들은 TreeTop을 사용합니다!누군가가 나를 위해 모든 힘든 일을 한 것 같습니다.