Port over most of the old XML error handling.

Some messages are a bit different due to ruby-ll's error handling, other than
that it's largely the same stuff as before.
This commit is contained in:
Yorick Peterse 2015-02-16 00:59:28 +01:00
parent 1a326fc516
commit 006ef4d51a
4 changed files with 62 additions and 4 deletions

View File

@ -222,6 +222,35 @@ string_body_follow
%inner %inner
{ {
##
# Hash mapping token types and dedicated error labels.
#
# @return [Hash]
#
TOKEN_ERROR_MAPPING = {
:T_STRING => 'string',
:T_TEXT => 'text',
:T_DOCTYPE_START => 'doctype start',
:T_DOCTYPE_END => 'doctype closing tag',
:T_DOCTYPE_TYPE => 'doctype type',
:T_DOCTYPE_NAME => 'doctype name',
:T_DOCTYPE_INLINE => 'inline doctype rules',
:T_CDATA => 'CDATA',
:T_COMMENT => 'comment',
:T_ELEM_START => 'element start',
:T_ELEM_NAME => 'element name',
:T_ELEM_NS => 'element namespace',
:T_ELEM_END => 'element closing tag',
:T_ATTR => 'attribute',
:T_ATTR_NS => 'attribute namespace',
:T_XML_DECL_START => 'XML declaration start',
:T_XML_DECL_END => 'XML declaration end',
:T_PROC_INS_START => 'processing-instruction start',
:T_PROC_INS_NAME => 'processing-instruction name',
:T_PROC_INS_END => 'processing-instruction closing tag',
-1 => 'end of input'
}
## ##
# @param [String|IO] data The input to parse. # @param [String|IO] data The input to parse.
# @param [Hash] options # @param [Hash] options
@ -258,6 +287,30 @@ string_body_follow
yield [-1, -1] yield [-1, -1]
end end
##
# @param [Fixnum] stack_type
# @param [Fixnum] stack_value
# @param [Symbol] token_type
# @param [String] token_value
#
def parser_error(stack_type, stack_value, token_type, token_value)
case id_to_type(stack_type)
when :rule
message = "Unexpected #{token_type} for rule #{stack_value}"
when :terminal
expected = id_to_terminal(stack_value)
expected = TOKEN_ERROR_MAPPING[expected] || expected
got = TOKEN_ERROR_MAPPING[token_type] || token_type
message = "Unexpected #{got}, expected #{expected} instead"
when :eof
message = 'Unexpected end of input'
end
message += " on line #{@line}"
raise LL::ParserError, message
end
## ##
# @see [LL::Driver#parse] # @see [LL::Driver#parse]
# #

View File

@ -12,8 +12,8 @@ describe Oga::XML::Parser do
EOF EOF
end end
it 'raises a Racc::ParseError' do it 'raises a LL::ParserError' do
expect { parse(@invalid_xml) }.to raise_error(Racc::ParseError) expect { parse(@invalid_xml) }.to raise_error(LL::ParserError)
end end
it 'includes the line number when using a String as input' do it 'includes the line number when using a String as input' do
@ -25,7 +25,8 @@ describe Oga::XML::Parser do
end end
it 'uses more friendly error messages when available' do it 'uses more friendly error messages when available' do
parse_error('</foo>').should =~ /Unexpected element closing tag/ parse_error('<foo>').should ==
'Unexpected end of input, expected element closing tag instead on line 1'
end end
end end
end end

View File

@ -93,7 +93,7 @@ module Oga
# #
def parse_error(xml) def parse_error(xml)
parse(xml) parse(xml)
rescue Racc::ParseError => error rescue LL::ParserError => error
return error.message return error.message
end end
end # ParsingHelpers end # ParsingHelpers

View File

@ -2,6 +2,10 @@ rule '.rb' => '.y' do |task|
sh "racc -l -o #{task.name} #{task.source}" sh "racc -l -o #{task.name} #{task.source}"
end end
rule '.rb' => '.rll' do |task|
sh "ruby-ll #{task.source} -o #{task.name}"
end
desc 'Generates the parser' desc 'Generates the parser'
task :parser => [ task :parser => [
'lib/oga/xml/parser.rb', 'lib/oga/xml/parser.rb',