Class JCON::Parser
In: lib/jcon/parser.rb
Parent: StringScanner

Methods

Included Modules

Types

Constants

COMMENT = %r{//.*|/\*(?:.|[\r\n])*?\*/}
WS_CHAR = /[\s\r\n]/
IGNORE = /(?:#{COMMENT}|#{WS_CHAR})+/
IDENTIFIER = /[\w_$][\w\d_$]*/

Attributes

dictionary  [R] 

Public Class methods

[Source]

    # File lib/jcon/parser.rb, line 22
22:     def initialize(source)
23:       super(source)
24:       @dictionary = Dictionary.new
25:     end

[Source]

    # File lib/jcon/parser.rb, line 16
16:     def self.parse(source)
17:       self.new(source).parse
18:     end

Public Instance methods

[Source]

    # 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

[Source]

     # 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

[Source]

    # 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

[Source]

    # 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

[Source]

     # File lib/jcon/parser.rb, line 123
123:     def parse_error(msg='unexpected token')
124:       raise "#{msg} at '#{skip(IGNORE); peek(20)}'"
125:     end

[Source]

     # 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

[Source]

    # 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

[Source]

    # 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

[Source]

     # File lib/jcon/parser.rb, line 118
118:     def sscan(pattern)
119:       skip(IGNORE)
120:       scan(pattern)
121:     end

[Validate]