Lexing/parsing of XML declaration tags.

This closes #12.
This commit is contained in:
Yorick Peterse 2014-03-24 21:30:19 +01:00
parent b695ecf0df
commit ac775918ee
4 changed files with 76 additions and 4 deletions

View File

@ -376,6 +376,34 @@ module Oga
any;
*|;
# XML declaration tags
#
# http://www.w3.org/TR/REC-xml/#sec-prolog-dtd
#
xml_decl_start = '<?xml';
xml_decl_end = '?>';
action start_xml_decl {
emit_buffer
add_token(:T_XML_DECL_START, nil)
start_buffer
fcall xml_decl;
}
# Machine that processes the contents of an XML declaration tag.
xml_decl := |*
xml_decl_end => {
emit_buffer
add_token(:T_XML_DECL_END, nil)
fret;
};
any;
*|;
# Elements
#
# http://www.w3.org/TR/html-markup/syntax.html#syntax-elements
@ -433,10 +461,11 @@ module Oga
*|;
main := |*
element_start => start_element;
doctype_start => start_doctype;
cdata_start => start_cdata;
comment_start => start_comment;
element_start => start_element;
doctype_start => start_doctype;
cdata_start => start_cdata;
comment_start => start_comment;
xml_decl_start => start_xml_decl;
# Enter the body of the tag. If HTML mode is enabled and the current
# element is a void element we'll close it and bail out.

View File

@ -14,6 +14,7 @@ token T_DOCTYPE_START T_DOCTYPE_END T_DOCTYPE_TYPE
token T_CDATA_START T_CDATA_END
token T_COMMENT_START T_COMMENT_END
token T_ELEM_START T_ELEM_NAME T_ELEM_NS T_ELEM_END T_ATTR
token T_XML_DECL_START T_XML_DECL_END
options no_result_var
@ -35,6 +36,7 @@ rule
| comment
| element
| text
| xmldecl
;
# Doctypes
@ -119,6 +121,11 @@ rule
| T_ATTR T_STRING { s(:attribute, val[0], val[1]) }
;
# XML declarations
xmldecl
: T_XML_DECL_START T_XML_DECL_END { s(:xml_decl) }
| T_XML_DECL_START text T_XML_DECL_END { s(:xml_decl, val[1]) }
# Plain text
text

View File

@ -0,0 +1,24 @@
require 'spec_helper'
describe Oga::Lexer do
context 'XML declaration tags' do
example 'lex a start tag' do
lex('<?xml').should == [[:T_XML_DECL_START, nil, 1]]
end
example 'lex a start and end tag' do
lex('<?xml?>').should == [
[:T_XML_DECL_START, nil, 1],
[:T_XML_DECL_END, nil, 1]
]
end
example 'lex a tag with text inside it' do
lex('<?xml version="1.0" ?>').should == [
[:T_XML_DECL_START, nil, 1],
[:T_TEXT, ' version="1.0" ', 1],
[:T_XML_DECL_END, nil, 1]
]
end
end
end

View File

@ -0,0 +1,12 @@
require 'spec_helper'
describe Oga::Parser do
context 'XML declaration tags' do
example 'lex an XML declaration tag' do
parse('<?xml hello ?>').should == s(
:document,
s(:xml_decl, s(:text, ' hello '))
)
end
end
end