tla-parser-s 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +75 -0
  3. data/VERSION +1 -0
  4. data/bin/tla-resolver.rb +7 -0
  5. data/lib/cli/cli.rb +90 -0
  6. data/lib/parser/exception.rb +6 -0
  7. data/lib/parser/lvalue.rb +63 -0
  8. data/lib/parser/parser.rb +129 -0
  9. data/lib/parser/parser_nodes.rb +1063 -0
  10. data/lib/parser/parser_sexp.treetop +442 -0
  11. data/lib/semantics/context.rb +355 -0
  12. data/lib/semantics/exception.rb +13 -0
  13. data/lib/semantics/resolver.rb +327 -0
  14. data/lib/semantics/symbol_table.rb +139 -0
  15. data/lib/tla-parser-s.rb +15 -0
  16. data/lib/utils/logger.rb +80 -0
  17. data/lib/utils/syntax_node.rb +73 -0
  18. data/lib/utils/version.rb +13 -0
  19. data/spec/fixtures/callables1.tla +64 -0
  20. data/spec/fixtures/directives.tla +7 -0
  21. data/spec/fixtures/resolver1/comments.tla +1 -0
  22. data/spec/fixtures/resolver1/directives.cfg +6 -0
  23. data/spec/fixtures/resolver1/directives.tla +12 -0
  24. data/spec/fixtures/resolver1/empty.tla +0 -0
  25. data/spec/fixtures/resolver1/macro1.tla +3 -0
  26. data/spec/fixtures/resolver1/macro2.tla +3 -0
  27. data/spec/fixtures/resolver1/op1.tla +3 -0
  28. data/spec/fixtures/resolver1/op2.tla +3 -0
  29. data/spec/fixtures/resolver1/proc1.tla +4 -0
  30. data/spec/fixtures/resolver1/proc2.tla +7 -0
  31. data/spec/fixtures/resolver1/proc3.tla +4 -0
  32. data/spec/fixtures/resolver1/proc4.tla +4 -0
  33. data/spec/fixtures/resolver1/proc4_hide.tla +4 -0
  34. data/spec/fixtures/resolver1/proc5.tla +4 -0
  35. data/spec/fixtures/resolver1/proc6.tla +4 -0
  36. data/spec/fixtures/resolver1/proc7.tla +4 -0
  37. data/spec/fixtures/resolver1/stmt_assert.tla +8 -0
  38. data/spec/fixtures/resolver1/stmt_assign.tla +6 -0
  39. data/spec/fixtures/resolver1/stmt_assign2.tla +6 -0
  40. data/spec/fixtures/resolver1/stmt_cond.tla +13 -0
  41. data/spec/fixtures/resolver1/stmt_either.tla +12 -0
  42. data/spec/fixtures/resolver1/stmt_print.tla +5 -0
  43. data/spec/fixtures/resolver1/var4.tla +1 -0
  44. data/spec/fixtures/resolver1/var5.tla +1 -0
  45. data/spec/fixtures/resolver1/var_choose_except.tla +2 -0
  46. data/spec/fixtures/resolver1/var_quantify.tla +4 -0
  47. data/spec/fixtures/resolver1/var_rec_except.tla +4 -0
  48. data/spec/fixtures/resolver1/var_rec_expr.tla +3 -0
  49. data/spec/fixtures/resolver1/var_record.tla +2 -0
  50. data/spec/fixtures/resolver1/var_seq.tla +1 -0
  51. data/spec/fixtures/resolver1/var_set.tla +1 -0
  52. data/spec/fixtures/resolver1/var_set_expr_map.tla +1 -0
  53. data/spec/fixtures/resolver1/var_x.tla +1 -0
  54. data/spec/fixtures/resolver1/variables.tla +4 -0
  55. data/spec/parser/parser_fixtures_spec.rb +117 -0
  56. data/spec/parser/parser_spec.rb +1649 -0
  57. data/spec/semantics/context_spec.rb +392 -0
  58. data/spec/semantics/resolver_spec.rb +364 -0
  59. data/spec/semantics/symbol_table_spec.rb +144 -0
  60. data/spec/spec_helper.rb +5 -0
  61. data/tla-parser-s.gemspec +41 -0
  62. metadata +153 -0
