tla-parser-s 0.1.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/VERSION +1 -1
- data/lib/parser/parser_nodes.rb +104 -8
- data/lib/parser/parser_sexp.treetop +51 -9
- data/lib/semantics/context.rb +42 -5
- data/lib/semantics/resolver.rb +3 -1
- data/spec/fixtures/resolver1/op3.tla +1 -0
- data/spec/fixtures/resolver1/proc10.tla +8 -0
- data/spec/fixtures/resolver1/proc8.tla +6 -0
- data/spec/fixtures/resolver1/proc9.tla +6 -0
- data/spec/fixtures/resolver1/set_constrcutore.tla +1 -0
- data/spec/fixtures/resolver1/var_if.tla +3 -0
- data/spec/fixtures/resolver1/var_if_no_else.tla +3 -0
- data/spec/fixtures/resolver1/var_rec_except2.tla +4 -0
- data/spec/parser/parser_spec.rb +145 -2
- data/spec/semantics/context_spec.rb +65 -0
- data/spec/semantics/resolver_spec.rb +44 -2
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f9d948ffca5a15da6675b14f14e17e5181615d2b
|
4
|
+
data.tar.gz: cbbb074f624f0afbc29a579bb0fe7a4afa5d3c9d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 502e237ae5b32370fbfe1df73231fb90f56f7659a3af762442764d6f8e7de1ae6fa578a3872379f394ecdb549aaceb5f19f345a426b81b312f422bd763c766d6
|
7
|
+
data.tar.gz: f54fe71c01a2f878f322afe41c79ac1a621ecc92b599e8359c80032d48e5fadae43c1d89da9faa9bb8b10c794028669314a020487b4f8c58c971e883f7deedda
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
[Up](../index.php) [Readme](README.html) [Releases](RELEASES.html) [Todo](TODO.html)
|
3
3
|
|
4
4
|
|
5
|
-
# tla-parser-s - TLA+ language parser (for tla-sbuilder) - $Release:0.1.
|
5
|
+
# tla-parser-s - TLA+ language parser (for tla-sbuilder) - $Release:0.1.2$
|
6
6
|
|
7
7
|
A Ruby library for parsing
|
8
8
|
[TLA+ language](http://research.microsoft.com/en-us/um/people/lamport/tla/book.html).
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.2
|
data/lib/parser/parser_nodes.rb
CHANGED
@@ -80,6 +80,13 @@ module Sexp
|
|
80
80
|
class Parameters <IdentifierList
|
81
81
|
end
|
82
82
|
|
83
|
+
class ProcVariables <IdentifierList
|
84
|
+
def identifier_nodes
|
85
|
+
recursive_select( Sexp::VariableDef).first.recursive_select( Sexp::Identifier )
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
83
90
|
|
84
91
|
|
85
92
|
class ExpressionList <Root
|
@@ -315,6 +322,37 @@ module Sexp
|
|
315
322
|
end
|
316
323
|
|
317
324
|
end
|
325
|
+
|
326
|
+
class IfExpressionCondition < Root
|
327
|
+
end
|
328
|
+
class IfExpressionThen < Root
|
329
|
+
end
|
330
|
+
class IfExpressionElse < Root
|
331
|
+
end
|
332
|
+
class IfExpression < SimpleExpression
|
333
|
+
|
334
|
+
# Node for condition
|
335
|
+
# @return [Expression] for IF condition
|
336
|
+
def condition_node
|
337
|
+
recursive_select( Sexp::IfExpressionCondition ).first.recursive_select(Sexp::Expression).first
|
338
|
+
end
|
339
|
+
|
340
|
+
# @return [Expression] for THEN expression
|
341
|
+
def then_expression_node
|
342
|
+
recursive_select( Sexp::IfExpressionThen ).first.recursive_select(Sexp::Expression).first end
|
343
|
+
|
344
|
+
# @return [Expression] for ELSE expression
|
345
|
+
def else_expression_node
|
346
|
+
tree_node = recursive_select( Sexp::IfExpressionElse ).first
|
347
|
+
return tree_node unless tree_node
|
348
|
+
tree_node.recursive_select(Sexp::Expression).first
|
349
|
+
end
|
350
|
+
|
351
|
+
def name
|
352
|
+
'IF'
|
353
|
+
end
|
354
|
+
|
355
|
+
end
|
318
356
|
|
319
357
|
class ChooseExpression < SimpleExpression
|
320
358
|
|
@@ -440,8 +478,8 @@ module Sexp
|
|
440
478
|
def expression_val
|
441
479
|
"exprsssion"
|
442
480
|
end
|
443
|
-
def
|
444
|
-
recursive_select( Sexp::
|
481
|
+
def record_base
|
482
|
+
recursive_select( Sexp::RecordExcepBase ).first.recursive_select( Sexp::Expression ).first
|
445
483
|
end
|
446
484
|
def record_field_definitions
|
447
485
|
# rigth recursion results to empty RecordExceptField -node
|
@@ -459,7 +497,7 @@ module Sexp
|
|
459
497
|
end
|
460
498
|
end
|
461
499
|
|
462
|
-
class
|
500
|
+
class RecordExcepBase < Root
|
463
501
|
end
|
464
502
|
|
465
503
|
|
@@ -532,6 +570,7 @@ module Sexp
|
|
532
570
|
end
|
533
571
|
end
|
534
572
|
|
573
|
+
|
535
574
|
class AbstractSetExpression < AbstactExpression
|
536
575
|
# AbstactExpression.traverse quit traversing the expression
|
537
576
|
def lhs_node
|
@@ -564,6 +603,12 @@ module Sexp
|
|
564
603
|
ret
|
565
604
|
end
|
566
605
|
|
606
|
+
# Elements defined on constructore
|
607
|
+
def set_elements
|
608
|
+
elems = recursive_select( Sexp::Expression )
|
609
|
+
elems
|
610
|
+
end
|
611
|
+
|
567
612
|
# For documentation purposes symbol table context needs a name
|
568
613
|
# (For procedures, and macros name is ovbious. For a set
|
569
614
|
# expression we define name set a string "Set+<generator set>"
|
@@ -576,7 +621,7 @@ module Sexp
|
|
576
621
|
# variable defined in set constructor generate. Return name of
|
577
622
|
# this variables.
|
578
623
|
#
|
579
|
-
# @return [Array]
|
624
|
+
# @return [Hash:Array] with :node_type,:value, :tree -properties
|
580
625
|
def symbol_definitions
|
581
626
|
return [] unless binds_node
|
582
627
|
[ { :node_type => node_type, :value => binds_node.bind_var.expression_val, :tree=>binds_node } ]
|
@@ -590,6 +635,9 @@ module Sexp
|
|
590
635
|
class SetExpression < AbstractSetExpression
|
591
636
|
end
|
592
637
|
|
638
|
+
class SetConstructor < AbstractSetExpression
|
639
|
+
end
|
640
|
+
|
593
641
|
class FieldBy < AbstactExpression
|
594
642
|
# AbstractExpression.traverse - do not recurse will evaluate separetetely
|
595
643
|
def lhs_node
|
@@ -602,6 +650,8 @@ module Sexp
|
|
602
650
|
|
603
651
|
end
|
604
652
|
|
653
|
+
|
654
|
+
|
605
655
|
class FieldByName < FieldBy
|
606
656
|
|
607
657
|
# @return [AbstactExpression] defining the name
|
@@ -963,6 +1013,7 @@ module Sexp
|
|
963
1013
|
node = parameters_node
|
964
1014
|
return node.value if node
|
965
1015
|
end
|
1016
|
+
|
966
1017
|
|
967
1018
|
def body_node
|
968
1019
|
ret = recursive_select(Sexp::Statement).first
|
@@ -981,21 +1032,60 @@ module Sexp
|
|
981
1032
|
}
|
982
1033
|
end
|
983
1034
|
|
984
|
-
# Symbols defined in this node
|
985
1035
|
#
|
986
|
-
# @return [Hash:Array] symbol hash with ':node_type', :value
|
987
|
-
|
988
|
-
def symbol_definitions
|
1036
|
+
# @return [Hash:Array] symbol hash with ':node_type', :value,:tree properties
|
1037
|
+
def parameter_definitions
|
989
1038
|
parameter_def = parameters
|
990
1039
|
return [] unless parameter_def
|
991
1040
|
parameter_def[:value]
|
992
1041
|
end
|
1042
|
+
|
1043
|
+
def declaration_definitions
|
1044
|
+
[]
|
1045
|
+
end
|
1046
|
+
|
1047
|
+
# Symbols defined in this node. They include parameters
|
1048
|
+
# and declarations (normally only in procedure)
|
1049
|
+
def symbol_definitions
|
1050
|
+
# unique b
|
1051
|
+
return parameter_definitions + declaration_definitions
|
1052
|
+
end
|
1053
|
+
|
993
1054
|
end
|
994
1055
|
|
995
1056
|
class Macro < Callable
|
996
1057
|
end
|
997
1058
|
|
998
1059
|
class Procedure < Callable
|
1060
|
+
|
1061
|
+
# @return [Nil|ProcVariables] of variable definition node for procedure
|
1062
|
+
def procedure_variables_node
|
1063
|
+
tree_nodes = recursive_select(Sexp::ProcVariables)
|
1064
|
+
return tree_nodes.first if tree_nodes
|
1065
|
+
end
|
1066
|
+
|
1067
|
+
# @return [VariableDef:Array] variable declarations
|
1068
|
+
def variable_declarations
|
1069
|
+
return [] unless procedure_variables_node
|
1070
|
+
return procedure_variables_node.recursive_select(Sexp::VariableDef)
|
1071
|
+
end
|
1072
|
+
|
1073
|
+
def procedure_variables
|
1074
|
+
# node = procedure_variables_node
|
1075
|
+
# return node.value if node
|
1076
|
+
variable_declarations.map { |variable_declaration| variable_declaration.variable.value }
|
1077
|
+
end
|
1078
|
+
|
1079
|
+
|
1080
|
+
# overrides method in parent to return decclartions in
|
1081
|
+
# @return [VariableDef:Array] of variable definition, empty array if no definition
|
1082
|
+
def declaration_definitions
|
1083
|
+
declaration_def = procedure_variables
|
1084
|
+
return [] unless declaration_def.any?
|
1085
|
+
declaration_def
|
1086
|
+
end
|
1087
|
+
|
1088
|
+
|
999
1089
|
end
|
1000
1090
|
|
1001
1091
|
class OperatorDef < Callable
|
@@ -1016,6 +1106,12 @@ module Sexp
|
|
1016
1106
|
def name
|
1017
1107
|
recursive_select(Sexp::Identifier).first.node_value
|
1018
1108
|
end
|
1109
|
+
|
1110
|
+
# @return [Identifier] tree node for variable defined
|
1111
|
+
def variable
|
1112
|
+
tree_nodes = recursive_select(Sexp::Identifier).first
|
1113
|
+
end
|
1114
|
+
|
1019
1115
|
|
1020
1116
|
# @return [Expression] tree node for init expression
|
1021
1117
|
def init
|
@@ -40,9 +40,16 @@ rule callable
|
|
40
40
|
end
|
41
41
|
|
42
42
|
rule procedure
|
43
|
+
'procedure' space? identifier ( '(' space? identifier_list? ')' <Parameters> ) space* procedure_variables? &'{' statement space* ';'? <Procedure>
|
44
|
+
end
|
45
|
+
|
43
46
|
|
44
|
-
|
47
|
+
rule procedure_variables
|
48
|
+
('variable' / 'variables') space* procedure_variable_decl (procedure_variables_tail* <NonTerminal>) ';' space* <ProcVariables>
|
49
|
+
end
|
45
50
|
|
51
|
+
rule procedure_variables_tail
|
52
|
+
',' space* procedure_variable_decl <NonTerminal>
|
46
53
|
end
|
47
54
|
|
48
55
|
rule macro
|
@@ -122,8 +129,9 @@ rule primary_expression
|
|
122
129
|
unit_expression space* ( unit_expression_tail* <UnitExpression> ) <PrimaryExpression>
|
123
130
|
end
|
124
131
|
|
132
|
+
|
125
133
|
rule unit_expression
|
126
|
-
sequence_expression / set_expression / set_expression_map / record_expression / operator_expression / quantify_expression / choose_expression
|
134
|
+
sequence_expression / set_expression / set_expression_map / set_constructor / record_expression / operator_expression / quantify_expression / choose_expression / if_expression
|
127
135
|
/ identifier
|
128
136
|
/ record_self
|
129
137
|
/ original_value
|
@@ -144,10 +152,11 @@ end
|
|
144
152
|
|
145
153
|
|
146
154
|
rule record_expression
|
147
|
-
&( '[' space*
|
155
|
+
&( '[' space* record_expression_base 'EXCEPT' ) '[' space* record_except ']' <RecordExcept>
|
148
156
|
/ '[' space? record_expression_element? ']' <RecordDefinition>
|
149
157
|
end
|
150
158
|
|
159
|
+
|
151
160
|
rule record_expression_element
|
152
161
|
|
153
162
|
( identifier space? '|->' space? expression <RecordElement>) space? record_expression_element_tail? <NonTerminal>
|
@@ -159,9 +168,14 @@ rule record_expression_element_tail
|
|
159
168
|
end
|
160
169
|
|
161
170
|
rule record_except
|
162
|
-
(
|
171
|
+
( record_expression_base 'EXCEPT' <RecordExcepBase>) space* (lvalue space* '=' space* expression space* <RecordExceptField>) ( record_except_tail* <RecordExceptField>) <NonTerminal>
|
172
|
+
end
|
173
|
+
|
174
|
+
rule record_expression_base
|
175
|
+
expression space* <NonTerminal>
|
163
176
|
end
|
164
177
|
|
178
|
+
|
165
179
|
rule record_except_tail
|
166
180
|
',' space* lvalue space* '=' space* expression <Root>
|
167
181
|
end
|
@@ -171,7 +185,15 @@ rule choose_expression
|
|
171
185
|
'CHOOSE' space* bound_expression space* ':' space* expression <ChooseExpression>
|
172
186
|
|
173
187
|
end
|
174
|
-
|
188
|
+
|
189
|
+
rule if_expression
|
190
|
+
'IF' (space* expression <IfExpressionCondition> ) space* 'THEN' (space* expression <IfExpressionThen>) if_expression_else? <IfExpression>
|
191
|
+
end
|
192
|
+
|
193
|
+
rule if_expression_else
|
194
|
+
'ELSE' space* expression <IfExpressionElse>
|
195
|
+
end
|
196
|
+
|
175
197
|
rule quantify_expression
|
176
198
|
quantify_operator space? ( quantify_expression_bound+ <BindsInExpression>) ':' space? space? expression <QuantifyExpression>
|
177
199
|
end
|
@@ -193,8 +215,13 @@ rule set_expression_map
|
|
193
215
|
|
194
216
|
end
|
195
217
|
|
218
|
+
|
196
219
|
rule set_expression
|
197
|
-
'{' space* ( bound_expression ':' space* <BoundInExpression> )
|
220
|
+
'{' space* ( bound_expression ':' space* <BoundInExpression> ) (space* expression? <SetExpressionDef>) '}' <SetExpression>
|
221
|
+
end
|
222
|
+
|
223
|
+
rule set_constructor
|
224
|
+
'{' space* expression_list? space* '}' space* <SetConstructor>
|
198
225
|
end
|
199
226
|
|
200
227
|
rule bound_expression
|
@@ -215,7 +242,7 @@ end
|
|
215
242
|
# unlabeled statements
|
216
243
|
|
217
244
|
rule unlabeled_statement
|
218
|
-
|
245
|
+
assignment_statement / compound_statement / either / conditional / macro_call / return_statement / skip / assert / goto / print / call
|
219
246
|
end
|
220
247
|
|
221
248
|
rule conditional
|
@@ -281,16 +308,31 @@ rule call
|
|
281
308
|
end
|
282
309
|
|
283
310
|
rule skip
|
284
|
-
'skip'
|
311
|
+
'skip' <Skip>
|
285
312
|
end
|
286
313
|
|
287
314
|
# ------------------------------------------------------------------
|
288
315
|
# variable
|
289
316
|
|
290
317
|
rule variable
|
291
|
-
|
318
|
+
variable_decl_with_init ';'? <VariableDef>
|
292
319
|
end
|
293
320
|
|
321
|
+
rule procedure_variable_decl
|
322
|
+
variable_decl_with_init / variable_decl_without_init
|
323
|
+
end
|
324
|
+
|
325
|
+
|
326
|
+
rule variable_decl_with_init
|
327
|
+
identifier space* '=' space? expression space* <VariableDef>
|
328
|
+
end
|
329
|
+
|
330
|
+
rule variable_decl_without_init
|
331
|
+
identifier space* <VariableDef>
|
332
|
+
end
|
333
|
+
|
334
|
+
|
335
|
+
|
294
336
|
|
295
337
|
# ------------------------------------------------------------------
|
296
338
|
# elementary
|
data/lib/semantics/context.rb
CHANGED
@@ -197,16 +197,33 @@ module TlaParserS
|
|
197
197
|
# @return see 'resolveStatement'
|
198
198
|
def resolveDefine( defineNode )
|
199
199
|
# @logger.debug "resolveDefine starting callable=#{defineNode.inspect}"
|
200
|
-
|
200
|
+
|
201
|
+
ret = nil
|
201
202
|
pushContext( defineNode )
|
202
203
|
# dumpContext
|
203
204
|
if defineNode.respond_to?( :body_node ) then
|
205
|
+
# macro, procedure, operatordef
|
204
206
|
@logger.info( "#{__method__} start with resolveStatement for #{defineNode.body_node}" )
|
205
207
|
if defineNode.body_node.is_a?(Sexp::Expression)
|
208
|
+
# operator
|
206
209
|
ret = resolveExpression( defineNode.body_node )
|
207
210
|
else
|
211
|
+
# macro, procedure
|
208
212
|
ret = resolveStatement( defineNode.body_node )
|
209
213
|
end
|
214
|
+
# resolve expressions initializing variable declarations
|
215
|
+
if defineNode.respond_to?(:variable_declarations)
|
216
|
+
sret = []
|
217
|
+
defineNode.variable_declarations.each do |variable_declaration|
|
218
|
+
sret = sret.concat( resolveExpression( variable_declaration.init ))
|
219
|
+
end
|
220
|
+
# add resolved symbols from declaration init only if symbol
|
221
|
+
# not already resolved
|
222
|
+
sret.each do |s|
|
223
|
+
ret << s unless ret.map { |r| r[:symbol] }.include?( s[:symbol])
|
224
|
+
end
|
225
|
+
end
|
226
|
+
# puts "sret found=#{sret}, ret=#{ret}" if sret.any?
|
210
227
|
elsif defineNode.respond_to?( :init ) then
|
211
228
|
@logger.info( "#{__method__} start with resolveExpression #{defineNode.init}" )
|
212
229
|
ret = resolveExpression( defineNode.init )
|
@@ -255,6 +272,18 @@ module TlaParserS
|
|
255
272
|
sret = sret.concat( resolveExpression( tuple_expr ))
|
256
273
|
end
|
257
274
|
ret = ret.concat( sret )
|
275
|
+
when "IfExpression"
|
276
|
+
@logger.debug( "#{__method__} IfExpression: enode=#{enode.inspect}" )
|
277
|
+
sret = resolveExpression( enode.condition_node )
|
278
|
+
ret.concat( sret )
|
279
|
+
@logger.info( "#{__method__} IfExpression: condition-expr=#{sret}" )
|
280
|
+
sret = resolveExpression( enode.then_expression_node )
|
281
|
+
ret.concat( sret )
|
282
|
+
@logger.info( "#{__method__} IfExpression: then-expr=#{sret}" )
|
283
|
+
sret = []
|
284
|
+
sret = resolveExpression( enode.else_expression_node ) if enode.else_expression_node
|
285
|
+
ret.concat( sret )
|
286
|
+
@logger.info( "#{__method__} IfExpression: els-expr=#{sret}" )
|
258
287
|
when "ChooseExpression"
|
259
288
|
@logger.debug( "#{__method__} ChooseExpression: enode=#{enode.inspect}" )
|
260
289
|
@logger.debug( "#{__method__} ChooseExpression: enode.binds_node=#{enode.binds_node}" )
|
@@ -275,16 +304,24 @@ module TlaParserS
|
|
275
304
|
@logger.info( "#{__method__} RecordDefinition: resolved sret=#{sret.map {|e| { e[:symbol] => e[:resolved] ? e[:resolved][:symbol_type]+':'+e[:resolved][:context] : nil} }}" )
|
276
305
|
ret = ret.concat( sret )
|
277
306
|
when "RecordExcept"
|
278
|
-
# resolve where
|
279
|
-
id = enode.record_identifier
|
280
|
-
ret << resolvedIdentifier( id, symbol_table.resolveContext( id ) )
|
281
|
-
|
307
|
+
# resolve where base expression
|
308
|
+
# id = enode.record_identifier
|
309
|
+
# ret << resolvedIdentifier( id, symbol_table.resolveContext( id ) )
|
310
|
+
bret = resolveExpression( enode.record_base )
|
311
|
+
ret = ret.concat( bret )
|
312
|
+
@logger.debug( "#{__method__} RecordExcept: record_base -->=#{bret}" )
|
282
313
|
sret = []
|
283
314
|
# resolve EXCEPT constructor field rvalue expression
|
284
315
|
enode.record_field_definitions && enode.record_field_definitions.each do |field_definition|
|
285
316
|
sret = sret.concat( resolveExpression( field_definition.rvalue_expression ))
|
286
317
|
end
|
287
318
|
ret = ret.concat( sret )
|
319
|
+
when "SetConstructor"
|
320
|
+
sret = []
|
321
|
+
enode.set_elements && enode.set_elements.each do |set_element|
|
322
|
+
sret = sret.concat( resolveExpression( set_element ))
|
323
|
+
end
|
324
|
+
ret = ret.concat( sret )
|
288
325
|
when "SetExpressionMap"
|
289
326
|
@logger.debug( "#{__method__} SetExpressionMap: enode=#{enode.inspect}" )
|
290
327
|
# resolve set mapped
|
data/lib/semantics/resolver.rb
CHANGED
@@ -207,10 +207,12 @@ module TlaParserS
|
|
207
207
|
break if unResolved.empty?
|
208
208
|
# next to resolve
|
209
209
|
entryPoint = unResolved.to_a.shift
|
210
|
+
@logger.info( "#{__method__} next to resolve entryPoint #{entryPoint} " )
|
211
|
+
next if resolved.include?( entryPoint )
|
210
212
|
|
211
213
|
# array of hashes how entry point is resolved
|
212
214
|
resolvedSymbols = resolveEntryPoint( entryPoint )
|
213
|
-
@logger.
|
215
|
+
@logger.info( "#{__method__} entryPoint #{entryPoint} ->resolvedSymbols=#{resolvedSymbols}" )
|
214
216
|
|
215
217
|
resolvedModules = # array of mod.names
|
216
218
|
resolvedSymbols. # { :symbol=>, :resolved=> }
|
@@ -0,0 +1 @@
|
|
1
|
+
op3 == op2 \/ op1
|
@@ -0,0 +1 @@
|
|
1
|
+
set_constrcutore = { 1, "Hello", var4 }
|
data/spec/parser/parser_spec.rb
CHANGED
@@ -125,7 +125,8 @@ describe TlaParserS::Parser do
|
|
125
125
|
rvalue_expression = field_node.rvalue_expression.traverse { |m, node_type, enode, node_val| m.concat( expression_value(node_type, enode, node_val )) }
|
126
126
|
elements << "#{lvalue_expression}=#{rvalue_expression}"
|
127
127
|
end
|
128
|
-
|
128
|
+
record_base = node.record_base.traverse { |m, node_type, enode, node_val| m.concat( expression_value(node_type, enode, node_val )) }
|
129
|
+
ret = "[#{record_base} EXCEPT #{elements.join(',')}]"
|
129
130
|
# puts "RecordExcept=>#{ret}"
|
130
131
|
ret
|
131
132
|
when "RecordDefinition"
|
@@ -149,7 +150,14 @@ describe TlaParserS::Parser do
|
|
149
150
|
# puts "SetExpression: bind_var=#{bind_var}"
|
150
151
|
|
151
152
|
return "{#{set_expression}: #{bind_var} \\in #{bind_set}}"
|
152
|
-
|
153
|
+
|
154
|
+
when "SetConstructor"
|
155
|
+
set_elements = []
|
156
|
+
node.set_elements && node.set_elements.each do |set_element|
|
157
|
+
set_elements << set_element.traverse { |m, node_type, enode, node_val| m.concat( expression_value(node_type, enode, node_val )) }
|
158
|
+
end
|
159
|
+
# puts "SetConstructor: set_elements=#{set_elements}"
|
160
|
+
"{#{ set_elements.join(',')}}"
|
153
161
|
when "SetExpression"
|
154
162
|
set_expression = nil
|
155
163
|
bind_var = nil
|
@@ -191,6 +199,11 @@ describe TlaParserS::Parser do
|
|
191
199
|
|
192
200
|
"#{node_val}(#{arguments.join(',')})#{ record_field ? "." + record_field : ''}"
|
193
201
|
|
202
|
+
when "IfExpression"
|
203
|
+
condition_expression = node.condition_node.traverse { |m, node_type, enode, node_val| m.concat( expression_value(node_type, enode, node_val )) }
|
204
|
+
then_expression = node.then_expression_node.traverse { |m, node_type, enode, node_val| m.concat( expression_value(node_type, enode, node_val )) }
|
205
|
+
else_expression = node.else_expression_node && node.else_expression_node.traverse { |m, node_type, enode, node_val| m.concat( expression_value(node_type, enode, node_val )) }
|
206
|
+
"IF #{condition_expression} THEN #{then_expression}#{ else_expression ? ' ELSE ' + else_expression : ''}"
|
194
207
|
when "ChooseExpression"
|
195
208
|
bind_set = node.binds_node.bind_set.traverse { |m, node_type, enode, node_val| m.concat( expression_value(node_type, enode, node_val )) }
|
196
209
|
bind_var = node.binds_node.bind_var.node_value
|
@@ -644,6 +657,7 @@ describe TlaParserS::Parser do
|
|
644
657
|
:expect => "macro1()",
|
645
658
|
},
|
646
659
|
|
660
|
+
|
647
661
|
{
|
648
662
|
:str => "macro2( 1,A )",
|
649
663
|
:desc => "macro call with actual parameters",
|
@@ -652,6 +666,69 @@ describe TlaParserS::Parser do
|
|
652
666
|
:exception => nil,
|
653
667
|
:expect => "macro2(1,A)",
|
654
668
|
},
|
669
|
+
|
670
|
+
{
|
671
|
+
:str => 'return_error(1,A)',
|
672
|
+
:desc => "macro starting with reserved word 'return'",
|
673
|
+
:debug => false,
|
674
|
+
:start => :statement,
|
675
|
+
:exception => nil,
|
676
|
+
:expect => "return_error(1,A)",
|
677
|
+
},
|
678
|
+
|
679
|
+
{
|
680
|
+
:str => 'skip_error(1,A)',
|
681
|
+
:desc => "macro starting with reserved word 'skip'",
|
682
|
+
:debug => false,
|
683
|
+
:start => :statement,
|
684
|
+
:exception => nil,
|
685
|
+
:expect => "skip_error(1,A)",
|
686
|
+
},
|
687
|
+
|
688
|
+
{
|
689
|
+
:str => 'assert_error(1,A)',
|
690
|
+
:desc => "macro starting with reserved word 'assert'",
|
691
|
+
:debug => false,
|
692
|
+
:start => :statement,
|
693
|
+
:exception => nil,
|
694
|
+
:expect => "assert_error(1,A)",
|
695
|
+
},
|
696
|
+
|
697
|
+
{
|
698
|
+
:str => 'goto_error(1,A)',
|
699
|
+
:desc => "macro starting with reserved word 'goto'",
|
700
|
+
:debug => false,
|
701
|
+
:start => :statement,
|
702
|
+
:exception => nil,
|
703
|
+
:expect => "goto_error(1,A)",
|
704
|
+
},
|
705
|
+
|
706
|
+
{
|
707
|
+
:str => 'print_error(1,A)',
|
708
|
+
:desc => "macro starting with reserved word 'print'",
|
709
|
+
:debug => false,
|
710
|
+
:start => :statement,
|
711
|
+
:exception => nil,
|
712
|
+
:expect => "print_error(1,A)",
|
713
|
+
},
|
714
|
+
|
715
|
+
{
|
716
|
+
:str => 'call_error(1,A)',
|
717
|
+
:desc => "macro starting with reserved word 'call'",
|
718
|
+
:debug => false,
|
719
|
+
:start => :statement,
|
720
|
+
:exception => nil,
|
721
|
+
:expect => "call_error(1,A)",
|
722
|
+
},
|
723
|
+
|
724
|
+
{
|
725
|
+
:str => 'either_error(1,A)',
|
726
|
+
:desc => "macro starting with reserved word 'either'",
|
727
|
+
:debug => false,
|
728
|
+
:start => :statement,
|
729
|
+
:exception => nil,
|
730
|
+
:expect => "either_error(1,A)",
|
731
|
+
},
|
655
732
|
|
656
733
|
{
|
657
734
|
:str => "print 1",
|
@@ -1059,6 +1136,21 @@ describe TlaParserS::Parser do
|
|
1059
1136
|
:expect => '{1}',
|
1060
1137
|
},
|
1061
1138
|
|
1139
|
+
{
|
1140
|
+
:str => '{ 1, 2 }',
|
1141
|
+
:desc => "Set two integer elements",
|
1142
|
+
:start => :expression,
|
1143
|
+
:debug => false,
|
1144
|
+
:expect => '{1,2}',
|
1145
|
+
},
|
1146
|
+
|
1147
|
+
{
|
1148
|
+
:str => '{ 1, "hello", A }',
|
1149
|
+
:desc => "Set constrcutor with integer, string, identifier",
|
1150
|
+
:start => :expression,
|
1151
|
+
:debug => false,
|
1152
|
+
:expect => '{1,"hello",A}',
|
1153
|
+
},
|
1062
1154
|
|
1063
1155
|
{
|
1064
1156
|
:str => '{ x \in Set: TRUE }',
|
@@ -1243,6 +1335,14 @@ describe TlaParserS::Parser do
|
|
1243
1335
|
:expect => '[v_ids EXCEPT ![id]=a]',
|
1244
1336
|
},
|
1245
1337
|
|
1338
|
+
{
|
1339
|
+
:str => '[ op(TRUE) EXCEPT ![id] = a ] ',
|
1340
|
+
:desc => "Record except using operator",
|
1341
|
+
:start => :expression,
|
1342
|
+
:debug => false,
|
1343
|
+
:expect => '[op(TRUE) EXCEPT ![id]=a]',
|
1344
|
+
},
|
1345
|
+
|
1246
1346
|
{
|
1247
1347
|
:str => '[ v_ids EXCEPT ![id] = a ] . fiildi [ aa ] ',
|
1248
1348
|
:desc => "Record except with record access)",
|
@@ -1293,6 +1393,22 @@ describe TlaParserS::Parser do
|
|
1293
1393
|
:expect => 'CHOOSE x \in t_Owner: 1+2',
|
1294
1394
|
},
|
1295
1395
|
|
1396
|
+
{
|
1397
|
+
:str => 'IF 1=2 THEN FALSE ELSE TRUE',
|
1398
|
+
:desc => "IF expression",
|
1399
|
+
:start => :expression,
|
1400
|
+
:debug => false,
|
1401
|
+
:expect => 'IF 1=2 THEN FALSE ELSE TRUE',
|
1402
|
+
},
|
1403
|
+
|
1404
|
+
{
|
1405
|
+
:str => 'IF 1=2 THEN (2=2)',
|
1406
|
+
:desc => "IF expression no elese",
|
1407
|
+
:start => :expression,
|
1408
|
+
:debug => false,
|
1409
|
+
:expect => 'IF 1=2 THEN (2=2)',
|
1410
|
+
},
|
1411
|
+
|
1296
1412
|
{
|
1297
1413
|
:str => 'elementti \in Set',
|
1298
1414
|
:desc => "Expr in setup ",
|
@@ -1532,6 +1648,16 @@ describe TlaParserS::Parser do
|
|
1532
1648
|
:expect => "1",
|
1533
1649
|
},
|
1534
1650
|
|
1651
|
+
{
|
1652
|
+
:str => "a = id",
|
1653
|
+
:desc => "Init to identitifer",
|
1654
|
+
:start => :variable,
|
1655
|
+
:exception => nil,
|
1656
|
+
:debug => false,
|
1657
|
+
:expect => "id",
|
1658
|
+
},
|
1659
|
+
|
1660
|
+
|
1535
1661
|
].each_with_index do |testCase,i|
|
1536
1662
|
|
1537
1663
|
it "#Case #{i}: #{testCase[:desc]} - parse '#{testCase[:str]}' starting '#{testCase[:start]}'" do
|
@@ -1541,6 +1667,7 @@ describe TlaParserS::Parser do
|
|
1541
1667
|
puts tree.inspect
|
1542
1668
|
end
|
1543
1669
|
expect( tree ).not_to eql( nil ) unless testCase[:exception]
|
1670
|
+
|
1544
1671
|
expect( tree.init.traverse { |memo, node_type, enode, node_val|
|
1545
1672
|
memo.concat( expression_value( node_type, enode, node_val ))
|
1546
1673
|
} ).to eql( testCase[:expect] )
|
@@ -1570,6 +1697,22 @@ describe TlaParserS::Parser do
|
|
1570
1697
|
:debug => false,
|
1571
1698
|
:expect => true,
|
1572
1699
|
},
|
1700
|
+
{
|
1701
|
+
:str => "procedure proc(a) variable a=0; {}",
|
1702
|
+
:desc => "Procedure with variable ",
|
1703
|
+
:start => :procedure,
|
1704
|
+
:exception => nil,
|
1705
|
+
:debug => false,
|
1706
|
+
:expect => true,
|
1707
|
+
},
|
1708
|
+
{
|
1709
|
+
:str => "procedure proc(a,b) variable v1=0,v2; {}",
|
1710
|
+
:desc => "Procedure with two variables",
|
1711
|
+
:start => :procedure,
|
1712
|
+
:exception => nil,
|
1713
|
+
:debug => false,
|
1714
|
+
:expect => true,
|
1715
|
+
},
|
1573
1716
|
{
|
1574
1717
|
:str => "procedure id(){}",
|
1575
1718
|
:desc => "Procedure ",
|
@@ -233,7 +233,72 @@ describe TlaParserS::Context do
|
|
233
233
|
:expect => [{"proc1" => "Procedure:Snippets" }, { "macro1" => "Macro:Snippets" } ],
|
234
234
|
},
|
235
235
|
|
236
|
+
{
|
237
|
+
:initialContext => [
|
238
|
+
<<-EOS,
|
239
|
+
procedure proc1() {}
|
240
|
+
macro macro1() {}
|
241
|
+
op1 == TRUE
|
242
|
+
EOS
|
243
|
+
],
|
244
|
+
:callable => "procedure procci() variable a=0; { call proc1( a ); macro1(); }",
|
245
|
+
:start => :procedure,
|
246
|
+
:desc => "Call proc, call macro, procedure variable decl with init",
|
247
|
+
:debug => false,
|
248
|
+
:expect_synopsis =>"Resolved in base context definitions ",
|
249
|
+
:expect => [{"proc1" => "Procedure:Snippets" }, {"a"=>"Identifier:procci"}, { "macro1" => "Macro:Snippets" } ],
|
250
|
+
},
|
251
|
+
|
252
|
+
|
253
|
+
{
|
254
|
+
:initialContext => [
|
255
|
+
<<-EOS,
|
256
|
+
procedure proc1() {}
|
257
|
+
macro macro1() {}
|
258
|
+
op1 == TRUE
|
259
|
+
EOS
|
260
|
+
],
|
261
|
+
:callable => "procedure procci() variable a, b=0; { call proc1( a ); macro1(); }",
|
262
|
+
:start => :procedure,
|
263
|
+
:desc => "Call proc, call macro, procedure variable decl without init",
|
264
|
+
:debug => false,
|
265
|
+
:expect_synopsis =>"Resolved in base context definitions ",
|
266
|
+
:expect => [{"proc1" => "Procedure:Snippets" }, {"a"=>"Identifier:procci"}, { "macro1" => "Macro:Snippets" } ],
|
267
|
+
},
|
268
|
+
|
269
|
+
{
|
270
|
+
:initialContext => [
|
271
|
+
<<-EOS,
|
272
|
+
procedure proc1() {}
|
273
|
+
macro macro1() {}
|
274
|
+
op1 == TRUE
|
275
|
+
b=1;
|
276
|
+
EOS
|
277
|
+
],
|
278
|
+
:callable => "procedure procci() variable a=b; { call proc1( a ); macro1(); }",
|
279
|
+
:start => :procedure,
|
280
|
+
:desc => "Call proc, call macro, procedure variable declaration with init",
|
281
|
+
:debug => false,
|
282
|
+
:expect_synopsis =>"Resolved in base context definitions ",
|
283
|
+
:expect => [{"proc1" => "Procedure:Snippets" }, {"a"=>"Identifier:procci"}, { "macro1" => "Macro:Snippets" }, { "b" => "VariableDef:Snippets" } ],
|
284
|
+
},
|
236
285
|
|
286
|
+
{
|
287
|
+
:initialContext => [
|
288
|
+
<<-EOS,
|
289
|
+
procedure proc1() {}
|
290
|
+
macro macro1() {}
|
291
|
+
op1 == TRUE
|
292
|
+
b=1;
|
293
|
+
EOS
|
294
|
+
],
|
295
|
+
:callable => "procedure procci() variable a=b,c; { call proc1( a ); macro1(b); }",
|
296
|
+
:start => :procedure,
|
297
|
+
:desc => "Call proc, call macro, procedure variable declaration with init",
|
298
|
+
:debug => false,
|
299
|
+
:expect_synopsis =>"Resolved in base context definitions ",
|
300
|
+
:expect => [{"proc1" => "Procedure:Snippets" }, {"a"=>"Identifier:procci"}, { "macro1" => "Macro:Snippets" }, { "b" => "VariableDef:Snippets" } ],
|
301
|
+
},
|
237
302
|
{
|
238
303
|
:initialContext => [
|
239
304
|
<<-EOS,
|
@@ -91,13 +91,13 @@ describe TlaParserS::Resolver do
|
|
91
91
|
:entrypoints => ["proc3"],
|
92
92
|
:expect => [ "proc3.tla", "macro1.tla", "variables.tla", "op1.tla", "directives.tla", "directives.cfg" ]
|
93
93
|
},
|
94
|
-
|
94
|
+
|
95
95
|
{
|
96
96
|
:desc => "Proc4 uses var4",
|
97
97
|
:entrypoints => ["proc4"],
|
98
98
|
:expect => [ "proc4.tla", "var4.tla", "directives.tla", "directives.cfg" ]
|
99
99
|
},
|
100
|
-
|
100
|
+
|
101
101
|
{
|
102
102
|
:desc => "Proc4_hide uses var4 -as formal parametr",
|
103
103
|
:entrypoints => ["proc4_hide"],
|
@@ -116,6 +116,24 @@ describe TlaParserS::Resolver do
|
|
116
116
|
:expect => [ "proc7.tla", "proc6.tla", "directives.tla", "directives.cfg" ]
|
117
117
|
},
|
118
118
|
|
119
|
+
{
|
120
|
+
:desc => "proc8 (with variable declaration)",
|
121
|
+
:entrypoints => ["proc8"],
|
122
|
+
:expect => [ "proc8.tla", "proc1.tla", "directives.tla", "macro1.tla", "directives.cfg" ]
|
123
|
+
},
|
124
|
+
|
125
|
+
{
|
126
|
+
:desc => "proc9 (with variable declaration with init)",
|
127
|
+
:entrypoints => ["proc9"],
|
128
|
+
:expect => [ "proc9.tla", "proc1.tla", "op1.tla", "directives.tla", "macro1.tla", "directives.cfg" ]
|
129
|
+
},
|
130
|
+
|
131
|
+
{
|
132
|
+
:desc => "proc10 (with two variable declaration with init)",
|
133
|
+
:entrypoints => ["proc10"],
|
134
|
+
:expect => [ "proc10.tla", "proc1.tla", "op3.tla", "directives.tla", "macro1.tla", "op2.tla", "op1.tla", "directives.cfg" ]
|
135
|
+
},
|
136
|
+
|
119
137
|
{
|
120
138
|
:desc => "Loop proc6->proc7",
|
121
139
|
:entrypoints => ["proc6"],
|
@@ -158,12 +176,36 @@ describe TlaParserS::Resolver do
|
|
158
176
|
:expect => [ "var_rec_except.tla", "var5.tla", "op1.tla", "directives.tla", "directives.cfg" ]
|
159
177
|
},
|
160
178
|
|
179
|
+
{
|
180
|
+
:desc => "Record except with base expression",
|
181
|
+
:entrypoints => ["var_rec_except2"],
|
182
|
+
:expect => [ "var_rec_except2.tla", "op2.tla", "var5.tla", "op1.tla", "directives.tla", "directives.cfg" ]
|
183
|
+
},
|
184
|
+
|
161
185
|
{
|
162
186
|
:desc => "Choose x in Set:",
|
163
187
|
:entrypoints => ["var_choose_except"],
|
164
188
|
:expect => [ "var_choose_except.tla", "op1.tla", "var4.tla", "directives.tla", "directives.cfg" ]
|
165
189
|
},
|
166
190
|
|
191
|
+
{
|
192
|
+
:desc => "var = IF THEN ELSE :",
|
193
|
+
:entrypoints => ["var_if"],
|
194
|
+
:expect => [ "var_if.tla", "op1.tla", "var4.tla", "var5.tla", "directives.tla", "directives.cfg" ]
|
195
|
+
},
|
196
|
+
|
197
|
+
{
|
198
|
+
:desc => "var = IF THEN :",
|
199
|
+
:entrypoints => ["var_if_no_else"],
|
200
|
+
:expect => [ "var_if_no_else.tla", "op1.tla", "var4.tla","directives.tla", "directives.cfg" ]
|
201
|
+
},
|
202
|
+
|
203
|
+
{
|
204
|
+
:desc => "Set constructore:",
|
205
|
+
:entrypoints => ["set_constrcutore"],
|
206
|
+
:expect => [ "set_constrcutore.tla", "var4.tla", "directives.tla", "directives.cfg" ]
|
207
|
+
},
|
208
|
+
|
167
209
|
{
|
168
210
|
:desc => "Record exression",
|
169
211
|
:entrypoints => ["var_rec_expr"],
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tla-parser-s
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jarjuk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-05-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -92,7 +92,9 @@ files:
|
|
92
92
|
- spec/fixtures/resolver1/macro2.tla
|
93
93
|
- spec/fixtures/resolver1/op1.tla
|
94
94
|
- spec/fixtures/resolver1/op2.tla
|
95
|
+
- spec/fixtures/resolver1/op3.tla
|
95
96
|
- spec/fixtures/resolver1/proc1.tla
|
97
|
+
- spec/fixtures/resolver1/proc10.tla
|
96
98
|
- spec/fixtures/resolver1/proc2.tla
|
97
99
|
- spec/fixtures/resolver1/proc3.tla
|
98
100
|
- spec/fixtures/resolver1/proc4.tla
|
@@ -100,6 +102,9 @@ files:
|
|
100
102
|
- spec/fixtures/resolver1/proc5.tla
|
101
103
|
- spec/fixtures/resolver1/proc6.tla
|
102
104
|
- spec/fixtures/resolver1/proc7.tla
|
105
|
+
- spec/fixtures/resolver1/proc8.tla
|
106
|
+
- spec/fixtures/resolver1/proc9.tla
|
107
|
+
- spec/fixtures/resolver1/set_constrcutore.tla
|
103
108
|
- spec/fixtures/resolver1/stmt_assert.tla
|
104
109
|
- spec/fixtures/resolver1/stmt_assign.tla
|
105
110
|
- spec/fixtures/resolver1/stmt_assign2.tla
|
@@ -109,8 +114,11 @@ files:
|
|
109
114
|
- spec/fixtures/resolver1/var4.tla
|
110
115
|
- spec/fixtures/resolver1/var5.tla
|
111
116
|
- spec/fixtures/resolver1/var_choose_except.tla
|
117
|
+
- spec/fixtures/resolver1/var_if.tla
|
118
|
+
- spec/fixtures/resolver1/var_if_no_else.tla
|
112
119
|
- spec/fixtures/resolver1/var_quantify.tla
|
113
120
|
- spec/fixtures/resolver1/var_rec_except.tla
|
121
|
+
- spec/fixtures/resolver1/var_rec_except2.tla
|
114
122
|
- spec/fixtures/resolver1/var_rec_expr.tla
|
115
123
|
- spec/fixtures/resolver1/var_record.tla
|
116
124
|
- spec/fixtures/resolver1/var_seq.tla
|