First pass of rewriting the CSS parser.
The new parser uses way less confusing rule names, is a bit more strict and in general much less of a pain to deal with.
This commit is contained in:
parent
e3de65a258
commit
851e7d6d0b
|
@ -13,67 +13,76 @@ options no_result_var
|
||||||
prechigh
|
prechigh
|
||||||
left T_COLON T_HASH T_DOT
|
left T_COLON T_HASH T_DOT
|
||||||
left T_CHILD T_FOLLOWING T_FOLLOWING_DIRECT
|
left T_CHILD T_FOLLOWING T_FOLLOWING_DIRECT
|
||||||
left T_DOT T_HASH
|
|
||||||
preclow
|
preclow
|
||||||
|
|
||||||
rule
|
rule
|
||||||
css
|
css
|
||||||
: expression { val[0] }
|
: selectors { val[0] }
|
||||||
| /* none */ { nil }
|
| /* none */ { nil }
|
||||||
;
|
;
|
||||||
|
|
||||||
expression
|
selectors
|
||||||
: steps { s(:path, *val[0]) }
|
: selector
|
||||||
| step
|
| selectors_ { s(:path, *val[0]) }
|
||||||
;
|
;
|
||||||
|
|
||||||
steps
|
selectors_
|
||||||
: step T_SPACE step { [val[0], val[2]] }
|
: selectors_ T_SPACE selector { val[0] << val[2] }
|
||||||
| step T_SPACE steps { [val[0], *val[2]] }
|
| selector T_SPACE selector { [val[0], val[2]] }
|
||||||
;
|
;
|
||||||
|
|
||||||
step
|
selector
|
||||||
: step_test { s(:axis, 'descendant-or-self', val[0]) }
|
: descendant_or_self
|
||||||
|
| axis
|
||||||
;
|
;
|
||||||
|
|
||||||
step_test
|
descendant_or_self
|
||||||
: element_test { val[0] }
|
: node_test { s(:axis, 'descendant-or-self', val[0]) }
|
||||||
| step_predicates { s(:test, nil, '*', val[0]) }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
step_predicates
|
axis
|
||||||
: step_predicate
|
: T_CHILD axis_selector { s(:axis, 'child', val[1]) }
|
||||||
| step_predicates step_predicate { s(:and, val[0], val[1]) }
|
| T_FOLLOWING axis_selector { s(:axis, 'following', val[1]) }
|
||||||
|
| T_FOLLOWING_DIRECT axis_selector { s(:axis, 'following-direct', val[1]) }
|
||||||
;
|
;
|
||||||
|
|
||||||
step_predicate
|
axis_selector
|
||||||
: class
|
| node_test
|
||||||
| id
|
| axis
|
||||||
#| axis
|
|
||||||
#| pseudo_class
|
|
||||||
;
|
;
|
||||||
|
|
||||||
element_test
|
node_test
|
||||||
# foo
|
# foo
|
||||||
: node_name { s(:test, *val[0]) }
|
: node_name
|
||||||
|
{
|
||||||
|
s(:test, *val[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
# .foo, :root, etc
|
||||||
|
| predicates
|
||||||
|
{
|
||||||
|
s(:test, nil, '*', val[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
# foo.bar
|
||||||
|
| node_name predicates
|
||||||
|
{
|
||||||
|
s(:test, *val[0], val[1])
|
||||||
|
}
|
||||||
|
|
||||||
# foo[bar]
|
# foo[bar]
|
||||||
| node_name predicate { s(:test, *val[0], val[1]) }
|
| node_name attribute_predicate
|
||||||
|
{
|
||||||
|
s(:test, *val[0], val[1])
|
||||||
|
}
|
||||||
|
|
||||||
# foo:root
|
# foo[bar].baz
|
||||||
| node_name step_predicates { s(:test, *val[0], val[1]) }
|
| node_name attribute_predicate predicates
|
||||||
|
|
||||||
# foo[bar]:root
|
|
||||||
| node_name predicate step_predicates
|
|
||||||
{
|
{
|
||||||
s(:test, *val[0], s(:and, val[1], val[2]))
|
s(:test, *val[0], s(:and, val[1], val[2]))
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
attribute_test
|
|
||||||
: node_name { s(:axis, 'attribute', s(:test, *val[0])) }
|
|
||||||
;
|
|
||||||
|
|
||||||
node_name
|
node_name
|
||||||
# foo
|
# foo
|
||||||
: T_IDENT { [nil, val[0]] }
|
: T_IDENT { [nil, val[0]] }
|
||||||
|
@ -85,15 +94,34 @@ rule
|
||||||
| T_PIPE T_IDENT { [nil, val[1]] }
|
| T_PIPE T_IDENT { [nil, val[1]] }
|
||||||
;
|
;
|
||||||
|
|
||||||
predicate
|
predicates
|
||||||
: T_LBRACK predicate_members T_RBRACK { val[1] }
|
: predicates predicate { s(:and, val[0], val[1]) }
|
||||||
|
| predicate
|
||||||
;
|
;
|
||||||
|
|
||||||
predicate_members
|
predicate
|
||||||
: attribute_test
|
: class
|
||||||
|
| id
|
||||||
|
| pseudo_class
|
||||||
|
;
|
||||||
|
|
||||||
|
attribute_predicate
|
||||||
|
: T_LBRACK attribute_predicate_members T_RBRACK { val[1] }
|
||||||
|
;
|
||||||
|
|
||||||
|
attribute_predicate_members
|
||||||
|
: attribute
|
||||||
| operator
|
| operator
|
||||||
;
|
;
|
||||||
|
|
||||||
|
attribute
|
||||||
|
: node_name { s(:axis, 'attribute', s(:test, *val[0])) }
|
||||||
|
;
|
||||||
|
|
||||||
|
operator
|
||||||
|
: attribute T_EQ string { s(:eq, val[0], val[2]) }
|
||||||
|
;
|
||||||
|
|
||||||
class
|
class
|
||||||
: T_DOT T_IDENT
|
: T_DOT T_IDENT
|
||||||
{
|
{
|
||||||
|
@ -119,78 +147,29 @@ rule
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
operator
|
pseudo_class
|
||||||
: op_members T_EQ op_members { s(:eq, val[0], val[2]) }
|
# :root
|
||||||
| op_members T_SPACE_IN op_members { s(:space_in, val[0], val[2]) }
|
: pseudo_name { s(:pseudo, nil, val[0]) }
|
||||||
| op_members T_STARTS_WITH op_members { s(:starts_with, val[0], val[2]) }
|
|
||||||
| op_members T_ENDS_WITH op_members { s(:ends_with, val[0], val[2]) }
|
# :nth-child(2)
|
||||||
| op_members T_IN op_members { s(:in, val[0], val[2]) }
|
| pseudo_name pseudo_args { s(:pseudo, nil, val[0], val[1]) }
|
||||||
| op_members T_HYPHEN_IN op_members { s(:hyphen_in, val[0],val[2]) }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
op_members
|
pseudo_name
|
||||||
: attribute_test
|
: T_COLON T_IDENT { val[1] }
|
||||||
| string
|
;
|
||||||
|
|
||||||
|
pseudo_args
|
||||||
|
: T_LPAREN pseudo_arg T_RPAREN { val[1] }
|
||||||
|
;
|
||||||
|
|
||||||
|
pseudo_arg
|
||||||
|
: integer
|
||||||
|
#| odd
|
||||||
|
#| even
|
||||||
|
#| nth
|
||||||
|
| selector
|
||||||
;
|
;
|
||||||
#
|
|
||||||
# axis
|
|
||||||
# # x > y
|
|
||||||
# : step_member T_CHILD step_member { s(:child, val[0], val[2]) }
|
|
||||||
#
|
|
||||||
# # x + y
|
|
||||||
# | step_member T_FOLLOWING step_member { s(:following, val[0], val[2]) }
|
|
||||||
#
|
|
||||||
# # x ~ y
|
|
||||||
# | step_member T_FOLLOWING_DIRECT step_member
|
|
||||||
# {
|
|
||||||
# s(:following_direct, val[0], val[2])
|
|
||||||
# }
|
|
||||||
# ;
|
|
||||||
#
|
|
||||||
# pseudo_class
|
|
||||||
# # :root
|
|
||||||
# : pseudo_name { s(:pseudo, nil, val[0]) }
|
|
||||||
#
|
|
||||||
# # x:root
|
|
||||||
# | step_member pseudo_name { s(:pseudo, val[0], val[1]) }
|
|
||||||
#
|
|
||||||
# # :nth-child(2)
|
|
||||||
# | pseudo_name pseudo_args { s(:pseudo, nil, val[0], val[1]) }
|
|
||||||
#
|
|
||||||
# # x:nth-child(2)
|
|
||||||
# | step_member pseudo_name pseudo_args { s(:pseudo, val[0], val[1], val[2]) }
|
|
||||||
# ;
|
|
||||||
#
|
|
||||||
# pseudo_name
|
|
||||||
# : T_COLON T_IDENT { val[1] }
|
|
||||||
# ;
|
|
||||||
#
|
|
||||||
# pseudo_args
|
|
||||||
# : T_LPAREN pseudo_arg T_RPAREN { val[1] }
|
|
||||||
# ;
|
|
||||||
#
|
|
||||||
# pseudo_arg
|
|
||||||
# : integer
|
|
||||||
# | odd
|
|
||||||
# | even
|
|
||||||
# | nth
|
|
||||||
# | node_test
|
|
||||||
# ;
|
|
||||||
#
|
|
||||||
# odd
|
|
||||||
# : T_ODD { s(:odd) }
|
|
||||||
# ;
|
|
||||||
#
|
|
||||||
# even
|
|
||||||
# : T_EVEN { s(:even) }
|
|
||||||
# ;
|
|
||||||
#
|
|
||||||
# nth
|
|
||||||
# : T_NTH { s(:nth) }
|
|
||||||
# | T_MINUS T_NTH { s(:nth) }
|
|
||||||
# | integer T_NTH { s(:nth, val[0]) }
|
|
||||||
# | integer T_NTH integer { s(:nth, val[0], val[2]) }
|
|
||||||
# ;
|
|
||||||
|
|
||||||
string
|
string
|
||||||
: T_STRING { s(:string, val[0]) }
|
: T_STRING { s(:string, val[0]) }
|
||||||
|
|
Loading…
Reference in New Issue