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

Returns a new instance of 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