Skip to content

Commit

Permalink
+ A very simple xml parser
Browse files Browse the repository at this point in the history
This parses something LIKE xml, not XML itself. It serves as yet another
example of how the transformator can be used to achieve different tree
walk goals.
  • Loading branch information
kschiess committed Nov 6, 2010
1 parent ad96e52 commit 3ecbf26
Showing 1 changed file with 60 additions and 0 deletions.
60 changes: 60 additions & 0 deletions example/simple_xml.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# A simple xml parser. It is simple in the respect as that it doesn't address
# any of the complexities of XML. This is ruby 1.9.

$:.unshift '../lib'

require 'pp'
require 'parslet'

module XML
include Parslet

root :document

rule(:document) {
tag(close: false).as(:o) >> document.as(:i) >> tag(close: true).as(:c) |
text
}

# Perhaps we could have some syntax sugar to make this more easy?
#
def tag(opts={})
close = opts[:close] || false

parslet = str('<')
parslet = parslet >> str('/') if close
parslet = parslet >> (str('>').absnt? >> match("[a-zA-Z]")).repeat(1).as(:name)
parslet = parslet >> str('>')

parslet
end

rule(:text) {
match('[^<>]').repeat(0)
}
end

def check(xml)
include XML
r=parse(xml)

# We'll validate the tree by reducing valid pairs of tags into simply the string
# ok. If the transformation ends on a string, then the document was 'valid'.
t = Parslet::Transform.new
t.rule(
o: {name: simple(:o)},
c: {name: simple(:c)},
i: simple(:t)
) { |d|
if d[:o] == d[:c]
"ok."
else
fail "Open tag doesn't match close tag ... #{d.inspect}"
end
}

t.apply(r)
end

pp check("<a><b>some text in the tags</b></a>")
pp check("<b><b>some text in the tags</b></a>")

0 comments on commit 3ecbf26

Please sign in to comment.