sfp 0.3.5 → 0.3.6
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 +2 -2
- data/bin/sfp +8 -2
- data/lib/sfp/SfpLangLexer.rb +340 -372
- data/lib/sfp/SfpLangParser.rb +4065 -3960
- data/lib/sfp/Sfplib.rb +32 -31
- data/lib/sfp/parser.rb +43 -129
- data/lib/sfp/sas_translator.rb +25 -28
- data/sfp.gemspec +3 -3
- data/src/SfpLang.g +52 -39
- metadata +18 -8
data/lib/sfp/Sfplib.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
module Sfp
|
2
2
|
module SfpLangHelper
|
3
|
-
attr_accessor :root_dir, :home_dir
|
3
|
+
attr_accessor :root_dir, :home_dir, :constraint_next_id
|
4
4
|
attr_reader :root, :used_classes, :arrays, :conformant
|
5
5
|
|
6
6
|
def init
|
7
7
|
@root = Hash.new
|
8
8
|
@now = @root
|
9
|
-
@id = 0
|
10
9
|
@root['Object'] = { '_self' => 'Object', '_context' => 'class', '_parent' => @root }
|
11
10
|
@unexpanded_classes = Array.new
|
12
11
|
@used_classes = Array.new
|
@@ -15,8 +14,8 @@ module Sfp
|
|
15
14
|
end
|
16
15
|
|
17
16
|
def next_id
|
18
|
-
nid = "c"
|
19
|
-
@
|
17
|
+
nid = "c#{@constraint_next_id}"
|
18
|
+
@constraint_next_id += 1
|
20
19
|
return nid
|
21
20
|
end
|
22
21
|
|
@@ -48,25 +47,25 @@ module Sfp
|
|
48
47
|
|
49
48
|
raise Exception, 'File not found: ' + file if not File.exist?(filepath)
|
50
49
|
|
51
|
-
|
52
|
-
|
50
|
+
parser = Sfp::Parser.new({ :root_dir => @root_dir,
|
51
|
+
:home_dir => File.expand_path(File.dirname(filepath)),
|
52
|
+
:constraint_next_id => @constraint_next_id })
|
53
53
|
parser.parse(File.read(filepath))
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
if @root[key]['_context'] != val['_context']
|
61
|
-
@root[key] = val
|
62
|
-
else
|
63
|
-
val['_context'].each_pair { |k2,v2| @root[key][k2] = v2 }
|
64
|
-
end
|
54
|
+
parser.root.each_pair do |key,val|
|
55
|
+
if val.is_a?(Hash)
|
56
|
+
if val['_context'] == 'state' and @root.has_key?(key) and @root[key]['_context'] == 'state'
|
57
|
+
val.each_pair { |k2,v2| @root[key][k2] = v2 if k2[0,1] != '_' }
|
58
|
+
elsif val['_context'] == 'constraint' and @root.has_key?(key) and @root[key]['_context'] == 'constraint'
|
59
|
+
val.each_pair { |k2,v2| @root[key][k2] = v2 if k2[0,1] != '_' }
|
65
60
|
else
|
66
61
|
@root[key] = val
|
62
|
+
val['_parent'] = @root if val['_context'] != 'state'
|
67
63
|
end
|
64
|
+
else
|
65
|
+
@root[key] = val
|
68
66
|
end
|
69
|
-
|
67
|
+
end
|
68
|
+
@constraint_next_id = parser.constraint_next_id
|
70
69
|
end
|
71
70
|
|
72
71
|
def goto_parent(remove_parent=false)
|
@@ -76,20 +75,22 @@ module Sfp
|
|
76
75
|
return n
|
77
76
|
end
|
78
77
|
|
79
|
-
def
|
80
|
-
@
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
if
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
c['_finals'] = sclass['_finals']
|
90
|
-
end
|
78
|
+
def expand_class(c)
|
79
|
+
sclass = @root.at?(c['_extends'])
|
80
|
+
c.inherits( sclass )
|
81
|
+
c['_super'] = (sclass.has_key?('_super') ? sclass['_super'].clone : Array.new)
|
82
|
+
c['_super'] << c['_extends']
|
83
|
+
if sclass['_finals'].is_a?(Array)
|
84
|
+
if c['_finals'].is_a?(Array)
|
85
|
+
c['_finals'].concat(sclass['_finals'])
|
86
|
+
else
|
87
|
+
c['_finals'] = sclass['_finals']
|
91
88
|
end
|
92
|
-
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def expand_classes
|
93
|
+
@unexpanded_classes.each { |c| expand_class(c) }
|
93
94
|
end
|
94
95
|
|
95
96
|
def expand_object(obj)
|
data/lib/sfp/parser.rb
CHANGED
@@ -1,136 +1,50 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
class
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
# @param string : a string in SFP language
|
23
|
-
def parse(string)
|
24
|
-
lexer = SfpLang::Lexer.new(string)
|
25
|
-
tokens = ANTLR3::CommonTokenStream.new(lexer)
|
26
|
-
parser = SfpLang::Parser.new(tokens)
|
27
|
-
parser.root_dir = @root_dir
|
28
|
-
parser.home_dir = @home_dir
|
29
|
-
parser.sfp
|
30
|
-
@root = parser.root
|
31
|
-
@conformant = parser.conformant
|
32
|
-
@parser_arrays = parser.arrays
|
33
|
-
end
|
34
|
-
|
35
|
-
def to_json(params={})
|
36
|
-
return 'null' if @root.nil?
|
37
|
-
return Sfp::Helper.to_pretty_json(@root) if params[:pretty]
|
38
|
-
return Sfp::Helper.to_json(@root)
|
39
|
-
end
|
40
|
-
|
41
|
-
def self.parse_file(filepath)
|
42
|
-
homedir = File.expand_path(File.dirname(filepath))
|
43
|
-
parser = Sfp::Parser.new({:home_dir => homedir})
|
44
|
-
parser.parse(File.read(filepath))
|
45
|
-
parser.root
|
46
|
-
end
|
47
|
-
|
48
|
-
=begin
|
49
|
-
# Parse SFP file and return its JSON representation
|
50
|
-
def self.parse_file(file)
|
51
|
-
return file_to_sfp(file)
|
52
|
-
end
|
53
|
-
|
54
|
-
def self.file_to_sfp(file)
|
55
|
-
parser = Parser.new
|
56
|
-
parser.parse_file(file)
|
57
|
-
return parser.to_sfp
|
58
|
-
end
|
59
|
-
|
60
|
-
def self.to_sfp(string)
|
61
|
-
parser = Parser.new
|
62
|
-
parser.parse(string)
|
63
|
-
return parser.to_sfp
|
64
|
-
end
|
65
|
-
|
66
|
-
# parse SFP file
|
67
|
-
def parse_file(file)
|
68
|
-
f = File.open(file, 'rb')
|
69
|
-
lexer = SFP::Lexer.new(f)
|
70
|
-
tokens = ANTLR3::CommonTokenStream.new(lexer)
|
71
|
-
parser = SFP::Parser.new(tokens)
|
72
|
-
parser.root_dir = (@root_dir == nil or @root_dir == '' ?
|
73
|
-
File.expand_path('.') : @root_dir)
|
74
|
-
parser.home_dir = File.dirname(f.path)
|
75
|
-
parser.sfp
|
76
|
-
@conformant = parser.conformant
|
77
|
-
@root = parser.root
|
78
|
-
@parser_arrays = parser.arrays
|
79
|
-
end
|
80
|
-
|
81
|
-
# parse SFP in a string
|
82
|
-
def parse(text)
|
83
|
-
lexer = SFP::Lexer.new(text)
|
84
|
-
tokens = ANTLR3::CommonTokenStream.new(lexer)
|
85
|
-
parser = SFP::Parser.new(tokens)
|
86
|
-
parser.root_dir = (@root_dir == nil or @root_dir == '' ?
|
87
|
-
File.expand_path(File.dirname('.')) : @root_dir)
|
88
|
-
parser.home_dir = parser.root_dir
|
89
|
-
parser.sfp
|
90
|
-
@root = parser.root
|
91
|
-
@parser_arrays = parser.arrays
|
92
|
-
end
|
93
|
-
|
94
|
-
# dump the parsed specification into standard output
|
95
|
-
def dump(root=nil)
|
96
|
-
return if root == nil
|
97
|
-
root = Nuri::Sfp.deep_clone(@root)
|
98
|
-
root.accept(ParentEliminator.new)
|
99
|
-
puts JSON.pretty_generate(root)
|
100
|
-
end
|
101
|
-
|
102
|
-
def self.dump(root)
|
103
|
-
return if root == nil
|
104
|
-
root = Nuri::Sfp.deep_clone(root)
|
105
|
-
root.accept(ParentEliminator.new)
|
106
|
-
puts JSON.pretty_generate(root)
|
107
|
-
end
|
108
|
-
|
109
|
-
def to_sfp
|
110
|
-
@root
|
111
|
-
end
|
112
|
-
|
113
|
-
def to_json
|
114
|
-
root = self.to_sfp
|
115
|
-
return if root == nil
|
116
|
-
root = Nuri::Sfp.deep_clone(root)
|
117
|
-
return Nuri::Sfp.to_json(root)
|
118
|
-
end
|
119
|
-
=end
|
1
|
+
# main class which processes configuration description in SFP language either
|
2
|
+
# in file or as a string
|
3
|
+
class Sfp::Parser
|
4
|
+
# enable this class to process SFP into FDR (SAS+)
|
5
|
+
include Sfp::SasTranslator
|
6
|
+
|
7
|
+
attr_accessor :root_dir, :home_dir, :conformant
|
8
|
+
attr_reader :root, :constraint_next_id
|
9
|
+
|
10
|
+
def initialize(params={})
|
11
|
+
@root_dir = (params[:root_dir].is_a?(String) ?
|
12
|
+
params[:root_dir].strip :
|
13
|
+
nil)
|
14
|
+
@home_dir = (params[:home_dir].is_a?(String) ?
|
15
|
+
params[:home_dir].strip :
|
16
|
+
nil)
|
17
|
+
@root = params[:root]
|
18
|
+
@conformant = !!params[:conformant]
|
19
|
+
@constraint_next_id = (params[:constraint_next_id] ? params[:constraint_next_id] : 0)
|
120
20
|
end
|
121
21
|
|
122
|
-
|
123
|
-
def
|
124
|
-
|
125
|
-
|
126
|
-
|
22
|
+
# @param string : a string in SFP language
|
23
|
+
def parse(string, options={})
|
24
|
+
lexer = SfpLang::Lexer.new(string)
|
25
|
+
tokens = ANTLR3::CommonTokenStream.new(lexer)
|
26
|
+
parser = SfpLang::Parser.new(tokens)
|
27
|
+
parser.root_dir = @root_dir
|
28
|
+
parser.home_dir = @home_dir
|
29
|
+
parser.constraint_next_id = @constraint_next_id
|
30
|
+
parser.sfp
|
31
|
+
@constraint_next_id = parser.constraint_next_id
|
32
|
+
@root = parser.root
|
33
|
+
@conformant = parser.conformant
|
34
|
+
@parser_arrays = parser.arrays
|
127
35
|
end
|
128
36
|
|
129
|
-
def
|
130
|
-
|
131
|
-
|
132
|
-
return
|
37
|
+
def to_json(params={})
|
38
|
+
return 'null' if @root.nil?
|
39
|
+
return Sfp::Helper.to_pretty_json(@root) if params[:pretty]
|
40
|
+
return Sfp::Helper.to_json(@root)
|
133
41
|
end
|
134
|
-
=end
|
135
42
|
|
43
|
+
def self.parse_file(filepath, options={})
|
44
|
+
#homedir = File.expand_path(File.dirname(filepath))
|
45
|
+
options[:home_dir] = File.expand_path(File.dirname(filepath)) if !options[:home_dir]
|
46
|
+
parser = Sfp::Parser.new(options) #{:home_dir => homedir})
|
47
|
+
parser.parse(File.read(filepath))
|
48
|
+
parser.root
|
49
|
+
end
|
136
50
|
end
|
data/lib/sfp/sas_translator.rb
CHANGED
@@ -162,15 +162,11 @@ module Sfp
|
|
162
162
|
end
|
163
163
|
|
164
164
|
### process all procedures
|
165
|
-
@variables.each_value
|
165
|
+
@variables.each_value do |var|
|
166
166
|
if var.is_final
|
167
|
-
var.init.each { |k,v|
|
168
|
-
if v.is_a?(Hash) and v.isprocedure
|
169
|
-
process_procedure(v, var.init)
|
170
|
-
end
|
171
|
-
}
|
167
|
+
var.init.each { |k,v| process_procedure(v, var.init) if v.is_a?(Hash) and v.isprocedure }
|
172
168
|
end
|
173
|
-
|
169
|
+
end
|
174
170
|
self.reset_operators_name
|
175
171
|
|
176
172
|
### process sometime modalities ###
|
@@ -304,7 +300,7 @@ module Sfp
|
|
304
300
|
postprocess_simple_global_constraint_to_operator(operator).each { |op|
|
305
301
|
@operators[op.name] = op
|
306
302
|
}
|
307
|
-
end
|
303
|
+
end if @operators.is_a?(Hash)
|
308
304
|
end
|
309
305
|
|
310
306
|
def postprocess_simple_global_constraint_to_operator(operator)
|
@@ -701,12 +697,10 @@ module Sfp
|
|
701
697
|
return map
|
702
698
|
end
|
703
699
|
|
704
|
-
def and_equals_constraint_to_map(
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
map[k] = v['_value'] if v['_type'] == 'equals'
|
709
|
-
}
|
700
|
+
def and_equals_constraint_to_map(c)
|
701
|
+
return { c['_self'] => c['_value'] } if c['_type'] == 'equals'
|
702
|
+
map = {}
|
703
|
+
c.each { |k,v| map[k] = v['_value'] if k[0,1] != '_' and v['_type'] == 'equals' }
|
710
704
|
return map
|
711
705
|
end
|
712
706
|
|
@@ -790,18 +784,7 @@ module Sfp
|
|
790
784
|
|
791
785
|
operators = ground_procedure_parameters(procedure)
|
792
786
|
if operators != nil
|
793
|
-
|
794
|
-
operators.each do |op|
|
795
|
-
#begin
|
796
|
-
process_operator(op)
|
797
|
-
#rescue UndefinedValueException
|
798
|
-
# invalid_operators << op
|
799
|
-
# puts "TODO -- invalid operator: " + op['_self'].to_s
|
800
|
-
#end
|
801
|
-
end
|
802
|
-
#operators.delete_if { |op| not invalid_operators.index(op).nil? }
|
803
|
-
else
|
804
|
-
#puts 'proc: ' + procedure.ref + ' cannot be grounded'
|
787
|
+
operators.each { |op| process_operator(op) }
|
805
788
|
end
|
806
789
|
# remove the procedure because we don't need it anymore
|
807
790
|
object.delete(procedure['_self'])
|
@@ -819,7 +802,14 @@ module Sfp
|
|
819
802
|
return nil
|
820
803
|
end
|
821
804
|
params[k] = Array.new
|
822
|
-
type =
|
805
|
+
type = case v['_context']
|
806
|
+
when 'null', 'any_value'
|
807
|
+
v['_isa']
|
808
|
+
when 'set'
|
809
|
+
"(#{v['_isa']})"
|
810
|
+
else
|
811
|
+
nil
|
812
|
+
end
|
823
813
|
next if type == nil
|
824
814
|
raise TypeNotFoundException, type if not @types.has_key?(type)
|
825
815
|
@types[ type ].each { |val| params[k] << val if not (val.is_a?(Hash) and val.isnull) }
|
@@ -1664,9 +1654,12 @@ module Sfp
|
|
1664
1654
|
|
1665
1655
|
def visit(name, value, obj)
|
1666
1656
|
return if name[0,1] == '_' and name != '_value' and name != '_template'
|
1657
|
+
# substituting left side
|
1667
1658
|
if name[0,1] != '_'
|
1668
1659
|
modified = false
|
1669
1660
|
map.each { |k,v|
|
1661
|
+
#puts k + ',' + name if v.is_a?(Sfp::Undefined) or v.is_a?(Sfp::Unknown)
|
1662
|
+
next if v.is_a?(Sfp::Undefined) or v.is_a?(Sfp::Unknown)
|
1670
1663
|
if name == k
|
1671
1664
|
obj[v] = value
|
1672
1665
|
obj.delete(name)
|
@@ -1675,6 +1668,7 @@ module Sfp
|
|
1675
1668
|
modified = true
|
1676
1669
|
break
|
1677
1670
|
elsif name.length > k.length and name[k.length,1] == '.' and name[0, k.length] == k
|
1671
|
+
#next if v.is_a?(Sfp::Undefined) or v.is_a?(Sfp::Unknown)
|
1678
1672
|
grounded = v + name[k.length, (name.length-k.length)]
|
1679
1673
|
obj[grounded] = value
|
1680
1674
|
obj.delete(name)
|
@@ -1705,12 +1699,15 @@ module Sfp
|
|
1705
1699
|
#puts "==>> " + obj.ref.push(name)
|
1706
1700
|
end
|
1707
1701
|
# ------ END of HACK! ----
|
1702
|
+
|
1703
|
+
# substituting right side
|
1708
1704
|
if value.is_a?(String) and value.isref
|
1709
1705
|
map.each { |k,v|
|
1710
1706
|
if value == k
|
1711
1707
|
obj[name] = v
|
1712
1708
|
break
|
1713
|
-
elsif value.length > k.length and value[k.length,1] == '.' and value[0,k.length] == k
|
1709
|
+
elsif value.length > k.length and value[k.length,1] == '.' and value[0,k.length] == k and
|
1710
|
+
not(v.is_a?(Sfp::Undefined) or v.is_a?(Sfp::Unknown))
|
1714
1711
|
obj[name] = v + value[k.length, (value.length-k.length)]
|
1715
1712
|
break
|
1716
1713
|
end
|
data/sfp.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'sfp'
|
3
|
-
s.version = '0.3.
|
4
|
-
s.date = '2013-
|
3
|
+
s.version = '0.3.6'
|
4
|
+
s.date = '2013-08-05'
|
5
5
|
s.summary = 'SFP Parser'
|
6
6
|
s.description = 'A Ruby API and script for SFP language parser'
|
7
7
|
s.authors = ['Herry']
|
@@ -17,5 +17,5 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.rubyforge_project = 'sfp'
|
18
18
|
|
19
19
|
s.add_dependency 'json', '~> 1.7.5'
|
20
|
-
s.add_dependency 'antlr3', '~> 1.
|
20
|
+
s.add_dependency 'antlr3', '~> 1.9.0'
|
21
21
|
end
|
data/src/SfpLang.g
CHANGED
@@ -38,11 +38,17 @@ TODO:
|
|
38
38
|
|
39
39
|
sfp
|
40
40
|
: { self.init }
|
41
|
-
NL*
|
42
|
-
{ self.expand_classes }
|
43
|
-
(object_def NL* |
|
41
|
+
NL*
|
42
|
+
//{ self.expand_classes }
|
43
|
+
( (object_def | state | constraints) NL* | include | class_def | procedure )*
|
44
|
+
// | goal_constraint | composite)*
|
44
45
|
;
|
45
46
|
|
47
|
+
constraints
|
48
|
+
: goal_constraint
|
49
|
+
| global_constraint
|
50
|
+
| sometime_constraint
|
51
|
+
;
|
46
52
|
|
47
53
|
/*mmutation
|
48
54
|
: reference equals_op value NL+
|
@@ -72,12 +78,12 @@ include_file
|
|
72
78
|
;
|
73
79
|
|
74
80
|
header
|
75
|
-
:
|
81
|
+
: class_def
|
76
82
|
| procedure
|
77
83
|
;
|
78
84
|
|
79
85
|
state
|
80
|
-
: ID 'state'
|
86
|
+
: ID 'state' NL*
|
81
87
|
{
|
82
88
|
@now[$ID.text] = { '_self' => $ID.text,
|
83
89
|
'_context' => 'state',
|
@@ -87,7 +93,7 @@ state
|
|
87
93
|
}
|
88
94
|
'{' NL*
|
89
95
|
attribute*
|
90
|
-
'}'
|
96
|
+
'}'
|
91
97
|
{ self.goto_parent(true) }
|
92
98
|
;
|
93
99
|
|
@@ -104,7 +110,7 @@ composite
|
|
104
110
|
{ self.goto_parent(true) }
|
105
111
|
;
|
106
112
|
|
107
|
-
|
113
|
+
class_def
|
108
114
|
: ('class'|'schema') ID
|
109
115
|
{
|
110
116
|
@now[$ID.text] = { '_self' => $ID.text,
|
@@ -124,6 +130,7 @@ class_definition
|
|
124
130
|
@now['_extends'] = '$.Object'
|
125
131
|
@now['_super'] = ['$.Object']
|
126
132
|
end
|
133
|
+
expand_class(@now)
|
127
134
|
self.goto_parent()
|
128
135
|
}
|
129
136
|
;
|
@@ -263,7 +270,7 @@ object_def
|
|
263
270
|
;
|
264
271
|
|
265
272
|
object_body
|
266
|
-
: '{' NL* ( object_attribute |
|
273
|
+
: '{' NL* ( object_attribute | procedure )* '}'
|
267
274
|
;
|
268
275
|
|
269
276
|
object_attribute
|
@@ -290,27 +297,6 @@ dep_effect
|
|
290
297
|
)
|
291
298
|
;
|
292
299
|
|
293
|
-
operator
|
294
|
-
: 'operator' ID '{' NL*
|
295
|
-
{
|
296
|
-
@now[$ID.text] = { '_self' => $ID.text,
|
297
|
-
'_context' => 'operator',
|
298
|
-
'_parent' => @now,
|
299
|
-
'_cost' => 1,
|
300
|
-
'_condition' => { '_context' => 'constraint' },
|
301
|
-
'_effect' => { '_context' => 'effect' }
|
302
|
-
}
|
303
|
-
@now = @now[$ID.text]
|
304
|
-
}
|
305
|
-
( 'cost' equals_op NUMBER NL+
|
306
|
-
{ @now['_cost'] = $NUMBER.text.to_i }
|
307
|
-
)?
|
308
|
-
/*op_param**/
|
309
|
-
op_conditions? op_effects
|
310
|
-
'}' NL+
|
311
|
-
{ self.goto_parent() }
|
312
|
-
;
|
313
|
-
|
314
300
|
op_param
|
315
301
|
: ID equals_op reference NL+
|
316
302
|
{ @now[$ID.text] = $reference.val }
|
@@ -369,7 +355,13 @@ parameters
|
|
369
355
|
;
|
370
356
|
|
371
357
|
parameter
|
372
|
-
: ID
|
358
|
+
: ID ':' path
|
359
|
+
{
|
360
|
+
@now[$ID.text] = { '_context' => 'any_value',
|
361
|
+
'_isa' => self.to_ref($path.text)
|
362
|
+
}
|
363
|
+
}
|
364
|
+
| ID reference_type
|
373
365
|
{ @now[$ID.text] = $reference_type.val }
|
374
366
|
| ID 'areall' path
|
375
367
|
{
|
@@ -424,10 +416,31 @@ goal_constraint
|
|
424
416
|
}
|
425
417
|
@now = @now['goal']
|
426
418
|
}
|
427
|
-
'{' NL* goal_body* '}'
|
419
|
+
'{' NL* goal_body* '}'
|
420
|
+
{ self.goto_parent() }
|
421
|
+
;
|
422
|
+
|
423
|
+
global_constraint
|
424
|
+
: ('global'|'always') 'constraint'? NL*
|
425
|
+
{
|
426
|
+
@now['global'] = self.create_constraint('global', 'and') if !@now.has_key?('global')
|
427
|
+
@now = @now['global']
|
428
|
+
}
|
429
|
+
'{' NL* constraint_body '}'
|
428
430
|
{ self.goto_parent() }
|
429
431
|
;
|
430
432
|
|
433
|
+
sometime_constraint
|
434
|
+
: 'sometime' 'constraint'? NL*
|
435
|
+
{
|
436
|
+
@now['sometime'] = self.create_constraint('sometime', 'or') if !@now.has_key?('sometime')
|
437
|
+
@now = @now['sometime']
|
438
|
+
}
|
439
|
+
'{' NL* constraint_body '}'
|
440
|
+
{ self.goto_parent() }
|
441
|
+
;
|
442
|
+
|
443
|
+
|
431
444
|
goal_body
|
432
445
|
: (
|
433
446
|
( constraint_statement
|
@@ -439,11 +452,11 @@ goal_body
|
|
439
452
|
| constraint_class_quantification
|
440
453
|
)
|
441
454
|
NL+)
|
442
|
-
| 'always' NL*
|
455
|
+
| ('always'|'global') NL*
|
443
456
|
{
|
444
|
-
@now['
|
445
|
-
not @now.has_key?('
|
446
|
-
@now = @now['
|
457
|
+
@now['global'] = self.create_constraint('global', 'and') if
|
458
|
+
not @now.has_key?('global')
|
459
|
+
@now = @now['global']
|
447
460
|
}
|
448
461
|
'{' NL* constraint_body '}' NL+
|
449
462
|
{ self.goto_parent() }
|
@@ -520,12 +533,12 @@ nested_constraint
|
|
520
533
|
;
|
521
534
|
|
522
535
|
constraint
|
523
|
-
:
|
536
|
+
: 'constraint' ID
|
524
537
|
{
|
525
538
|
@now[$ID.text] = self.create_constraint($ID.text, 'and')
|
526
539
|
@now = @now[$ID.text]
|
527
540
|
}
|
528
|
-
'{' NL* constraint_body '}'
|
541
|
+
'{' NL* constraint_body '}'
|
529
542
|
{ self.goto_parent() }
|
530
543
|
;
|
531
544
|
|
@@ -1015,7 +1028,7 @@ BOOLEAN
|
|
1015
1028
|
| 'no'
|
1016
1029
|
;
|
1017
1030
|
|
1018
|
-
ID : ('a'..'z'|'A'..'Z')
|
1031
|
+
ID : ('a'..'z'|'A'..'Z')('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
|
1019
1032
|
;
|
1020
1033
|
|
1021
1034
|
NUMBER
|
@@ -1039,7 +1052,7 @@ MULTILINE_STRING
|
|
1039
1052
|
: 'r"' ( options {greedy=false;} : .)* '"'
|
1040
1053
|
;
|
1041
1054
|
|
1042
|
-
NL : '\r'? '\n'
|
1055
|
+
NL : ('\r'? '\n'|';')
|
1043
1056
|
;
|
1044
1057
|
|
1045
1058
|
WS : ( ' ' | '\t' ) {$channel=HIDDEN;}
|
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.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-08-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,18 +21,28 @@ dependencies:
|
|
21
21
|
version: 1.7.5
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.7.5
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: antlr3
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ~>
|
31
36
|
- !ruby/object:Gem::Version
|
32
|
-
version: 1.
|
37
|
+
version: 1.9.0
|
33
38
|
type: :runtime
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.9.0
|
36
46
|
description: A Ruby API and script for SFP language parser
|
37
47
|
email: herry13@gmail.com
|
38
48
|
executables:
|
@@ -79,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
89
|
version: '0'
|
80
90
|
requirements: []
|
81
91
|
rubyforge_project: sfp
|
82
|
-
rubygems_version: 1.8.
|
92
|
+
rubygems_version: 1.8.23
|
83
93
|
signing_key:
|
84
94
|
specification_version: 3
|
85
95
|
summary: SFP Parser
|