Class: ERLE::Parser

Inherits:
StringScanner
  • Object
show all
Defined in:
lib/erle/parser.rb

Constant Summary collapse

UNPARSED =
Object.new.freeze
IGNORE =
%r(
  (?:
   //[^\n\r]*[\n\r]| # line comments
   /\*               # c-style comments
   (?:
    [^*/]|        # normal chars
    /[^*]|        # slashes that do not start a nested comment
    \*[^/]|       # asterisks that do not end this comment
    /(?=\*/)      # single slash before this comment's end
   )*
     \*/               # the End of this comment
     |[ \t\r\n]+       # whitespaces: space, horicontal tab, lf, cr
  )+
)mx
INTEGER =
/(-?0|-?[1-9]\d*)/
FLOAT =
/(-?
(?:0|[1-9]\d*)
(?:
  \.\d+(?i:e[+-]?\d+) |
  \.\d+ |
  (?i:e[+-]?\d+)
)
)/x
TRUE =
/true/
FALSE =
/false/

Instance Method Summary collapse

Constructor Details

#initialize(source, opts = {}) ⇒ Parser

Returns a new instance of Parser.



36
37
38
39
40
# File 'lib/erle/parser.rb', line 36

def initialize(source, opts = {})
  opts ||= {}
  # source = convert_encoding source
  super source
end

Instance Method Details

#parseObject



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/erle/parser.rb', line 44

def parse
  reset
  obj = nil

  until_done do
    if eos?
      raise_parsing_error
    else
      obj = parse_value
      UNPARSED.equal?(obj) and raise_parsing_error
    end
  end

  eos? or raise_parsing_error
  obj
end

#parse_valueObject



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/erle/parser.rb', line 95

def parse_value
  # TODO: handle symbols
  skip_ignore

  case
  when scan(TRUE)
    true
  when scan(FALSE)
    false
  when !eos? && scan(ERLE::Registry.openings_regex) # TODO: Take out !eos?
    regex, term_class = ERLE::Registry.open_find(matched)
    term_str = term_class.parse(self)
  else
    term_class, regex = ERLE::Registry.pattern_find do |p|
      match?(p)
    end

    if term_class
      term_class.parse(self)
    else
      UNPARSED
    end
  end
end

#peekaboo(peek = 30, back = 30) ⇒ Object



75
76
77
# File 'lib/erle/parser.rb', line 75

def peekaboo(peek = 30, back = 30)
  string[pos-back, peek+back]
end

#raise_parsing_error(message = "source is not valid Erlang!") ⇒ Object

Raises:



79
80
81
82
# File 'lib/erle/parser.rb', line 79

def raise_parsing_error(message = "source is not valid Erlang!")
  # warn "Parsing =>\n#{string}"
  raise ParserError, "Parsing =>\n#{string}\n#{message}"
end

#raise_unexpected_token(followup = nil) ⇒ Object

Raises:



89
90
91
92
93
# File 'lib/erle/parser.rb', line 89

def raise_unexpected_token(followup=nil)
  message = "Unexpected token at:\n#{whereami?}"
  message += "\n#{followup}" if followup
  raise ParserError, message
end

#skip_ignoreObject



61
62
63
# File 'lib/erle/parser.rb', line 61

def skip_ignore
  skip(IGNORE)
end

#until_doneObject



65
66
67
68
69
70
71
72
73
# File 'lib/erle/parser.rb', line 65

def until_done
  result = nil
  while !eos?
    skip_ignore
    result = yield if block_given?
    skip_ignore
  end
  result
end

#whereami?(peek = 30, back = 30) ⇒ Boolean

Returns:

  • (Boolean)


84
85
86
87
# File 'lib/erle/parser.rb', line 84

def whereami?(peek = 30, back = 30)
  back = [back, string.length - pos].sort[0]
  "#{peekaboo(peek, back)}'\n#{"" * (back)}"
end