Class: DBC::Parser

Inherits:
CTokenizer::LexerBase show all
Includes:
CTokenizer::Scoped
Defined in:
lib/dbc/dbc.rb

Constant Summary

Constants included from CTokenizer

CTokenizer::CP_RESERVED, CTokenizer::C_RESERVED, CTokenizer::EOF_TOKEN

Instance Attribute Summary collapse

Attributes included from CTokenizer::Scoped

#scope

Attributes included from CTokenizer::Sourced

#source

Instance Method Summary collapse

Methods included from CTokenizer::Scoped

#macro?, #process_scope, #start_of_line?

Methods included from CTokenizer::Sourced

#empty?, #file, #file=, #line, #line=, #match?, #scan

Methods included from CTokenizer

#collect, #each, #error, error, line_count, #parse_error, #to_a, #token_error, #unmatched_error, #warning

Constructor Details

#initialize(str, file = nil, line = 1) ⇒ Parser



31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/dbc/dbc.rb', line 31

def initialize(str, file=nil, line=1)
  super(str, file, line)
  
  @scope = 0
  @macro = false
  @start_line = true # begining of file
  
  @contract = nil
  @conditions = {} # hash of contracts
  # @ctype_parser.parse(source) -> parses source until a compelete
  # top level C statement has been parsed.  If the statement is a 
  # function definition it stops when the opening '{' is reached.
  @ctype_parser = CType::Parser.new()
end

Instance Attribute Details

#conditionsObject (readonly)

Returns the value of attribute conditions.



46
47
48
# File 'lib/dbc/dbc.rb', line 46

def conditions
  @conditions
end

Instance Method Details

#each_statementObject



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
# File 'lib/dbc/dbc.rb', line 58

def each_statement
  until @source.empty?
    context = @ctype_parser.parse(self)
    # if scope != 0 then we are in a function body
    if f_body = (@scope != 0)
      # first yield function header
      yield(nil)
      until @scope == 0 or @source.empty?
        # get back to group zero
        # don't check for contract comments
        process_scope(@source.shift)
      end
    end #if
    # add type definitions
    context.each do |ctxt|
      CType[ctxt.identifier] = ctxt if ctxt.typedef?
    end
    if @contract
      # the contract should have no context
      #raise "impossible" if @contract.context
      self.error("expecting one context for contract") unless context.length == 1
      @contract.context = context.first
      self.merge_current_contract()
    end # if
    yield(f_body ? context.first : nil)
  end # until
end

#merge_current_contractObject

each_statement



86
87
88
89
90
91
# File 'lib/dbc/dbc.rb', line 86

def merge_current_contract()
  context = @contract.context
  context = context.short_name unless context.class == String
  @conditions[context] = @contract
  @contract = nil # done with current contract
end

#shiftObject



48
49
50
51
52
53
54
55
56
# File 'lib/dbc/dbc.rb', line 48

def shift
  t = process_scope(super)
  if t.at(0) == :COMMENT and start_of_line? and ocl = DBC.get_ocl(t.at(1))
    self.error("no context for previous contract") if @contract
    @contract = OCL::Parser.new(ocl, self.file, self.line - CTokenizer.line_count(ocl))
    self.merge_current_contract() if @contract.context
  end
  t
end