Class: ZRB::Parser
- Inherits:
-
Object
- Object
- ZRB::Parser
- Defined in:
- lib/zrb.rb
Constant Summary collapse
- SPACE =
/[\t ]/- TOKEN =
/ (.*?) # Regular text (?: ( # Expression start \#\{ ) | (?: # Statement (^#{SPACE}*)? \<\? (.*?) \?> (#{SPACE}*\n)? # Remove trailing newline ) | \z ) /mx
- EXPR_CLOSE =
'}'
Instance Attribute Summary collapse
-
#data ⇒ Object
readonly
Returns the value of attribute data.
-
#filename ⇒ Object
readonly
Returns the value of attribute filename.
-
#lineno ⇒ Object
readonly
Returns the value of attribute lineno.
-
#source ⇒ Object
readonly
Returns the value of attribute source.
Instance Method Summary collapse
- #append_expr(ruby) ⇒ Object
- #append_newline ⇒ Object
- #append_ruby(ruby) ⇒ Object
- #append_text(text) ⇒ Object
- #ensure_string ⇒ Object
- #generate ⇒ Object
-
#initialize(data, filename, lineno) ⇒ Parser
constructor
A new instance of Parser.
- #parse ⇒ Object
- #valid_ruby?(text) ⇒ Boolean
Constructor Details
#initialize(data, filename, lineno) ⇒ Parser
Returns a new instance of Parser.
5 6 7 8 9 10 11 12 |
# File 'lib/zrb.rb', line 5 def initialize(data, filename, lineno) @data = data @filename = filename @lineno = lineno @source = "" @state = :ruby generate end |
Instance Attribute Details
#data ⇒ Object (readonly)
Returns the value of attribute data.
3 4 5 |
# File 'lib/zrb.rb', line 3 def data @data end |
#filename ⇒ Object (readonly)
Returns the value of attribute filename.
3 4 5 |
# File 'lib/zrb.rb', line 3 def filename @filename end |
#lineno ⇒ Object (readonly)
Returns the value of attribute lineno.
3 4 5 |
# File 'lib/zrb.rb', line 3 def lineno @lineno end |
#source ⇒ Object (readonly)
Returns the value of attribute source.
3 4 5 |
# File 'lib/zrb.rb', line 3 def source @source end |
Instance Method Details
#append_expr(ruby) ⇒ Object
103 104 105 106 |
# File 'lib/zrb.rb', line 103 def append_expr(ruby) ensure_string source << "\#{buffer.escape((#{ruby}))}" end |
#append_newline ⇒ Object
114 115 116 117 118 119 120 |
# File 'lib/zrb.rb', line 114 def append_newline if @state == :string source << "\"\\\n\"" else source << "\n" end end |
#append_ruby(ruby) ⇒ Object
108 109 110 111 112 |
# File 'lib/zrb.rb', line 108 def append_ruby(ruby) source << '";' if @state == :string source << ruby @state = :ruby end |
#append_text(text) ⇒ Object
96 97 98 99 100 101 |
# File 'lib/zrb.rb', line 96 def append_text(text) escaped = text.split("\n", -1).map { |part| part.inspect[1..-2] }.join("\n") ensure_string source << escaped end |
#ensure_string ⇒ Object
89 90 91 92 93 94 |
# File 'lib/zrb.rb', line 89 def ensure_string if @state != :string source << 'buffer << "' @state = :string end end |
#generate ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/zrb.rb', line 122 def generate append_ruby('buffer = build_zrb_buffer;') parse do |type, value| case type when :text append_text(value) when :expression append_expr(value) when :block_expression append_ruby("buffer.safe_append=#{value};") when :statement append_ruby("#{value};") when :newline append_newline when :comment # no nothing else raise "internal error: unknown parsing type" end end append_ruby('buffer') end |
#parse ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/zrb.rb', line 34 def parse pos = 0 while pos < data.size match = data.match(TOKEN, pos) raise SyntaxError, "#{filename}:#{lineno}: parse error" unless match all, text, expr, _, statement, statement_space = *match pos += all.size yield :text, text unless text.empty? if expr # Start looking for a closing brace closing_pos = pos begin closing_pos = data.index(EXPR_CLOSE, closing_pos + 1) break unless closing_pos expr = data[pos...closing_pos] end until valid_ruby?(expr) if !closing_pos raise SyntaxError, "#{filename}:#{lineno}: unclosed brace" end yield :expression, expr pos = closing_pos + 1 end if statement case statement[0] when ?= # block expression yield :block_expression, statement[1..-1] when ?# # comment yield :comment, statement[1..-1] else yield :statement, statement end end yield :newline if statement_space end end |
#valid_ruby?(text) ⇒ Boolean
79 80 81 82 83 84 85 86 87 |
# File 'lib/zrb.rb', line 79 def valid_ruby?(text) catch(:halt) do eval("BEGIN{throw :halt};#{text}") end rescue SyntaxError false else true end |