Remove (path) usage from the CSS parser
This updates the CSS parser to make it compatible with the XPath AST
changes introduced in commit 365a9e9fa9
.
This also, finally, means I can get rid of some of the hacks that were
used for "+ foo" selectors and building (path) nodes.
This commit is contained in:
parent
365a9e9fa9
commit
083d048e63
|
@ -27,73 +27,79 @@ css
|
||||||
;
|
;
|
||||||
|
|
||||||
selectors
|
selectors
|
||||||
= path selectors_follow*
|
= selector selectors_follow*
|
||||||
{
|
{
|
||||||
path = val[0]
|
node = val[0]
|
||||||
|
|
||||||
val[1].each do |chunk|
|
val[1].each do |chunk|
|
||||||
path = s(:pipe, path, chunk)
|
node = s(:pipe, node, chunk)
|
||||||
end
|
end
|
||||||
|
|
||||||
path
|
node
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
selectors_follow
|
selectors_follow
|
||||||
= T_COMMA path { val[1] }
|
= T_COMMA selector { val[1] }
|
||||||
;
|
|
||||||
|
|
||||||
path
|
|
||||||
= selector path_follow*
|
|
||||||
{
|
|
||||||
# Single selector
|
|
||||||
if val[1].empty?
|
|
||||||
ret = val[0]
|
|
||||||
|
|
||||||
if ret.is_a?(Array)
|
|
||||||
ret = s(:path, *ret)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Multiple selectors
|
|
||||||
else
|
|
||||||
steps = [val[0]]
|
|
||||||
|
|
||||||
val[1].each do |step|
|
|
||||||
# "+ foo" is broken up into two steps.
|
|
||||||
if step.is_a?(Array)
|
|
||||||
# Using Array#+ or Array#| would require allocating an extra Array
|
|
||||||
step.each { |sub| steps << sub }
|
|
||||||
else
|
|
||||||
steps << step
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
ret = s(:path, *steps)
|
|
||||||
end
|
|
||||||
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
path_follow
|
|
||||||
= T_SPACE selector { val[1] }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
selector
|
selector
|
||||||
= descendant_or_self predicates?
|
= axis_or_descendant_or_self predicates? selector_follow?
|
||||||
{
|
{
|
||||||
val[1] ? s(:predicate, val[0], val[1]) : val[0]
|
node = val[0]
|
||||||
|
pred = val[1]
|
||||||
|
more = val[2]
|
||||||
|
|
||||||
|
if pred
|
||||||
|
node = s(:predicate, node, pred)
|
||||||
|
end
|
||||||
|
|
||||||
|
if more
|
||||||
|
node = node.updated(nil, node.children + [more])
|
||||||
|
end
|
||||||
|
|
||||||
|
node
|
||||||
}
|
}
|
||||||
| axis predicates?
|
| predicates selector_follow?
|
||||||
{
|
{
|
||||||
val[1] ? s(:predicate, val[0], val[1]) : val[0]
|
node = s(:axis, 'descendant', on_test(nil, '*'))
|
||||||
|
preds = val[0]
|
||||||
|
more = val[1]
|
||||||
|
|
||||||
|
if more
|
||||||
|
s(:predicate, node, preds, more)
|
||||||
|
else
|
||||||
|
s(:predicate, node, preds)
|
||||||
|
end
|
||||||
}
|
}
|
||||||
| predicates
|
# + foo
|
||||||
|
#
|
||||||
|
# This branch is not part of the "axis" rule because we need more fine grained
|
||||||
|
# control over what to do with any selec
|
||||||
|
| T_PLUS axis_selector selector_follow?
|
||||||
{
|
{
|
||||||
s(:predicate, s(:axis, 'descendant', on_test(nil, '*')), val[0])
|
selector = val[1]
|
||||||
|
more = val[2]
|
||||||
|
|
||||||
|
if more
|
||||||
|
child = s(:axis, 'self', selector, more)
|
||||||
|
else
|
||||||
|
child = s(:axis, 'self', selector)
|
||||||
|
end
|
||||||
|
|
||||||
|
s(
|
||||||
|
:predicate,
|
||||||
|
s(:axis, 'following-sibling', on_test(nil, '*')),
|
||||||
|
s(:int, 1),
|
||||||
|
child
|
||||||
|
)
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
selector_follow
|
||||||
|
= T_SPACE selector { val[1] }
|
||||||
|
;
|
||||||
|
|
||||||
descendant_or_self
|
descendant_or_self
|
||||||
= node_test { s(:axis, 'descendant', val[0]) }
|
= node_test { s(:axis, 'descendant', val[0]) }
|
||||||
;
|
;
|
||||||
|
@ -110,19 +116,11 @@ axis
|
||||||
{
|
{
|
||||||
s(:axis, 'following-sibling', val[1])
|
s(:axis, 'following-sibling', val[1])
|
||||||
}
|
}
|
||||||
|
;
|
||||||
|
|
||||||
# + foo
|
axis_or_descendant_or_self
|
||||||
| T_PLUS axis_selector
|
= descendant_or_self
|
||||||
{
|
| axis
|
||||||
[
|
|
||||||
s(
|
|
||||||
:predicate,
|
|
||||||
s(:axis, 'following-sibling', on_test(nil, '*')),
|
|
||||||
s(:int, 1)
|
|
||||||
),
|
|
||||||
s(:axis, 'self', val[1])
|
|
||||||
]
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
axis_selector
|
axis_selector
|
||||||
|
|
Loading…
Reference in New Issue