Class: Ynl::Parser

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

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source) ⇒ Parser

Returns a new instance of Parser.

Parameters:

  • source (String, #read)


9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'ynl/lib/ynl/parser.rb', line 9

def initialize(source)
  @yaml = YAML.load(source, aliases: true)

  @consts = {}
  @flags = {}
  @enums = {}
  @structs = {}

  @attribute_sets = {}
  @attribute_definitions = {}
  @sub_messages = {}
  @operations = {}
  @mcast_groups = {}
end

Class Method Details

.parse_file(path) ⇒ Models::Family

Parameters:

  • path (String, #to_path)

Returns:



27
28
29
# File 'ynl/lib/ynl/parser.rb', line 27

def self.parse_file(path)
  File.open(path) {|f| new(f) }.parse
end

Instance Method Details

#parse ⇒ Models::Family

Returns:



33
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'ynl/lib/ynl/parser.rb', line 33

def parse
  protocol = @yaml['protocol'] || 'genetlink'
  version = @yaml.fetch('version', 1)
  protonum = @yaml['protonum']
  name = @yaml['name']
  doc = translate_doc(@yaml['doc'])

  @yaml['definitions']&.each do |d|
    parse_definition(d)
  end
  @yaml['attribute-sets'].each do |d|
    parse_attribute_set(d)
  end
  @yaml['sub-messages']&.each do |d|
    parse_sub_message(d)
  end
  if operations = @yaml['operations']
    enum_model = case operations['enum-model']
    when 'directional'
      :directional
    when 'unified', nil
      :unified
    else
      raise ParseError, "Unknown enum model: #{operations['enum-model']}"
    end
    @default_fixed_header = operations['fixed-header']&.then { @structs.fetch(it) }

    if enum_model == :unified
      counter = 0
      operations['list']&.each do |d|
        counter = d['value'] || (counter + 1)
        parse_operation(d, request_id: counter, reply_id: counter)
      end
    else
      request_counter = 1
      reply_counter = 1
      operations['list']&.each do |d|
        if d.key?('notify') || d.key?('event')
          reply_counter = d['value'] || reply_counter
          parse_operation(d, request_id: nil, reply_id: reply_counter)
          reply_counter += 1
        else
          primary = d['do'] || d['dump']
          request_counter = primary&.dig('request', 'value') || request_counter
          request_id = request_counter
          request_counter += 1
          if primary&.key?('reply')
            reply_counter = primary.dig('reply', 'value') || reply_counter
            reply_id = reply_counter
            reply_counter += 1
          else
            reply_id = nil
          end
          parse_operation(d, request_id:, reply_id:)
        end
      end
    end
  end
  @yaml.dig('mcast-groups', 'list')&.each do |d|
    parse_mcast_group(d)
  end

  Models::Family.new(
    name:,
    protocol:,
    version:,
    protonum:,
    doc:,
    consts: @consts,
    enums: @enums,
    flags: @flags,
    structs: @structs,
    attribute_sets: @attribute_sets,
    sub_messages: @sub_messages,
    operations: @operations,
    mcast_groups: @mcast_groups,
  ).resolve
end