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

Returns a new instance of StatementParser.



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

Parameters:

  • root_node (Object)
  • tree_root_node (nil) (defaults to: nil)
  • tree_current_node (nil) (defaults to: nil)


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