Compacter parser AST.

The AST no longer uses the generic `element` type for element nodes but instead
changes the type based on the element type. That is, a <p> element now results
in an (p) node, <link> in (link), etc.
This commit is contained in:
Yorick Peterse 2014-03-17 21:03:54 +01:00
parent 8d3f3f15d7
commit 8898d08831
4 changed files with 34 additions and 60 deletions

View File

@ -77,16 +77,18 @@ rule
element element
: element_open attributes element_body T_ELEM_CLOSE : element_open attributes element_body T_ELEM_CLOSE
{ {
s(:element, val[0], val[1], val[2]) namespace, name = val[0]
s(name, namespace, val[1], val[2])
} }
; ;
element_open element_open
# <p> # <p>
: T_ELEM_OPEN T_ELEM_NAME { [nil, val[1]] } : T_ELEM_OPEN T_ELEM_NAME { [nil, val[1].to_sym] }
# <foo:p> # <foo:p>
| T_ELEM_OPEN T_ELEM_NS T_ELEM_NAME { [val[1], val[2]] } | T_ELEM_OPEN T_ELEM_NS T_ELEM_NAME { [val[1], val[2].to_sym] }
; ;
elements elements

View File

@ -20,27 +20,24 @@ describe Oga::Parser do
# <html> # <html>
s( s(
:element, :html,
nil, nil,
'html',
nil, nil,
s(:text, "\n"), s(:text, "\n"),
# <head> # <head>
s( s(
:element, :head,
nil, nil,
'head',
nil, nil,
s(:text, "\n"), s(:text, "\n"),
# <title> # <title>
s( s(
:element, :title,
nil, nil,
'title',
nil, nil,
s(:text, 'Title') s(:text, 'Title')
), ),
@ -50,7 +47,7 @@ describe Oga::Parser do
# <body> # <body>
s(:text, "\n"), s(:text, "\n"),
s(:element, nil, 'body', nil, nil), s(:body, nil, nil, nil),
s(:text, "\n") s(:text, "\n")
), ),
s(:text, "\n") s(:text, "\n")

View File

@ -3,30 +3,27 @@ require 'spec_helper'
describe Oga::Parser do describe Oga::Parser do
context 'elements' do context 'elements' do
example 'parse an empty element' do example 'parse an empty element' do
parse('<p></p>').should == s( parse('<p></p>').should == s(:document, s(:p, nil, nil, nil))
:document,
s(:element, nil, 'p', nil, nil)
)
end end
example 'parse an element with text' do example 'parse an element with text' do
parse('<p>foo</p>').should == s( parse('<p>foo</p>').should == s(
:document, :document,
s(:element, nil, 'p', nil, s(:text, 'foo')) s(:p, nil, nil, s(:text, 'foo'))
) )
end end
example 'parse an element with a single attribute' do example 'parse an element with a single attribute' do
parse('<p foo></p>').should == s( parse('<p foo></p>').should == s(
:document, :document,
s(:element, nil, 'p', s(:attributes, s(:attribute, 'foo')), nil) s(:p, nil, s(:attributes, s(:attribute, 'foo')), nil)
) )
end end
example 'parse an element with a single attribute with a value' do example 'parse an element with a single attribute with a value' do
parse('<p foo="bar"></p>').should == s( parse('<p foo="bar"></p>').should == s(
:document, :document,
s(:element, nil, 'p', s(:attributes, s(:attribute, 'foo', 'bar')), nil) s(:p, nil, s(:attributes, s(:attribute, 'foo', 'bar')), nil)
) )
end end
@ -34,9 +31,8 @@ describe Oga::Parser do
parse('<p foo="bar" baz="bad"></p>').should == s( parse('<p foo="bar" baz="bad"></p>').should == s(
:document, :document,
s( s(
:element, :p,
nil, nil,
'p',
s( s(
:attributes, :attributes,
s(:attribute, 'foo', 'bar'), s(:attribute, 'foo', 'bar'),
@ -51,9 +47,8 @@ describe Oga::Parser do
parse('<p class="foo">Bar</p>').should == s( parse('<p class="foo">Bar</p>').should == s(
:document, :document,
s( s(
:element, :p,
nil, nil,
'p',
s(:attributes, s(:attribute, 'class', 'foo')), s(:attributes, s(:attribute, 'class', 'foo')),
s(:text, 'Bar') s(:text, 'Bar')
) )
@ -63,7 +58,7 @@ describe Oga::Parser do
example 'parse an element with a namespace' do example 'parse an element with a namespace' do
parse('<foo:p></p>').should == s( parse('<foo:p></p>').should == s(
:document, :document,
s(:element, 'foo', 'p', nil, nil) s(:p, 'foo', nil, nil)
) )
end end
@ -71,9 +66,8 @@ describe Oga::Parser do
parse('<foo:p class="bar"></p>').should == s( parse('<foo:p class="bar"></p>').should == s(
:document, :document,
s( s(
:element, :p,
'foo', 'foo',
'p',
s(:attributes, s(:attribute, 'class', 'bar')), s(:attributes, s(:attribute, 'class', 'bar')),
nil nil
) )
@ -83,7 +77,7 @@ describe Oga::Parser do
example 'parse an element nested inside another element' do example 'parse an element nested inside another element' do
parse('<p><a></a></p>').should == s( parse('<p><a></a></p>').should == s(
:document, :document,
s(:element, nil, 'p', nil, s(:element, nil, 'a', nil, nil)) s(:p, nil, nil, s(:a, nil, nil, nil))
) )
end end
@ -91,12 +85,11 @@ describe Oga::Parser do
parse('<p>Foo<a>Bar</a></p>').should == s( parse('<p>Foo<a>Bar</a></p>').should == s(
:document, :document,
s( s(
:element, :p,
nil, nil,
'p',
nil, nil,
s(:text, 'Foo'), s(:text, 'Foo'),
s(:element, nil, 'a', nil, s(:text, 'Bar')) s(:a, nil, nil, s(:text, 'Bar'))
) )
) )
end end
@ -105,12 +98,11 @@ describe Oga::Parser do
parse('<p>Foo<a>Bar</a>Baz</p>').should == s( parse('<p>Foo<a>Bar</a>Baz</p>').should == s(
:document, :document,
s( s(
:element, :p,
nil, nil,
'p',
nil, nil,
s(:text, 'Foo'), s(:text, 'Foo'),
s(:element, nil, 'a', nil, s(:text, 'Bar')), s(:a, nil, nil, s(:text, 'Bar')),
s(:text, 'Baz') s(:text, 'Baz')
) )
) )
@ -120,11 +112,10 @@ describe Oga::Parser do
parse('<p><a>Bar</a>Baz</p>').should == s( parse('<p><a>Bar</a>Baz</p>').should == s(
:document, :document,
s( s(
:element, :p,
nil, nil,
'p',
nil, nil,
s(:element, nil, 'a', nil, s(:text, 'Bar')), s(:a, nil, nil, s(:text, 'Bar')),
s(:text, 'Baz') s(:text, 'Baz')
) )
) )
@ -134,13 +125,12 @@ describe Oga::Parser do
parse('<p><a>Bar</a>Baz<span>Da</span></p>').should == s( parse('<p><a>Bar</a>Baz<span>Da</span></p>').should == s(
:document, :document,
s( s(
:element, :p,
nil, nil,
'p',
nil, nil,
s(:element, nil, 'a', nil, s(:text, 'Bar')), s(:a, nil, nil, s(:text, 'Bar')),
s(:text, 'Baz'), s(:text, 'Baz'),
s(:element, nil, 'span', nil, s(:text, 'Da')) s(:span, nil, nil, s(:text, 'Da'))
) )
) )
end end

View File

@ -5,14 +5,14 @@ describe Oga::Parser do
example 'parse a void element that omits the closing /' do example 'parse a void element that omits the closing /' do
parse('<link>', :html => true).should == s( parse('<link>', :html => true).should == s(
:document, :document,
s(:element, nil, 'link', nil, nil) s(:link, nil, nil, nil)
) )
end end
example 'parse a void element inside another element' do example 'parse a void element inside another element' do
parse('<head><link></head>', :html => true).should == s( parse('<head><link></head>', :html => true).should == s(
:document, :document,
s(:element, nil, 'head', nil, s(:element, nil, 'link', nil, nil)) s(:head, nil, nil, s(:link, nil, nil, nil))
) )
end end
@ -20,14 +20,12 @@ describe Oga::Parser do
parse('<head><link href="foo.css"></head>', :html => true).should == s( parse('<head><link href="foo.css"></head>', :html => true).should == s(
:document, :document,
s( s(
:element, :head,
nil, nil,
'head',
nil, nil,
s( s(
:element, :link,
nil, nil,
'link',
s(:attributes, s(:attribute, 'href', 'foo.css')), s(:attributes, s(:attribute, 'href', 'foo.css')),
nil nil
) )
@ -39,24 +37,11 @@ describe Oga::Parser do
parse('<head><link><title>Foo</title></head>', :html => true).should == s( parse('<head><link><title>Foo</title></head>', :html => true).should == s(
:document, :document,
s( s(
:element, :head,
nil, nil,
'head',
nil, nil,
s( s(:link, nil, nil, nil),
:element, s(:title, nil, nil, s(:text, 'Foo'))
nil,
'link',
nil,
nil
),
s(
:element,
nil,
'title',
nil,
s(:text, 'Foo')
)
) )
) )
end end