Class: IcAgent::Ast::StatementParser

Inherits:
Object
  • Object
show all
Defined in:
lib/ic_agent/ast/statement_parser.rb

Constant Summary collapse

REFER_TYPE_CLASS =
['IcAgent::Ast::Nodes::IcBaseTypeRecord',
'IcAgent::Ast::Nodes::IcBaseTypeVariant',
'IcAgent::Ast::Nodes::IcBaseTypeVec',
'IcAgent::Ast::Nodes::IcBaseTypeOpt']
TREE_TYPE_CLASS =
['IcAgent::Ast::Nodes::IcBaseTypeRecord',
'IcAgent::Ast::Nodes::IcBaseTypeVariant',
'IcAgent::Ast::Nodes::IcBaseTypeVec',
'IcAgent::Ast::Nodes::IcBaseTypeFunc',
'IcAgent::Ast::Nodes::IcBaseTypeOpt',
'IcAgent::Ast::Nodes::IcBaseTypeSingle',
'IcAgent::Ast::Nodes::IcBaseTypeOther']
REFER_TYPE_KEYS =
['record', 'variant']

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeStatementParser



23
24
25
26
# File 'lib/ic_agent/ast/statement_parser.rb', line 23

def initialize
  Treetop.load(File.expand_path(File.join(File.dirname(__FILE__), 'nested_type_grammar.treetop')))
  @parser = TypeGrammarParser.new
end

Instance Attribute Details

#parserObject

Returns the value of attribute parser.



6
7
8
# File 'lib/ic_agent/ast/statement_parser.rb', line 6

def parser
  @parser
end

#source_treeObject

Returns the value of attribute source_tree.



6
7
8
# File 'lib/ic_agent/ast/statement_parser.rb', line 6

def source_tree
  @source_tree
end

#treeObject

Returns the value of attribute tree.



6
7
8
# File 'lib/ic_agent/ast/statement_parser.rb', line 6

def tree
  @tree
end

Instance Method Details

#clean_tree(root_node) ⇒ Object



41
42
43
44
45
46
# File 'lib/ic_agent/ast/statement_parser.rb', line 41

def clean_tree(root_node)
  return if root_node.elements.nil?

  root_node.elements.delete_if { |node| node.class.name == 'Treetop::Runtime::SyntaxNode' and node.parent.class.name != 'IcAgent::Ast::Nodes::IcBaseTypeValue' and node.parent.class.name != "IcAgent::Ast::Nodes::IcTypeDef" }
  root_node.elements.each { |node| self.clean_tree(node) }
end

#gen_source_tree(root_node, tree_root_node = nil, tree_current_node = nil) ⇒ Object



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
# File 'lib/ic_agent/ast/statement_parser.rb', line 51

def gen_source_tree(root_node, tree_root_node = nil, tree_current_node = nil)
  return if root_node.elements.nil?

  tree_root_node = tree_root_node.nil? ? Tree::TreeNode.new('root', { 'total_child': 0, 'ic_type': nil, 'refer_type': [], 'prototype': root_node.source_content, 'content': root_node.source_content }) : tree_root_node
  tree_current_node = tree_current_node.nil? ? tree_root_node : tree_current_node

  root_node.elements.each do |node|
    if TREE_TYPE_CLASS.include?(node.class.name) && node.source_content != tree_root_node.content[:prototype]

      id = tree_root_node.content[:total_child] + 1
      new_tree_node = Tree::TreeNode.new("node_#{id}", { 'total_child': 0, 'ic_type': nil, 'prototype': root_node.source_content, 'content': root_node.source_content })
      tree_current_node << new_tree_node
      tree_root_node.content[:total_child] = id

      # set refer_type
      unless Regexp.union(REFER_TYPE_KEYS) === root_node.source_content
        # func type content
        if root_node.source_content.index('->')
          param_arr = []
          temp_param_arr = root_node.source_content.strip.split(' ').collect { |v| v.strip.gsub(';', '') }
          temp_param_arr.delete_if {|v| !v.index('(') && !v.index(')') }
          temp_param_arr.each {|v| param_arr = param_arr + v.sub('(', '').sub(')', '').split(',')}
        else
          param_arr = root_node.source_content.strip.split(' ').collect { |v| v.strip.gsub(';', '') }
          param_arr = param_arr - IcAgent::Candid::ALL_TYPES
        end
        tree_root_node.content[:refer_type] = (tree_root_node.content[:refer_type] + param_arr).uniq
      end

      self.source_tree = tree_root_node
      self.gen_source_tree(node, tree_root_node, new_tree_node)
    else
      self.gen_source_tree(node, tree_root_node, tree_current_node)
    end
  end

  self.source_tree = tree_root_node
end

#ic_statement_childsObject



94
95
96
97
98
# File 'lib/ic_agent/ast/statement_parser.rb', line 94

def ic_statement_childs
  if tree.elements[0] && tree.elements[0].elements[0].elements[0]
    tree.elements[0].elements[0].elements[0].elements
  end
end

#ic_statement_rootObject



90
91
92
# File 'lib/ic_agent/ast/statement_parser.rb', line 90

def ic_statement_root
  tree.elements[0]
end

#parse(data, return_type = :string) ⇒ Object

Raises:

  • (Exception)


28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/ic_agent/ast/statement_parser.rb', line 28

def parse(data, return_type = :string)
  tree = @parser.parse(data)
  raise Exception, "Parse error at offset: #{@parser.index} #{@parser.failure_reason}" if tree.nil?

  # this edits the tree in place
  clean_tree(tree)

  # generate soure tree
  gen_source_tree(tree)
  @tree = tree
  tree
end