sfp 0.3.8 → 0.3.9
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.
- data/README.md +1 -1
- data/VERSION +1 -0
- data/bin/sfp +3 -3
- data/lib/sfp/SfpLangLexer.rb +343 -290
- data/lib/sfp/SfpLangParser.rb +3011 -2980
- data/sfp.gemspec +1 -1
- data/src/SfpLang.g +5 -2
- data/src/compiler.rb +23 -0
- data/src/sfplib.rb +191 -0
- metadata +8 -6
- data/modules/.gitignore +0 -1
data/sfp.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'sfp'
|
3
|
-
s.version =
|
3
|
+
s.version = File.read(File.join(File.dirname(__FILE__), 'VERSION')).sub(/\n/, '')
|
4
4
|
s.date = '2013-08-13'
|
5
5
|
s.summary = 'SFP Parser'
|
6
6
|
s.description = 'A Ruby API and script for SFP language parser'
|
data/src/SfpLang.g
CHANGED
@@ -330,14 +330,17 @@ op_statement
|
|
330
330
|
;
|
331
331
|
|
332
332
|
procedure
|
333
|
-
:
|
333
|
+
: { @synchornized = false }
|
334
|
+
('synchronized' { @synchronized = true })?
|
335
|
+
('procedure'|'sub') ID
|
334
336
|
{
|
335
337
|
@now[$ID.text] = { '_self' => $ID.text,
|
336
338
|
'_context' => 'procedure',
|
337
339
|
'_parent' => @now,
|
338
340
|
'_cost' => 1,
|
339
341
|
'_condition' => { '_context' => 'constraint', '_type' => 'and' },
|
340
|
-
'_effect' => { '_context' => 'effect', '_type' => 'and' }
|
342
|
+
'_effect' => { '_context' => 'effect', '_type' => 'and' },
|
343
|
+
'_synchronized' => @synchronized,
|
341
344
|
}
|
342
345
|
@now = @now[$ID.text]
|
343
346
|
}
|
data/src/compiler.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'sfplib.rb')
|
2
|
+
|
3
|
+
module Sfp::Compiler
|
4
|
+
def to_fdr
|
5
|
+
# TODO -- return FDR representation
|
6
|
+
end
|
7
|
+
|
8
|
+
def variables
|
9
|
+
# TODO -- process variables
|
10
|
+
end
|
11
|
+
|
12
|
+
def goal_state
|
13
|
+
# TODO -- process goal state
|
14
|
+
end
|
15
|
+
|
16
|
+
def initial_state
|
17
|
+
# TODO -- process initial state
|
18
|
+
end
|
19
|
+
|
20
|
+
def procedures
|
21
|
+
# TODO -- process procedures
|
22
|
+
end
|
23
|
+
end
|
data/src/sfplib.rb
ADDED
@@ -0,0 +1,191 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Sfp
|
5
|
+
|
6
|
+
# sfp::undefined
|
7
|
+
Undefined = Object.new
|
8
|
+
def Undefined.to_s
|
9
|
+
'Undefined'
|
10
|
+
end
|
11
|
+
|
12
|
+
# sfp::unknown
|
13
|
+
Unknown = Object.new
|
14
|
+
def Unknown.to_s
|
15
|
+
'Unknown'
|
16
|
+
end
|
17
|
+
|
18
|
+
# method to create a visitor object
|
19
|
+
def visitor
|
20
|
+
object = Object.new
|
21
|
+
def object.set_proc(p)
|
22
|
+
@proc = p
|
23
|
+
end
|
24
|
+
def object.visit(name, value, parent)
|
25
|
+
return false if @proc.nil?
|
26
|
+
@proc.call(name, value, parent)
|
27
|
+
end
|
28
|
+
object.set_proc(block_given? ? Proc.new : nil)
|
29
|
+
object
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
# convert SFP to JSON
|
35
|
+
Hash.send(:define_method, "to_json") {
|
36
|
+
v = visitor { |name,value,parent|
|
37
|
+
parent.delete('_parent') if parent.has_key?('_parent')
|
38
|
+
true
|
39
|
+
}
|
40
|
+
clone = self.deep_clone
|
41
|
+
JSON.generate(clone.accept(v))
|
42
|
+
}
|
43
|
+
|
44
|
+
# deep clone of current Hash
|
45
|
+
Hash.send(:define_method, "deep_clone") {
|
46
|
+
def helper(value)
|
47
|
+
if value.is_a?(Hash)
|
48
|
+
result = value.clone
|
49
|
+
value.each { |k,v|
|
50
|
+
if k != '_parent'
|
51
|
+
result[k] = helper(v)
|
52
|
+
result[k]['_parent'] = result if result[k].is_a?(Hash) and result[k].has_key?('_parent')
|
53
|
+
end
|
54
|
+
}
|
55
|
+
result
|
56
|
+
elsif value.is_a?(Array)
|
57
|
+
result = Array.new
|
58
|
+
value.each { |v| result << helper(v) }
|
59
|
+
result
|
60
|
+
else
|
61
|
+
value
|
62
|
+
end
|
63
|
+
end
|
64
|
+
helper(self)
|
65
|
+
}
|
66
|
+
|
67
|
+
# return the reference of current object
|
68
|
+
Hash.send(:define_method, "ref") {
|
69
|
+
return '$' if !self['_parent'].is_a?(Hash) or !self.has_key?('_self')
|
70
|
+
return "#{self['_parent'].ref}.#{self['_self']}"
|
71
|
+
}
|
72
|
+
|
73
|
+
# accept visitor object - see Visitor pattern
|
74
|
+
Hash.send(:define_method, "accept") { |visitor|
|
75
|
+
if visitor.respond_to?(:visit)
|
76
|
+
self.keys.each do |key|
|
77
|
+
next if key == '_parent' or !self.has_key?(key)
|
78
|
+
value = self[key]
|
79
|
+
value.accept(visitor) if visitor.visit(key, value, self) and value.is_a?(Hash)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
self
|
83
|
+
}
|
84
|
+
|
85
|
+
# return the value of given reference
|
86
|
+
Hash.send(:define_method, "at?") { |ref|
|
87
|
+
return self if ref.nil?
|
88
|
+
return Undefined if !ref.is_a?(String)
|
89
|
+
first, rest = ref.split('.', 2)
|
90
|
+
if first == '$' or first == 'root'
|
91
|
+
self.root.at?(rest)
|
92
|
+
elsif first == 'this' or first == 'self'
|
93
|
+
self.at?(rest)
|
94
|
+
elsif first == 'parent'
|
95
|
+
if !self['_parent'].is_a?(Hash)
|
96
|
+
nil
|
97
|
+
else
|
98
|
+
self['_parent'].at?(rest)
|
99
|
+
end
|
100
|
+
elsif self.has_key?(first)
|
101
|
+
if rest.nil?
|
102
|
+
self[first]
|
103
|
+
elsif self[first].is_a?(Hash)
|
104
|
+
self[first].at?(rest)
|
105
|
+
else
|
106
|
+
Undefined
|
107
|
+
end
|
108
|
+
else
|
109
|
+
Undefined
|
110
|
+
end
|
111
|
+
}
|
112
|
+
|
113
|
+
# return root of given SFP
|
114
|
+
Hash.send(:define_method, "root") {
|
115
|
+
return self if !self.has_key?('_parent') or !self['_parent'].is_a?(Hash)
|
116
|
+
self['_parent'].root
|
117
|
+
}
|
118
|
+
|
119
|
+
Hash.send(:define_method, "is?") { |context|
|
120
|
+
# context => schema, object, constraint, procedure, state
|
121
|
+
(self['_context'] == context)
|
122
|
+
}
|
123
|
+
|
124
|
+
# add path to the end of a reference
|
125
|
+
String.send(:define_method, "push") { |value|
|
126
|
+
return self.to_s + "." + value
|
127
|
+
}
|
128
|
+
|
129
|
+
# return an array of [ parent, last_element ]
|
130
|
+
String.send(:define_method, 'pop') {
|
131
|
+
return self if not self.ref?
|
132
|
+
parts = self.split('.')
|
133
|
+
return self if parts.length <= 1
|
134
|
+
last = parts[ parts.length - 1 ]
|
135
|
+
len = self.length - last.length - 1
|
136
|
+
return [self[0, len], last]
|
137
|
+
}
|
138
|
+
|
139
|
+
# return true if this string is a reference, otherwise false
|
140
|
+
String.send(:define_method, 'ref?') {
|
141
|
+
s = self.to_s
|
142
|
+
return true if (s.length > 0 and s[0,2] == '$.')
|
143
|
+
return false
|
144
|
+
}
|
145
|
+
|
146
|
+
# return true if this is an SFP:Reference
|
147
|
+
String.send(:define_method, 'reference?') {
|
148
|
+
self =~ /^\$\.[a-zA-Z]+(\.[a-zA-Z]+)*$/
|
149
|
+
}
|
150
|
+
|
151
|
+
# return true if this is an SFP:String
|
152
|
+
String.send(:define_method, 'string?') {
|
153
|
+
self =~ /^(?!\$\.).*/
|
154
|
+
}
|
155
|
+
|
156
|
+
# return the prefix of this path
|
157
|
+
# e.g.: if self == 'a.b.c.d', it will return 'a.b.c'
|
158
|
+
String.send(:define_method, 'prefix') {
|
159
|
+
return self if self == '$'
|
160
|
+
parts = self.split('.')
|
161
|
+
return self[0, self.length - parts[parts.length-1].length - 1]
|
162
|
+
}
|
163
|
+
|
164
|
+
# simplify a reference by removing unnecessary 'parent'
|
165
|
+
String.send(:define_method, 'simplify') {
|
166
|
+
return self if not self.ref?
|
167
|
+
ids = self.split('.')
|
168
|
+
i = 0
|
169
|
+
until i >= ids.length do
|
170
|
+
if i >= 3 and ids[i] == 'parent'
|
171
|
+
ids.delete_at(i)
|
172
|
+
ids.delete_at(i-1)
|
173
|
+
i -= 1
|
174
|
+
else
|
175
|
+
i += 1
|
176
|
+
end
|
177
|
+
end
|
178
|
+
ids.join('.')
|
179
|
+
}
|
180
|
+
|
181
|
+
# conversion from JSON to SFP
|
182
|
+
String.send(:define_method, "to_sfp") {
|
183
|
+
v = visitor { |name,value,parent|
|
184
|
+
value['_parent'] = parent if value.is_a?(Hash)
|
185
|
+
true
|
186
|
+
}
|
187
|
+
sfp = JSON[self]
|
188
|
+
sfp.accept(v)
|
189
|
+
}
|
190
|
+
|
191
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sfp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.9
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2013-08-13 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json
|
16
|
-
requirement: &
|
16
|
+
requirement: &15560460 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 1.7.5
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *15560460
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: antlr3
|
27
|
-
requirement: &
|
27
|
+
requirement: &15559300 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: 1.9.0
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *15559300
|
36
36
|
description: A Ruby API and script for SFP language parser
|
37
37
|
email: herry13@gmail.com
|
38
38
|
executables:
|
@@ -43,6 +43,7 @@ files:
|
|
43
43
|
- .gitignore
|
44
44
|
- LICENSE
|
45
45
|
- README.md
|
46
|
+
- VERSION
|
46
47
|
- bin/sfp
|
47
48
|
- lib/sfp.rb
|
48
49
|
- lib/sfp/SfpLangLexer.rb
|
@@ -53,11 +54,12 @@ files:
|
|
53
54
|
- lib/sfp/sfw2graph.rb
|
54
55
|
- lib/sfp/trollop.rb
|
55
56
|
- lib/sfp/visitors.rb
|
56
|
-
- modules/.gitignore
|
57
57
|
- sfp.gemspec
|
58
58
|
- src/SfpLang.g
|
59
59
|
- src/SfpLang.g.bak
|
60
60
|
- src/build.sh
|
61
|
+
- src/compiler.rb
|
62
|
+
- src/sfplib.rb
|
61
63
|
homepage: https://github.com/herry13/sfp-ruby
|
62
64
|
licenses:
|
63
65
|
- BSD
|
data/modules/.gitignore
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
*
|