Basic CSS parser boilerplate.
This currently only parses single node tests (e.g. just "foo").
This commit is contained in:
parent
4eea6d8359
commit
b9a1f914bd
|
@ -7,6 +7,7 @@ lib/oga/xml/parser.rb
|
||||||
lib/oga/xpath/lexer.rb
|
lib/oga/xpath/lexer.rb
|
||||||
lib/oga/xpath/parser.rb
|
lib/oga/xpath/parser.rb
|
||||||
lib/oga/css/lexer.rb
|
lib/oga/css/lexer.rb
|
||||||
|
lib/oga/css/parser.rb
|
||||||
|
|
||||||
lib/liboga.*
|
lib/liboga.*
|
||||||
|
|
||||||
|
|
|
@ -49,3 +49,4 @@ require_relative 'oga/xpath/parser'
|
||||||
require_relative 'oga/xpath/evaluator'
|
require_relative 'oga/xpath/evaluator'
|
||||||
|
|
||||||
require_relative 'oga/css/lexer'
|
require_relative 'oga/css/lexer'
|
||||||
|
require_relative 'oga/css/parser'
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
##
|
||||||
|
# AST parser for CSS expressions.
|
||||||
|
#
|
||||||
|
class Oga::CSS::Parser
|
||||||
|
|
||||||
|
options no_result_var
|
||||||
|
|
||||||
|
rule
|
||||||
|
css
|
||||||
|
: selectors { val[0] }
|
||||||
|
| /* none */ { nil }
|
||||||
|
;
|
||||||
|
|
||||||
|
selectors
|
||||||
|
: selectors selector { val[0] << val[1] }
|
||||||
|
| selector { val[0] }
|
||||||
|
;
|
||||||
|
|
||||||
|
selector
|
||||||
|
: node_test
|
||||||
|
;
|
||||||
|
|
||||||
|
node_test
|
||||||
|
: node_name { s(:test, *val[0]) }
|
||||||
|
;
|
||||||
|
|
||||||
|
node_name
|
||||||
|
# foo
|
||||||
|
: T_IDENT { [nil, val[0]] }
|
||||||
|
|
||||||
|
# ns|foo
|
||||||
|
| T_IDENT T_PIPE T_IDENT { [val[0], val[2]] }
|
||||||
|
|
||||||
|
# |foo
|
||||||
|
| T_PIPE T_IDENT { [nil, val[1]] }
|
||||||
|
;
|
||||||
|
end
|
||||||
|
|
||||||
|
---- inner
|
||||||
|
##
|
||||||
|
# @param [String] data The input to parse.
|
||||||
|
#
|
||||||
|
def initialize(data)
|
||||||
|
@lexer = Lexer.new(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# @param [Symbol] type
|
||||||
|
# @param [Array] children
|
||||||
|
# @return [AST::Node]
|
||||||
|
#
|
||||||
|
def s(type, *children)
|
||||||
|
return AST::Node.new(type, children)
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Yields the next token from the lexer.
|
||||||
|
#
|
||||||
|
# @yieldparam [Array]
|
||||||
|
#
|
||||||
|
def yield_next_token
|
||||||
|
@lexer.advance do |*args|
|
||||||
|
yield args
|
||||||
|
end
|
||||||
|
|
||||||
|
yield [false, false]
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Parses the input and returns the corresponding AST.
|
||||||
|
#
|
||||||
|
# @example
|
||||||
|
# parser = Oga::CSS::Parser.new('foo.bar')
|
||||||
|
# ast = parser.parse
|
||||||
|
#
|
||||||
|
# @return [AST::Node]
|
||||||
|
#
|
||||||
|
def parse
|
||||||
|
ast = yyparse(self, :yield_next_token)
|
||||||
|
|
||||||
|
return ast
|
||||||
|
end
|
||||||
|
|
||||||
|
# vim: set ft=racc:
|
|
@ -3,4 +3,8 @@ rule '.rb' => '.y' do |task|
|
||||||
end
|
end
|
||||||
|
|
||||||
desc 'Generates the parser'
|
desc 'Generates the parser'
|
||||||
task :parser => ['lib/oga/xml/parser.rb', 'lib/oga/xpath/parser.rb']
|
task :parser => [
|
||||||
|
'lib/oga/xml/parser.rb',
|
||||||
|
'lib/oga/xpath/parser.rb',
|
||||||
|
'lib/oga/css/parser.rb'
|
||||||
|
]
|
||||||
|
|
Loading…
Reference in New Issue