| Class | JCON::Parser |
| In: |
lib/jcon/parser.rb
|
| Parent: | StringScanner |
| COMMENT | = | %r{//.*|/\*(?:.|[\r\n])*?\*/} |
| WS_CHAR | = | /[\s\r\n]/ |
| IGNORE | = | /(?:#{COMMENT}|#{WS_CHAR})+/ |
| IDENTIFIER | = | /[\w_$][\w\d_$]*/ |
| dictionary | [R] |
# File lib/jcon/parser.rb, line 22
22: def initialize(source)
23: super(source)
24: @dictionary = Dictionary.new
25: end
# File lib/jcon/parser.rb, line 76
76: def add_modifiers(type)
77: while sscan(/[!?]/)
78: case self[0]
79: when '!'
80: type = required(type)
81: when '?'
82: type = optional(type)
83: end
84: type.context = dictionary
85: end
86: type
87: end
# File lib/jcon/parser.rb, line 112
112: def expect(name, pattern)
113: value = sscan(pattern)
114: parse_error("expected #{name}") unless value
115: value
116: end
# File lib/jcon/parser.rb, line 27
27: def parse
28: reset
29: until eos?
30: case
31: when skip(IGNORE)
32: when skip(/;/)
33: ;
34: when scan(/type/)
35: parse_deftype
36: else
37: type = parse_type
38: dictionary.start = type
39: while skip(IGNORE) || skip(/;/); end
40: parse_error "expected end of input" unless eos?
41: end
42: end
43: dictionary
44: end
# File lib/jcon/parser.rb, line 46
46: def parse_deftype
47: name = expect('identifier', IDENTIFIER)
48: expect('=', /=/)
49: type = parse_type
50: dictionary.deftype(name.intern, type)
51: sscan(/;/)
52: end
# File lib/jcon/parser.rb, line 123
123: def parse_error(msg='unexpected token')
124: raise "#{msg} at '#{skip(IGNORE); peek(20)}'"
125: end
# File lib/jcon/parser.rb, line 99
99: def parse_structure_type
100: map = {}
101: while true
102: break if sscan(/\}/)
103: expect('comma', /,/) if map.any?
104: name = expect('id', IDENTIFIER)
105: expect(':', /:/)
106: type = parse_type
107: map[name.intern] = type
108: end
109: RecordType.new(map)
110: end
# File lib/jcon/parser.rb, line 54
54: def parse_type
55: skip(IGNORE)
56: type = case
57: when id = scan(IDENTIFIER)
58: simple_type(id)
59: when scan(/\*/)
60: simple_type('*')
61: when scan(/\[/)
62: types = parse_types_until(/\]/)
63: list(*types)
64: when scan(/\(/)
65: types = parse_types_until(/\)/)
66: union(*types)
67: when scan(/\{/)
68: parse_structure_type
69: else
70: parse_error
71: end
72: type.context = dictionary
73: add_modifiers(type)
74: end
# File lib/jcon/parser.rb, line 89
89: def parse_types_until(stop_pattern)
90: types = []
91: while true
92: break if sscan(stop_pattern)
93: expect('comma', /,/) if types.any?
94: types << parse_type
95: end
96: types
97: end