@@ -0,0 +1,15 @@
1
+ #
2
+
3
+ # open Treetop::Runner::SyntaxNode
4
+ require_relative( "utils/syntax_node" )
5
+
6
+ require_relative( "utils/logger" )
7
+ require_relative( "utils/version" )
8
+
9
+ require_relative( "parser/exception" )
10
+ require_relative( "parser/parser" )
11
+
12
+ require_relative( "semantics/exception" )
13
+ require_relative( "semantics/symbol_table" )
14
+ require_relative( "semantics/context" )
15
+ require_relative( "semantics/resolver" )
@@ -0,0 +1,80 @@
1
+ require 'logger'
2
+
3
+ # see http://hawkins.io/2013/08/using-the-ruby-logger/
4
+
5
+ module TlaParserS
6
+
7
+ module Utils
8
+
9
+ module MyLogger
10
+
11
+ # no logging done
12
+
13
+ class NullLoger < Logger
14
+ def initialize(*args)
15
+ end
16
+
17
+ def add(*args, &block)
18
+ end
19
+
20
+ def debug?
21
+ false
22
+ end
23
+ end
24
+
25
+ @@logfile = nil # absolute path to log file
26
+ LOGFILE="tla-parser-s.log"
27
+
28
+ def logfile( options )
29
+ return @@logfile if @@logfile
30
+ @@logfile = options[:logfile] || File.join( Dir.getwd, LOGFILE )
31
+ end
32
+
33
+ def getLogger( progname, options={} )
34
+
35
+ level = get_level( options )
36
+
37
+ if level.nil?
38
+
39
+ return NullLoger.new
40
+
41
+ else
42
+
43
+ logger = Logger.new( logfile( options ) )
44
+ logger.level=level
45
+ logger.progname = progname
46
+ return logger
47
+
48
+ end
49
+
50
+ end # getLogger
51
+
52
+ # ------------------------------------------------------------------
53
+ private
54
+
55
+ def get_level( options )
56
+
57
+ # puts "#{__method__}: options=#{options}"
58
+
59
+ level_name = options && options[:log] ? options[:log] : ENV['LOG_LEVEL']
60
+
61
+ level = case level_name
62
+ when 'warn', 'WARN'
63
+ Logger::WARN
64
+ when 'info', 'INFO'
65
+ Logger::INFO
66
+ when 'debug', 'DEBUG'
67
+ Logger::DEBUG
68
+ when 'error', 'ERROR'
69
+ Logger::ERROR
70
+ else
71
+ nil
72
+ end
73
+
74
+ return level
75
+ end
76
+
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1,73 @@
1
+ module Treetop
2
+
3
+ module Runtime
4
+
5
+ class SyntaxNode
6
+
7
+ # @return [String] name of syntax node (as bare class name)
8
+ def node_type
9
+ self.class.name.split('::').last
10
+ end
11
+
12
+ # To abstact
13
+ # @return [String|Array|Hash] of node value
14
+ def node_value
15
+ text_value
16
+ end
17
+
18
+ # Default implementation of syntax node value (override in
19
+ # sub-classes)
20
+ #
21
+ # @return [String] value representeation of the node
22
+ def value
23
+ {
24
+ :node_type => node_type,
25
+ :value => node_value,
26
+ }
27
+ end
28
+
29
+
30
+ # http://www.rubydoc.info/gems/logstash-core/1.5.2.2/Treetop/Runtime/SyntaxNode
31
+ def recursive_inject_parent(results=[], &block)
32
+ if !parent.nil?
33
+ if block.call(parent)
34
+ results << parent
35
+ else
36
+ parent.recursive_inject_parent(results, &block)
37
+ end
38
+ end
39
+ return results
40
+ end
41
+
42
+ # Traverse the syntax tree recursively. The order should respect
43
+ # the order of the configuration file as it is read and written by
44
+ # humans (and the order in which it is parsed).
45
+ def recursive_inject(results=[], deep=false, &block)
46
+ if !elements.nil?
47
+ elements.each do |element|
48
+ if block.call(element)
49
+ results << element
50
+ if deep
51
+ element.recursive_inject(results, deep, &block)
52
+ end
53
+ else
54
+ element.recursive_inject(results, &block)
55
+ end
56
+ end
57
+ end
58
+ return results
59
+ end
60
+
61
+ # When Treetop parses the configuration file it will generate a
62
+ # tree, the generated tree will contain a few `Empty` nodes to
63
+ # represent the actual space/tab or newline in the file. Some of
64
+ # theses node will point to our concrete class. To fetch a
65
+ # specific types of object we need to follow each branch and
66
+ # ignore the empty nodes.
67
+ def recursive_select(klass, deep=false)
68
+ return recursive_inject([], deep ) { |e| e.is_a?(klass) }
69
+ end
70
+
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,13 @@
1
+ module TlaParserS
2
+
3
+
4
+ def self.version
5
+ File.readlines( File.join File.dirname( __FILE__ ), "../../VERSION" ).first.gsub( /\n/, "" )
6
+ end
7
+
8
+ def self.model_version
9
+ return File.readlines( "VERSION" ).first.gsub( /\n/, "" ) if File.exist?( "VERSION" )
10
+ return "Model version file #{Dir.pwd}/VERSION not found"
11
+ end
12
+
13
+ end
@@ -0,0 +1,64 @@
1
+ \* line
2
+
3
+ macro macroid1( m1_p1, m1_p2 )
4
+ {
5
+ skip;
6
+
7
+ };
8
+
9
+ \* this is the second macro
10
+ macro macroid2( macro2_a, macro2_b) {
11
+
12
+
13
+ skip;
14
+
15
+ }
16
+
17
+ (* ******************************************************************
18
+ This is comment containing macro3, which is not included into
19
+ n parse tree - because it is commented
20
+
21
+ macro macroid3( macro3_a, macro3_b) {
22
+
23
+
24
+ skip;
25
+
26
+ }
27
+
28
+ ******************************************************************)
29
+
30
+
31
+
32
+ ItWorks == TRUE
33
+
34
+ ItCalls == ItWorks( 1 )
35
+
36
+
37
+ (* ******************************************************************
38
+ Define procedures
39
+ ******************************************************************)
40
+
41
+ procedure proc0( ) {
42
+ skip;
43
+ }
44
+
45
+
46
+ procedure proc1( a ) {
47
+ skip;
48
+ }
49
+
50
+ procedure proc2( a,b ) {
51
+ skip;
52
+ }
53
+
54
+
55
+
56
+ (* ******************************************************************
57
+ Variables
58
+ ******************************************************************)
59
+
60
+ a = 1
61
+
62
+ b = { a \in Set: TRUE }
63
+
64
+ c = {}
@@ -0,0 +1,7 @@
1
+ ASSUME Assume_Domains
2
+
3
+ ASSUME a2 a3
4
+
5
+ INVARIANT i1
6
+
7
+ INVARIANT i2 i3
@@ -0,0 +1 @@
1
+ \* File with just comments
@@ -0,0 +1,6 @@
1
+ ASSUME a1 a2
2
+
3
+ INVARIANT i1
4
+
5
+
6
+
@@ -0,0 +1,12 @@
1
+ a1 == TRUE
2
+
3
+ a2 == FALSE
4
+
5
+ i1 == TRUE /\ a1
6
+
7
+
8
+
9
+
10
+
11
+
12
+
File without changes
@@ -0,0 +1,3 @@
1
+ macro macro1() {
2
+ }
3
+
@@ -0,0 +1,3 @@
1
+ macro macro2() {
2
+ }
3
+
@@ -0,0 +1,3 @@
1
+ op1 == TRUE \/ FALSE
2
+
3
+
@@ -0,0 +1,3 @@
1
+ op2 == TRUE \/ FALSE
2
+
3
+
@@ -0,0 +1,4 @@
1
+ procedure proc1( a ) {
2
+ macro1( a );
3
+ }
4
+
@@ -0,0 +1,7 @@
1
+ procedure proc2() {
2
+
3
+ macro1( );
4
+ macro2();
5
+ call proc1();
6
+ }
7
+
@@ -0,0 +1,4 @@
1
+ procedure proc3( a ) {
2
+ macro1( var1, op1 );
3
+ }
4
+
@@ -0,0 +1,4 @@
1
+ procedure proc4( a ) {
2
+ call proc4( var4 );
3
+ }
4
+
@@ -0,0 +1,4 @@
1
+ procedure proc4_hide( var4 ) {
2
+ call proc4_hide( var4 );
3
+ }
4
+
@@ -0,0 +1,4 @@
1
+ procedure proc5( a ) {
2
+ call proc5( var5 );
3
+ }
4
+
@@ -0,0 +1,4 @@
1
+ procedure proc6( a ) {
2
+ call proc7( a, unkown_variable );
3
+ }
4
+
@@ -0,0 +1,4 @@
1
+ procedure proc7( a ) {
2
+ call proc6( a );
3
+ }
4
+
@@ -0,0 +1,8 @@
1
+ \*
2
+ procedure stmt_assert( id_type ) {
3
+
4
+ assert( x = id_type );
5
+
6
+ }
7
+
8
+
@@ -0,0 +1,6 @@
1
+ macro assignit( local ) {
2
+
3
+ var1.a := var4;
4
+
5
+ }
6
+
@@ -0,0 +1,6 @@
1
+ macro assignit2( local ) {
2
+
3
+ var5[x] := var4;
4
+
5
+ }
6
+
@@ -0,0 +1,13 @@
1
+ \*
2
+ procedure stmt_cond( id_type ) {
3
+
4
+ \* var4 := id_type;
5
+
6
+ if ( var4[ id_type ] = 0 ) {
7
+ x := TRUE;
8
+ }
9
+ else
10
+ var5 := FALSE;
11
+ }
12
+
13
+
@@ -0,0 +1,12 @@
1
+ \*
2
+ procedure stmt_either( id_type ) {
3
+
4
+ either {
5
+ var4 := TRUE;
6
+ } or {
7
+ var5 := FALSE;
8
+ };
9
+
10
+ }
11
+
12
+
@@ -0,0 +1,5 @@
1
+ macro printit( local ) {
2
+
3
+ print <<var1,local, op2(var4)>>;
4
+ }
5
+
@@ -0,0 +1 @@
1
+ var4 = 5
@@ -0,0 +1 @@
1
+ var5 = op1
@@ -0,0 +1,2 @@
1
+ var_choose_except = CHOOSE x \in Set : op1( x, var4 )
2
+
@@ -0,0 +1,4 @@
1
+ var_quantify = \A a \in op1( var4 ): TRUE
2
+
3
+
4
+