tla-trace-filter 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,134 @@
1
+ module TlaTraceFilter
2
+
3
+ # Class service {#filter} acepptss lines from tla+tools trace
4
+ # output, and manages state {#state}, {#lines},
5
+ # {#stateLine}.Collaborates with {#parser} to parse state variable
6
+ # assignents in trace output {#lines}
7
+ #
8
+ class Filter
9
+
10
+ include TlaTraceFilter::Util::MyLogger
11
+
12
+
13
+ # @# @!attribute [String] stateLine line opending state space dump
14
+ attr_accessor :stateLine
15
+
16
+ # @# @!attribute [Array<String>] lines collected
17
+ attr_accessor :lines
18
+
19
+ # @# @!attribute [enum] state where filtering is in
20
+ attr_accessor :state
21
+
22
+
23
+ # @# @!attribute [Parser] parser
24
+ attr_accessor :parser
25
+
26
+ # ------------------------------------------------------------------
27
+ # @!group Constructor
28
+
29
+ def initialize(options={})
30
+
31
+ @logger = getLogger( nil, options )
32
+ @logger.info "#{__method__}: init filter"
33
+
34
+
35
+ initState( options )
36
+ end
37
+
38
+ def initState( options = {} )
39
+ self.state = :default
40
+ self.parser = TlaTraceFilter::Parser::Parser.new( options )
41
+ end
42
+
43
+ # @!endgroup
44
+
45
+
46
+ # ------------------------------------------------------------------
47
+ # @!group Class services
48
+
49
+ # Accept 'line' input and act according to {#state} :default=
50
+ # return 'line' possibly modified in place, :inStateSpace=collect
51
+ # {#lines}.
52
+ #
53
+ # @param line [String] line to filter
54
+ #
55
+ # @return [String, nil] result from filtering line, nil do not
56
+ # output
57
+ def filter(line)
58
+ case state
59
+ when :default
60
+ inDefault(line)
61
+ when :inStateSpace
62
+ inStateSpace(line)
63
+ else
64
+ raise "Unknown filter state #{state}"
65
+ end
66
+ end
67
+
68
+
69
+ # @!endgroup
70
+
71
+
72
+
73
+ # ------------------------------------------------------------------
74
+ # @!group Filter state machine. Valid states see {#filter}
75
+
76
+ def inDefault( line )
77
+ if line =~ /^State [0-9]+:/
78
+ enterStateSpace( line )
79
+ else
80
+ line
81
+ end
82
+ end
83
+
84
+ def inStateSpace( line )
85
+ if line =~ /^[\s]*\n$/
86
+ return exitStateSapce
87
+ else
88
+ self.lines << line
89
+ return nil
90
+ end
91
+ end
92
+
93
+ # @!endgroup
94
+
95
+ # ------------------------------------------------------------------
96
+ # @!group State changes
97
+
98
+ # @return [nil] nil output postponed in exit state apce
99
+ def enterStateSpace(line)
100
+ @logger.info "#{__method__}: line=#{line}"
101
+ self.stateLine = line
102
+ self.lines = []
103
+ # self.lines = [ line ]
104
+
105
+ self.state = :inStateSpace
106
+ return nil
107
+ end
108
+
109
+ # @return [Hash] hash with properties :line (String), :actionLine
110
+ # (Integer parsed), :state_space
111
+ def exitStateSapce
112
+ @logger.info "#{__method__} entering"
113
+
114
+ ret = {
115
+ :line => stateLine || "empty line",
116
+ :actionLine => stateLine[/Action line ([0-9]*)/,1].to_i,
117
+ :state_space => parser.parse( lines.join( "\n") ).value,
118
+ }
119
+ @logger.info "#{__method__} return=#{ret.to_yaml}"
120
+ self.state = :default
121
+ ret
122
+ end
123
+
124
+ # @!endgroup
125
+
126
+ # ------------------------------------------------------------------
127
+ # @!group Helpers
128
+
129
+
130
+ # @!endgroup
131
+
132
+
133
+ end
134
+ end
@@ -0,0 +1,132 @@
1
+ module TlaTraceFilter
2
+ module Parser
3
+ grammar Grammar
4
+
5
+ # ------------------------------------------------------------------
6
+ # state_space
7
+
8
+ rule state_space
9
+ ( '/\\' space variables:state_variable space* <NonTerminal> )* <StateSpace> / newline
10
+ end
11
+
12
+ rule state_variable
13
+ state_variable:name space+ "=" space+ variable_value:composite_value <StateVariable>
14
+ end
15
+
16
+ # ------------------------------------------------------------------
17
+ # Composite values
18
+
19
+ rule composite_value
20
+ set_value /
21
+ function_value / sequence_value / record_value / reserved_word / integer / string
22
+ end
23
+
24
+ rule set_value
25
+ '{' space* (value_list)? '}' <SetValue>
26
+ end
27
+
28
+ rule function_value
29
+ '(' space* (function_value_list)? ')' <FunctionValue>
30
+ end
31
+
32
+ rule sequence_value
33
+ '<<' space* (value_list)? '>>' <SequenceValue>
34
+ end
35
+
36
+ rule record_value
37
+ '[' space* (record_element_list)? ']' <RecordValue>
38
+ end
39
+
40
+
41
+ # ------------------------------------------------------------------
42
+ # Composite buiding blocks
43
+
44
+ rule record_element_list
45
+ record_element space* (record_element_list_tail)*
46
+ end
47
+
48
+ rule record_element_list_tail
49
+ ',' space* record_element
50
+ end
51
+
52
+ rule record_element
53
+ element_name:name space* '|->' space* element_value:value space* <RecordElement>
54
+ end
55
+
56
+ rule function_value_list
57
+ function_value_element space* (function_value_list_tail)*
58
+ end
59
+
60
+ rule function_value_list_tail
61
+ '@@' space* function_value_element
62
+ end
63
+
64
+ rule function_value_element
65
+ domain:function_domain space* ':>' space* range:value space* <FunctionElement>
66
+ end
67
+
68
+ rule function_domain
69
+ string / integer / reserved_word
70
+ end
71
+
72
+ rule value_list
73
+ value space* (value_list_tail)*
74
+ end
75
+
76
+ rule value_list_tail
77
+ ',' space* value_list
78
+ end
79
+
80
+ rule value
81
+ reserved_word / integer / string / composite_value
82
+ end
83
+
84
+
85
+ # ------------------------------------------------------------------
86
+ # atomic values
87
+
88
+ rule string
89
+ '"' string_value:[^"]* '"' <StringValue>
90
+ end
91
+
92
+ rule name
93
+ [_A-Za-z] [_A-Za-z0-9]* <Name>
94
+ end
95
+
96
+ rule integer
97
+ ('+'/'-')? [0-9]+ <IntegerValue>
98
+ end
99
+
100
+ rule reserved_word
101
+ (tla_reserved_word/ sbuilder_reserved_word )
102
+ end
103
+
104
+ rule tla_reserved_word
105
+ "FALSE" <FalseValue> / "TRUE" <TrueValue>
106
+ end
107
+
108
+ rule sbuilder_reserved_word
109
+ "Nil" <NilValue> / "WildCard" <WildCardValue>
110
+ end
111
+
112
+
113
+
114
+ # ------------------------------------------------------------------
115
+ # white spaces etc
116
+
117
+ rule space
118
+ whitespace / newline
119
+ end
120
+
121
+ rule whitespace
122
+ [\s]+
123
+ end
124
+
125
+ rule newline
126
+ [\n]
127
+ end
128
+
129
+
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,267 @@
1
+ require 'set'
2
+ # Open up Treetop::Runtime::SyntaxNode to add tree traversal methods
3
+ module Treetop
4
+ module Runtime
5
+ class SyntaxNode
6
+
7
+ # ------------------------------------------------------------------
8
+ # @!group Tree traversing methods added to an opend class
9
+
10
+
11
+ # @return [s(AstSexp) nodes matching 'sym' or 'blk' returning
12
+ # true anywhere in sexp-tree
13
+ def nodes_with_match( cl=nil, &blk )
14
+ blk = ->(chldSexp) { chldSexp.class == cl } unless cl.nil?
15
+ nodes = [] # []
16
+ deep_each do |n|
17
+ found = blk[n]
18
+ nodes << n if found
19
+ found
20
+ end
21
+ nodes
22
+ end
23
+
24
+ def deep_each(prune=true, &block)
25
+ return enum_for(:deep_each) unless block_given?
26
+
27
+ each_sexp do |sexp|
28
+ found = block[sexp]
29
+ if !( prune && found )
30
+ sexp.deep_each(&block)
31
+ end
32
+ end
33
+ end
34
+
35
+ def each_sexp
36
+ return enum_for(:each_sexp) unless block_given?
37
+ elements && elements.each do |sexp|
38
+ # next unless Sexp === sexp
39
+ yield sexp
40
+ end
41
+ end
42
+
43
+ # @!endgroup
44
+
45
+
46
+ end # class SyntaxNode
47
+ end
48
+
49
+ end
50
+
51
+ module TlaTraceFilter
52
+ module Parser
53
+ module Grammar
54
+
55
+ class Root <Treetop::Runtime::SyntaxNode
56
+ end # root
57
+
58
+
59
+ class NonTerminal <Root
60
+ end
61
+ class Terminal <Root
62
+ end
63
+
64
+ class StateSpace < NonTerminal
65
+
66
+ def value
67
+ h = state_space
68
+ h.keys.each do |variable|
69
+ h[variable] = h[variable].variable_value.value
70
+ end
71
+ h
72
+ end
73
+
74
+ def state_space
75
+ # nodes_with_match(StateVariable).each_with_index do |e, indx|
76
+ # puts ( "#{indx} e.class=#{e.class} #{e.respond_to?(:name) ? e.name : 'xx'}")
77
+ # end
78
+ nodes_with_match(StateVariable).inject( {} ) do |memo,stateVariable|
79
+ memo[stateVariable.name.to_sym] = stateVariable
80
+ memo
81
+ end
82
+ end
83
+ end
84
+
85
+
86
+ class StateVariable < NonTerminal
87
+ def name
88
+ state_variable.text_value
89
+ end
90
+ end
91
+
92
+ # ------------------------------------------------------------------
93
+ # @!group Composites
94
+
95
+ class CompositeValue < NonTerminal
96
+
97
+ def value_childs
98
+ nodes_with_match do |n|
99
+ n.is_a?( Terminal ) ||
100
+ n.is_a?( CompositeValue) ||
101
+ n.is_a?(RecordElement) ||
102
+ n.is_a?(FunctionElement)
103
+ end
104
+ end
105
+
106
+ end
107
+
108
+ class FunctionValue < CompositeValue
109
+
110
+ def value
111
+ function_value
112
+ end
113
+
114
+ def function_value
115
+ value_childs.inject({}) do |memo, functionElement|
116
+ memo = memo.merge( functionElement.value )
117
+ end
118
+ end
119
+
120
+ end
121
+
122
+ class RecordValue < CompositeValue
123
+ def value
124
+ record_value
125
+ end
126
+
127
+ def record_value
128
+ value_childs.inject({}) do |memo, recordElement|
129
+ memo = memo.merge( recordElement.value )
130
+ end
131
+ # {}
132
+ end
133
+
134
+ def record_elements
135
+ value_childs
136
+ end
137
+
138
+ end
139
+
140
+ class SetValue < CompositeValue
141
+ def value
142
+ set_value
143
+ end
144
+
145
+ def set_value
146
+ Set.new(set_array)
147
+ end
148
+
149
+ def set_array
150
+ value_childs.inject( [] ) do |memo, setElement|
151
+ memo << setElement.value
152
+ memo
153
+ end
154
+ end
155
+
156
+
157
+ end
158
+
159
+
160
+ class FunctionElement < NonTerminal
161
+ def value
162
+ function_element_value
163
+ end
164
+
165
+ def function_element_value
166
+ { domain.value => range.value }
167
+ end
168
+ end
169
+
170
+ class RecordElement < NonTerminal
171
+
172
+ def value
173
+ record_element_value
174
+ end
175
+
176
+ def record_element_value
177
+ { element_name.value => element_value.value }
178
+ end
179
+
180
+ end
181
+
182
+ class SequenceValue < CompositeValue
183
+ def value
184
+ sequence_value
185
+ end
186
+
187
+ def sequence_value
188
+ value_childs.map { |n| n.value }
189
+ end
190
+
191
+ end
192
+
193
+
194
+ # @!endgroup
195
+
196
+
197
+ # ------------------------------------------------------------------
198
+ # @!group Atomic values
199
+
200
+ class Name < Terminal
201
+ def value
202
+ name_value
203
+ end
204
+ def name_value
205
+ text_value
206
+ end
207
+ end
208
+
209
+ class LiteralValue < Terminal
210
+ def value
211
+ literal_value
212
+ end
213
+ def literal_value
214
+ text_value
215
+ end
216
+ end
217
+
218
+ class TrueValue < LiteralValue
219
+ def value
220
+ true
221
+ end
222
+ end
223
+
224
+ class FalseValue < LiteralValue
225
+ def value
226
+ false
227
+ end
228
+ end
229
+
230
+ class NilValue < LiteralValue
231
+ def value
232
+ nil
233
+ end
234
+ end
235
+
236
+ class WildCardValue < LiteralValue
237
+ def value
238
+ "*"
239
+ end
240
+ end
241
+
242
+ class StringValue < Terminal
243
+ def value
244
+ str_value
245
+ end
246
+ def str_value
247
+ string_value.text_value
248
+ end
249
+ end
250
+
251
+ class IntegerValue < Terminal
252
+ def value
253
+ int_value
254
+ end
255
+ def int_value
256
+ text_value.to_i
257
+ end
258
+
259
+ end
260
+
261
+
262
+ # @!endgroup
263
+
264
+
265
+ end
266
+ end
267
+ end