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.
- checksums.yaml +7 -0
- data/README.md +75 -0
- data/VERSION +1 -0
- data/bin/tla-resolver.rb +7 -0
- data/lib/cli/cli.rb +90 -0
- data/lib/parser/exception.rb +6 -0
- data/lib/parser/lvalue.rb +63 -0
- data/lib/parser/parser.rb +129 -0
- data/lib/parser/parser_nodes.rb +1063 -0
- data/lib/parser/parser_sexp.treetop +442 -0
- data/lib/semantics/context.rb +355 -0
- data/lib/semantics/exception.rb +13 -0
- data/lib/semantics/resolver.rb +327 -0
- data/lib/semantics/symbol_table.rb +139 -0
- data/lib/tla-parser-s.rb +15 -0
- data/lib/utils/logger.rb +80 -0
- data/lib/utils/syntax_node.rb +73 -0
- data/lib/utils/version.rb +13 -0
- data/spec/fixtures/callables1.tla +64 -0
- data/spec/fixtures/directives.tla +7 -0
- data/spec/fixtures/resolver1/comments.tla +1 -0
- data/spec/fixtures/resolver1/directives.cfg +6 -0
- data/spec/fixtures/resolver1/directives.tla +12 -0
- data/spec/fixtures/resolver1/empty.tla +0 -0
- data/spec/fixtures/resolver1/macro1.tla +3 -0
- data/spec/fixtures/resolver1/macro2.tla +3 -0
- data/spec/fixtures/resolver1/op1.tla +3 -0
- data/spec/fixtures/resolver1/op2.tla +3 -0
- data/spec/fixtures/resolver1/proc1.tla +4 -0
- data/spec/fixtures/resolver1/proc2.tla +7 -0
- data/spec/fixtures/resolver1/proc3.tla +4 -0
- data/spec/fixtures/resolver1/proc4.tla +4 -0
- data/spec/fixtures/resolver1/proc4_hide.tla +4 -0
- data/spec/fixtures/resolver1/proc5.tla +4 -0
- data/spec/fixtures/resolver1/proc6.tla +4 -0
- data/spec/fixtures/resolver1/proc7.tla +4 -0
- data/spec/fixtures/resolver1/stmt_assert.tla +8 -0
- data/spec/fixtures/resolver1/stmt_assign.tla +6 -0
- data/spec/fixtures/resolver1/stmt_assign2.tla +6 -0
- data/spec/fixtures/resolver1/stmt_cond.tla +13 -0
- data/spec/fixtures/resolver1/stmt_either.tla +12 -0
- data/spec/fixtures/resolver1/stmt_print.tla +5 -0
- data/spec/fixtures/resolver1/var4.tla +1 -0
- data/spec/fixtures/resolver1/var5.tla +1 -0
- data/spec/fixtures/resolver1/var_choose_except.tla +2 -0
- data/spec/fixtures/resolver1/var_quantify.tla +4 -0
- data/spec/fixtures/resolver1/var_rec_except.tla +4 -0
- data/spec/fixtures/resolver1/var_rec_expr.tla +3 -0
- data/spec/fixtures/resolver1/var_record.tla +2 -0
- data/spec/fixtures/resolver1/var_seq.tla +1 -0
- data/spec/fixtures/resolver1/var_set.tla +1 -0
- data/spec/fixtures/resolver1/var_set_expr_map.tla +1 -0
- data/spec/fixtures/resolver1/var_x.tla +1 -0
- data/spec/fixtures/resolver1/variables.tla +4 -0
- data/spec/parser/parser_fixtures_spec.rb +117 -0
- data/spec/parser/parser_spec.rb +1649 -0
- data/spec/semantics/context_spec.rb +392 -0
- data/spec/semantics/resolver_spec.rb +364 -0
- data/spec/semantics/symbol_table_spec.rb +144 -0
- data/spec/spec_helper.rb +5 -0
- data/tla-parser-s.gemspec +41 -0
- metadata +153 -0
data/lib/tla-parser-s.rb
ADDED
@@ -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" )
|
data/lib/utils/logger.rb
ADDED
@@ -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 @@
|
|
1
|
+
\* File with just comments
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
var4 = 5
|
@@ -0,0 +1 @@
|
|
1
|
+
var5 = op1
|