Basic parser setup without tests.
Who needs tests anyway!
This commit is contained in:
parent
c4e0406ed9
commit
e764ba640a
5
Rakefile
5
Rakefile
|
@ -8,10 +8,9 @@ GEMSPEC = Gem::Specification.load('oga.gemspec')
|
||||||
LEXER_INPUT = 'lib/oga/lexer.rl'
|
LEXER_INPUT = 'lib/oga/lexer.rl'
|
||||||
LEXER_OUTPUT = 'lib/oga/lexer.rb'
|
LEXER_OUTPUT = 'lib/oga/lexer.rb'
|
||||||
|
|
||||||
#PARSER_INPUT = 'lib/oga/parser.y'
|
HTML_PARSER = 'lib/oga/parser/html.rb'
|
||||||
#PARSER_OUTPUT = 'lib/oga/parser.rb'
|
|
||||||
|
|
||||||
GENERATED_FILES = ['coverage', 'yardoc', LEXER_OUTPUT]
|
GENERATED_FILES = ['coverage', 'yardoc', LEXER_OUTPUT, HTML_PARSER]
|
||||||
|
|
||||||
GENERATED_FILES.each do |file|
|
GENERATED_FILES.each do |file|
|
||||||
CLEAN << file if File.exist?(file)
|
CLEAN << file if File.exist?(file)
|
||||||
|
|
|
@ -2,3 +2,4 @@ require 'ast'
|
||||||
|
|
||||||
require_relative 'oga/ast/node'
|
require_relative 'oga/ast/node'
|
||||||
require_relative 'oga/lexer'
|
require_relative 'oga/lexer'
|
||||||
|
require_relative 'oga/parser/html'
|
||||||
|
|
|
@ -3,7 +3,7 @@ module Oga
|
||||||
##
|
##
|
||||||
#
|
#
|
||||||
class Node < ::AST::Node
|
class Node < ::AST::Node
|
||||||
|
attr_reader :line, :column
|
||||||
end # Node
|
end # Node
|
||||||
end # AST
|
end # AST
|
||||||
end # Oga
|
end # Oga
|
||||||
|
|
|
@ -0,0 +1,223 @@
|
||||||
|
#
|
||||||
|
# DO NOT MODIFY!!!!
|
||||||
|
# This file is automatically generated by Racc 1.4.11
|
||||||
|
# from Racc grammer file "".
|
||||||
|
#
|
||||||
|
|
||||||
|
require 'racc/parser.rb'
|
||||||
|
module Oga
|
||||||
|
module Parser
|
||||||
|
class HTML < Racc::Parser
|
||||||
|
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
@lexer = Lexer.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def reset
|
||||||
|
@lines = []
|
||||||
|
@line = 1
|
||||||
|
@column = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
def s(type, *children)
|
||||||
|
return AST::Node.new(
|
||||||
|
type,
|
||||||
|
children.flatten,
|
||||||
|
:line => @line,
|
||||||
|
:column => @column
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def next_token
|
||||||
|
type, value, line, column = @tokens.shift
|
||||||
|
|
||||||
|
@line = line if line
|
||||||
|
@column = column if column
|
||||||
|
|
||||||
|
return type ? [type, value] : [false, false]
|
||||||
|
end
|
||||||
|
|
||||||
|
def on_error(type, value, stack)
|
||||||
|
name = token_to_str(type)
|
||||||
|
line_str = @lines[@line - 1]
|
||||||
|
indicator = '~' * (@column - 1) + '^'
|
||||||
|
|
||||||
|
raise Racc::ParseError, <<-EOF.strip
|
||||||
|
Failed to parse the supplied input.
|
||||||
|
|
||||||
|
Reason: unexpected #{name} with value #{value.inspect}
|
||||||
|
Location: line #{@line}, column #{@column}
|
||||||
|
|
||||||
|
Offending code:
|
||||||
|
|
||||||
|
#{line_str}
|
||||||
|
#{indicator}
|
||||||
|
|
||||||
|
Current stack:
|
||||||
|
|
||||||
|
#{stack.inspect}
|
||||||
|
EOF
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse(string)
|
||||||
|
@lines = string.lines
|
||||||
|
@tokens = @lexer.lex(string)
|
||||||
|
ast = do_parse
|
||||||
|
|
||||||
|
reset
|
||||||
|
|
||||||
|
return ast
|
||||||
|
end
|
||||||
|
|
||||||
|
# vim: set ft=racc:
|
||||||
|
##### State transition tables begin ###
|
||||||
|
|
||||||
|
racc_action_table = [
|
||||||
|
5, 7, 5, 9, 11, 12, 13, 14, 15, 16,
|
||||||
|
17 ]
|
||||||
|
|
||||||
|
racc_action_check = [
|
||||||
|
0, 1, 2, 5, 6, 7, 9, 10, 14, 15,
|
||||||
|
16 ]
|
||||||
|
|
||||||
|
racc_action_pointer = [
|
||||||
|
-4, 1, -2, nil, nil, -12, -11, 5, nil, 1,
|
||||||
|
3, nil, nil, nil, 2, -6, 5, nil ]
|
||||||
|
|
||||||
|
racc_action_default = [
|
||||||
|
-2, -9, -1, -4, -5, -9, -9, -9, -3, -9,
|
||||||
|
-9, -8, 18, -6, -9, -9, -9, -7 ]
|
||||||
|
|
||||||
|
racc_goto_table = [
|
||||||
|
3, 1, 8, 2, 10 ]
|
||||||
|
|
||||||
|
racc_goto_check = [
|
||||||
|
3, 1, 3, 2, 6 ]
|
||||||
|
|
||||||
|
racc_goto_pointer = [
|
||||||
|
nil, 1, 3, 0, nil, nil, -2 ]
|
||||||
|
|
||||||
|
racc_goto_default = [
|
||||||
|
nil, nil, nil, nil, 4, 6, nil ]
|
||||||
|
|
||||||
|
racc_reduce_table = [
|
||||||
|
0, 0, :racc_error,
|
||||||
|
1, 17, :_reduce_1,
|
||||||
|
0, 17, :_reduce_2,
|
||||||
|
2, 18, :_reduce_3,
|
||||||
|
1, 18, :_reduce_4,
|
||||||
|
1, 19, :_reduce_none,
|
||||||
|
3, 21, :_reduce_6,
|
||||||
|
6, 20, :_reduce_7,
|
||||||
|
1, 22, :_reduce_none ]
|
||||||
|
|
||||||
|
racc_reduce_n = 9
|
||||||
|
|
||||||
|
racc_shift_n = 18
|
||||||
|
|
||||||
|
racc_token_table = {
|
||||||
|
false => 0,
|
||||||
|
:error => 1,
|
||||||
|
:T_SPACE => 2,
|
||||||
|
:T_NEWLINE => 3,
|
||||||
|
:T_SMALLER => 4,
|
||||||
|
:T_GREATER => 5,
|
||||||
|
:T_SLASH => 6,
|
||||||
|
:T_DQUOTE => 7,
|
||||||
|
:T_SQUOTE => 8,
|
||||||
|
:T_DASH => 9,
|
||||||
|
:T_RBRACKET => 10,
|
||||||
|
:T_LBRACKET => 11,
|
||||||
|
:T_COLON => 12,
|
||||||
|
:T_BANG => 13,
|
||||||
|
:T_EQUALS => 14,
|
||||||
|
:T_TEXT => 15 }
|
||||||
|
|
||||||
|
racc_nt_base = 16
|
||||||
|
|
||||||
|
racc_use_result_var = false
|
||||||
|
|
||||||
|
Racc_arg = [
|
||||||
|
racc_action_table,
|
||||||
|
racc_action_check,
|
||||||
|
racc_action_default,
|
||||||
|
racc_action_pointer,
|
||||||
|
racc_goto_table,
|
||||||
|
racc_goto_check,
|
||||||
|
racc_goto_default,
|
||||||
|
racc_goto_pointer,
|
||||||
|
racc_nt_base,
|
||||||
|
racc_reduce_table,
|
||||||
|
racc_token_table,
|
||||||
|
racc_shift_n,
|
||||||
|
racc_reduce_n,
|
||||||
|
racc_use_result_var ]
|
||||||
|
|
||||||
|
Racc_token_to_s_table = [
|
||||||
|
"$end",
|
||||||
|
"error",
|
||||||
|
"T_SPACE",
|
||||||
|
"T_NEWLINE",
|
||||||
|
"T_SMALLER",
|
||||||
|
"T_GREATER",
|
||||||
|
"T_SLASH",
|
||||||
|
"T_DQUOTE",
|
||||||
|
"T_SQUOTE",
|
||||||
|
"T_DASH",
|
||||||
|
"T_RBRACKET",
|
||||||
|
"T_LBRACKET",
|
||||||
|
"T_COLON",
|
||||||
|
"T_BANG",
|
||||||
|
"T_EQUALS",
|
||||||
|
"T_TEXT",
|
||||||
|
"$start",
|
||||||
|
"document",
|
||||||
|
"expressions",
|
||||||
|
"expression",
|
||||||
|
"tag",
|
||||||
|
"tag_start",
|
||||||
|
"tag_body" ]
|
||||||
|
|
||||||
|
Racc_debug_parser = false
|
||||||
|
|
||||||
|
##### State transition tables end #####
|
||||||
|
|
||||||
|
# reduce 0 omitted
|
||||||
|
|
||||||
|
def _reduce_1(val, _values)
|
||||||
|
s(:document, val[0])
|
||||||
|
end
|
||||||
|
|
||||||
|
def _reduce_2(val, _values)
|
||||||
|
s(:document)
|
||||||
|
end
|
||||||
|
|
||||||
|
def _reduce_3(val, _values)
|
||||||
|
val.compact
|
||||||
|
end
|
||||||
|
|
||||||
|
def _reduce_4(val, _values)
|
||||||
|
val[0]
|
||||||
|
end
|
||||||
|
|
||||||
|
# reduce 5 omitted
|
||||||
|
|
||||||
|
def _reduce_6(val, _values)
|
||||||
|
val[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
def _reduce_7(val, _values)
|
||||||
|
s(:element, val[0], val[1])
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
# reduce 8 omitted
|
||||||
|
|
||||||
|
def _reduce_none(val, _values)
|
||||||
|
val[0]
|
||||||
|
end
|
||||||
|
|
||||||
|
end # class HTML
|
||||||
|
end # module Parser
|
||||||
|
end # module Oga
|
|
@ -0,0 +1,104 @@
|
||||||
|
class Oga::Parser::HTML
|
||||||
|
|
||||||
|
token T_SPACE T_NEWLINE T_SMALLER T_GREATER T_SLASH
|
||||||
|
token T_DQUOTE T_SQUOTE T_DASH T_RBRACKET T_LBRACKET
|
||||||
|
token T_COLON T_BANG T_EQUALS T_TEXT
|
||||||
|
|
||||||
|
options no_result_var
|
||||||
|
|
||||||
|
rule
|
||||||
|
document
|
||||||
|
: expressions { s(:document, val[0]) }
|
||||||
|
| /* none */ { s(:document) }
|
||||||
|
;
|
||||||
|
|
||||||
|
expressions
|
||||||
|
: expressions expression { val.compact }
|
||||||
|
| expression { val[0] }
|
||||||
|
;
|
||||||
|
|
||||||
|
expression
|
||||||
|
: tag
|
||||||
|
;
|
||||||
|
|
||||||
|
tag_start
|
||||||
|
# <p>
|
||||||
|
: T_SMALLER T_TEXT T_GREATER { val[1] }
|
||||||
|
;
|
||||||
|
|
||||||
|
tag
|
||||||
|
# <p>foo</p>
|
||||||
|
: tag_start tag_body T_SMALLER T_SLASH T_TEXT T_GREATER
|
||||||
|
{
|
||||||
|
s(:element, val[0], val[1])
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
tag_body
|
||||||
|
: T_TEXT
|
||||||
|
;
|
||||||
|
end
|
||||||
|
|
||||||
|
---- inner
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
@lexer = Lexer.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def reset
|
||||||
|
@lines = []
|
||||||
|
@line = 1
|
||||||
|
@column = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
def s(type, *children)
|
||||||
|
return AST::Node.new(
|
||||||
|
type,
|
||||||
|
children.flatten,
|
||||||
|
:line => @line,
|
||||||
|
:column => @column
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def next_token
|
||||||
|
type, value, line, column = @tokens.shift
|
||||||
|
|
||||||
|
@line = line if line
|
||||||
|
@column = column if column
|
||||||
|
|
||||||
|
return type ? [type, value] : [false, false]
|
||||||
|
end
|
||||||
|
|
||||||
|
def on_error(type, value, stack)
|
||||||
|
name = token_to_str(type)
|
||||||
|
line_str = @lines[@line - 1]
|
||||||
|
indicator = '~' * (@column - 1) + '^'
|
||||||
|
|
||||||
|
raise Racc::ParseError, <<-EOF.strip
|
||||||
|
Failed to parse the supplied input.
|
||||||
|
|
||||||
|
Reason: unexpected #{name} with value #{value.inspect}
|
||||||
|
Location: line #{@line}, column #{@column}
|
||||||
|
|
||||||
|
Offending code:
|
||||||
|
|
||||||
|
#{line_str}
|
||||||
|
#{indicator}
|
||||||
|
|
||||||
|
Current stack:
|
||||||
|
|
||||||
|
#{stack.inspect}
|
||||||
|
EOF
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse(string)
|
||||||
|
@lines = string.lines
|
||||||
|
@tokens = @lexer.lex(string)
|
||||||
|
ast = do_parse
|
||||||
|
|
||||||
|
reset
|
||||||
|
|
||||||
|
return ast
|
||||||
|
end
|
||||||
|
|
||||||
|
# vim: set ft=racc:
|
|
@ -1,5 +1,5 @@
|
||||||
desc 'Generates auto-generated files'
|
desc 'Generates auto-generated files'
|
||||||
task :generate => [:lexer]
|
task :generate => [:lexer, :parser]
|
||||||
|
|
||||||
desc 'Regenerates auto-generated files'
|
desc 'Regenerates auto-generated files'
|
||||||
task :regenerate => [:clean, :generate]
|
task :regenerate => [:clean, :generate]
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
=begin
|
|
||||||
rule '.rb' => '.y' do |task|
|
rule '.rb' => '.y' do |task|
|
||||||
Cliver.assert('racc', '~> 1.4')
|
Cliver.assert('racc', '~> 1.4')
|
||||||
|
|
||||||
|
@ -6,5 +5,4 @@ rule '.rb' => '.y' do |task|
|
||||||
end
|
end
|
||||||
|
|
||||||
desc 'Generates the parser'
|
desc 'Generates the parser'
|
||||||
task :parser => [PARSER_OUTPUT]
|
task :parser => [HTML_PARSER]
|
||||||
=end
|
|
||||||
|
|
Loading…
Reference in New Issue