lib/interpreter/parse.tab.rb in nudge-0.1.2 vs lib/interpreter/parse.tab.rb in nudge-0.1.3
- old
+ new
@@ -1,12 +1,7 @@
# encoding: utf-8
-# DO NOT MODIFY!!!!
-# This file is automatically generated by racc 1.4.5
-# from racc grammer file "parse.y".
-#
-
require 'racc/parser'
require 'strscan'
class NudgeTree < Racc::Parser
@@ -14,34 +9,54 @@
module_eval <<'..end parse.y modeval..ida1760a43d7', 'parse.y', 22
def self.from(string)
nt = NudgeTree.new(string)
result = nt.send(:do_parse)
{tree:result, unused:nt.footnotes}
+ rescue ParseError => exc
+ {tree:NilPoint.new, unused:{}}
end
- attr_accessor :footnotes
+ attr_accessor :tree, :footnotes, :unused_footnotes
+
+
def initialize(string)
@tokens = []
@string = string.strip
@footnotes = Hash.new { |hash, category| hash[category] = [] }
-
+ @unused_footnotes = {}
self.make_footnotes!
self.tokenize!
end
+
def make_footnotes!
- return unless split_point = @string.index(/^«/)
+ return unless split_point = @string.index(/\n«/um)
raise ParseError, "No program string" if split_point == 0
- ss = StringScanner.new(@string.slice!((split_point - 1)..-1))
+ ss = StringScanner.new(@string.slice!((split_point)..-1))
- while ss.scan(/\n/)
- @footnotes[ss.scan(/«[\p{Alpha}][_\p{Alnum}]*»/u)[1..-2]] << ss.scan(/[^\n]*/).strip # <-- /\n«/
+ fn_head = /\n«([\p{Alpha}][_\p{Alnum}]*)»/u
+
+ while ss.exist?(fn_head)
+ ss.scan_until(fn_head)
+ cat = ss[1]
+ if ss.exist?(/\n«/um)
+ ss.scan_until(/(.*?)\n«/um)
+ fn = ss[1]
+ elsif ss.eos?
+ fn = ""
+ else
+ ss.scan_until(/(.*)$/um)
+ fn = ss[1]
+ end
+ ss.pos -= 3
+ @footnotes[cat] << fn.strip
end
end
+
def pop_footnote(category)
value = @footnotes[category].shift
if category == "code"
embedded_footnotes = [""]
@@ -50,55 +65,58 @@
end
return value
end
+
def collect_embedded_footnotes!(code_text, embedded_footnotes)
- ss = StringScanner.new(code_text)
-
- while ss.skip_until(/«[\p{Alpha}][\p{Alnum}_]*»/)
- category = ss.matched[1...-1]
- footnote = @footnotes[category].shift
+ ss = StringScanner.new(code_text)
+ while ss.skip_until(/«([\p{Alpha}][\p{Alnum}_]*?)»/um)
+ category = ss[1]
+ footnote = @footnotes[category].shift || ""
- embedded_footnotes << "«#{category}»#{footnote}"
+ embedded_footnotes << "«#{category}» #{footnote}"
if category == "code"
self.collect_embedded_footnotes!(footnote, embedded_footnotes)
end
end
end
+
def next_token
return @tokens.shift
end
+
def tokenize!
ss = StringScanner.new(@string)
until ss.eos?
@tokens << case c = ss.getch
when /\s/
nil
when /[{}«»]/
[c, 0]
- when /[\p{Alpha}]/
- ss.pointer -= 1
- ss.scan(/[\p{Alpha}][\p{Alnum}_]*/) # <- \p{Alpha}
+ when /[\p{Alpha}]/u
+ ss.unscan
+ ss.scan(/[\p{Alpha}][_\p{Alnum}]*/u) # <- \p{Alpha}
case m = ss.matched
when "block", "ref", "do", "value"
[m, 0]
else
[:ID, m]
end
else
- raise ParseError, "Couldn't tokenize program string"
+ raise ParseError, "Couldn't tokenize program string \"#{@string}\""
end
end
@tokens.compact!
@tokens << [false, false]
end
+
def on_error(error_token_id, error_value, value_stack)
raise ParseError, "Couldn't parse program string"
end
\ No newline at end of file