Provide somewhat more meaningful parser errors.

While still a bit cryptic this is probably as best as we can get it. An example:

    Oga.parse_xml("<namefoo:bar=\"10\"")

    parser.rb:116:in `on_error': Unexpected string on line 1: (Racc::ParseError)

    => 1: <namefoo:bar="10"

This fixes #43.
This commit is contained in:
Yorick Peterse 2014-09-16 01:09:06 +02:00
parent 32b11ef1e2
commit cdfeeed85f
2 changed files with 35 additions and 1 deletions

View File

@ -193,6 +193,35 @@ rule
end end
---- 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',
'$end' => '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
@ -237,6 +266,7 @@ end
# #
def on_error(type, value, stack) def on_error(type, value, stack)
name = token_to_str(type) name = token_to_str(type)
name = TOKEN_ERROR_MAPPING[name] || name
index = @line - 1 index = @line - 1
index_range = (index - 5)..(index + 5) index_range = (index - 5)..(index + 5)
code = '' code = ''
@ -268,7 +298,7 @@ end
end end
raise Racc::ParseError, <<-EOF.strip raise Racc::ParseError, <<-EOF.strip
Unexpected #{name} with value #{value.inspect} on line #{@line}: Unexpected #{name} on line #{@line}:
#{code} #{code}
EOF EOF

View File

@ -43,5 +43,9 @@ describe Oga::XML::Parser do
parse_error(StringIO.new(@invalid_xml)).should =~ /#{partial}/ parse_error(StringIO.new(@invalid_xml)).should =~ /#{partial}/
end end
example 'use more friendly error messages when available' do
parse_error('</foo>').should =~ /Unexpected element closing tag/
end
end end
end end