ruby 解析器 - 示例解析器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ruby 解析器 - 示例解析器相关的知识,希望对你有一定的参考价值。
## Simple Parser
##
## This parser implments an example of a parser similiar to Hoplon or Pollen
## in that it translates an s expression to html
## ie (h1 "The Great Gatsby") produces <h1>The Great Gatsby</h1>
#
#
# Input
#
#
# Initial S Expression
#
# (html
# (head
# (title "Hello World"))
# (body
# (h1 "Hello World")
# (p "This is your parser")))
#
#
# '(html(head(title "Hello World"))(body (h1 "Hello World")(p "This is your parser")))'
#
## Converted to nested array of symbols with class Reader
##
## parse_string ==
## [:html, [:head, [:title, "Hello World"]], [:body, [:h1, "Hello World"], [:p, "This is your parser"]]]
##
##
### Finally to HTML
###
### <html>
### <head>
### <title>Hello World</title>
### </head>
### <body>
### <h1> Hello World </h1>
### <p> This is your parser</p>
### </body>
### </html>
require 'strscan'
class Reader < StringScanner
# Check for Missing parens
def initialize(string)
unless(string.count('(') == string.count(')'))
raise Exception, "Missing closing parentheses"
end
super(string)
end
# Pull the tokens from the S_Exp into an Array
def parse
exp = []
while true
case fetch_token
when '('
exp << parse
when ')'
break
when :"'"
case fetch_token
when '(' then exp << [:quote].concat([parse])
else exp << [:quote, @token]
end
when String, Fixnum, Symbol
exp << @token
when nil
break
end
end
exp
end
# Use scan with regex to grab each token
def fetch_token
skip(/\s+/)
return nil if(eos?)
@token =
# Match parentheses
if scan(/[\(\)]/)
matched
# Match a string
elsif scan(/"([^"\\]|\\.)*"/)
eval(matched)
# Match an integer
elsif scan(/[\-\+]?[0-9]+/)
matched.to_i
# Match a single quote (for single quoting)
elsif scan(/'/)
matched.to_sym
# Match a symbol
elsif scan(/[^\(\)\s]+/)
matched.to_sym
# If we've gotten here then we have an invalid token
else
near = scan %r{.{0,20}}
raise "Invalid character at position #{pos} near '#{near}'."
end
end
end
class Parser
# Parse a string containing an S-Expression into a
# nested set of Ruby arrays
def parse_string(string)
tree = Reader.new(string).parse
tree = tree[0] # pull off the outer Array
return tree
end
def to_html(data)
if (data.is_a?(Array))
tag = data[0]
children = data[1..-1]
return "<#{tag}>" + children.map {|x| to_html(x)}.join(' ') + "</#{tag}>"
else
return data
end
end
# Convert a set of nested arrays back into an S-Expression
def to_sexp(data)
if( data.is_a?(Array))
mapped = data.map do |item|
if( item.is_a?(Array))
to_sexp(item)
else
item.to_s
end
end
"(" + mapped.join(" ") + ")"
else
data.to_s
end
end
end
以上是关于ruby 解析器 - 示例解析器的主要内容,如果未能解决你的问题,请参考以下文章