pione 0.1.1 → 0.1.2
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/History.txt +9 -2
- data/Rakefile +1 -1
- data/example/Fib/Fib.pione +5 -5
- data/example/SequentialProcess/SequentialProcess.pione +69 -0
- data/lib/pione.rb +7 -11
- data/lib/pione/agent/input-generator.rb +3 -2
- data/lib/pione/agent/task-worker.rb +6 -3
- data/lib/pione/agent/trivial-routine-worker.rb +6 -5
- data/lib/pione/command/basic-command.rb +7 -1
- data/lib/pione/command/child-process.rb +5 -1
- data/lib/pione/command/front-owner-command.rb +15 -4
- data/lib/pione/command/pione-client.rb +16 -9
- data/lib/pione/command/pione-syntax-checker.rb +45 -30
- data/lib/pione/command/pione-task-worker.rb +22 -13
- data/lib/pione/command/pione-tuple-space-provider.rb +4 -2
- data/lib/pione/command/pione-tuple-space-receiver.rb +10 -5
- data/lib/pione/front/task-worker-owner.rb +1 -0
- data/lib/pione/model/basic-model.rb +3 -0
- data/lib/pione/model/block.rb +2 -1
- data/lib/pione/model/call-rule.rb +10 -0
- data/lib/pione/model/feature-expr.rb +143 -54
- data/lib/pione/model/float.rb +0 -1
- data/lib/pione/model/rule-expr.rb +132 -7
- data/lib/pione/model/rule.rb +53 -17
- data/lib/pione/model/ticket-expr.rb +124 -0
- data/lib/pione/parser/expr-parser.rb +75 -38
- data/lib/pione/parser/literal-parser.rb +14 -0
- data/lib/pione/parser/parslet-extension.rb +143 -0
- data/lib/pione/rule-handler/flow-handler.rb +33 -3
- data/lib/pione/system/global.rb +10 -3
- data/lib/pione/transformer.rb +24 -0
- data/lib/pione/transformer/block-transformer.rb +6 -5
- data/lib/pione/transformer/document-transformer.rb +5 -10
- data/lib/pione/transformer/expr-transformer.rb +56 -30
- data/lib/pione/transformer/feature-expr-transformer.rb +9 -5
- data/lib/pione/transformer/flow-element-transformer.rb +21 -23
- data/lib/pione/transformer/literal-transformer.rb +39 -35
- data/lib/pione/transformer/rule-definition-transformer.rb +8 -6
- data/lib/pione/transformer/transformer-module.rb +7 -5
- data/lib/pione/tuple/ticket-tuple.rb +8 -0
- data/lib/pione/util/{message.rb → console-message.rb} +54 -26
- data/lib/pione/version.rb +1 -1
- data/pione.gemspec +2 -1
- data/test/model/spec_feature-expr.rb +18 -3
- data/test/model/spec_feature-expr.yml +28 -16
- data/test/model/spec_ticket-expr.rb +67 -0
- data/test/parser/spec_expr-parser.yml +74 -25
- data/test/parser/spec_literal-parser.yml +11 -0
- data/test/test-util.rb +1 -1
- data/test/transformer/spec_expr-transformer.rb +27 -54
- data/test/transformer/spec_literal-transformer.rb +6 -0
- metadata +29 -7
- data/lib/pione/parser/syntax-error.rb +0 -61
@@ -12,6 +12,10 @@ module Pione
|
|
12
12
|
# +expr+ matches all expressions in PIONE document.
|
13
13
|
# @return [Parslet::Atoms::Entity] +expr+ atom
|
14
14
|
# @example
|
15
|
+
# "abc"[0]
|
16
|
+
# @example
|
17
|
+
# 'abc'.as_string
|
18
|
+
# @example
|
15
19
|
# 1 + 1
|
16
20
|
# @example
|
17
21
|
# (1 + 1).next
|
@@ -24,31 +28,52 @@ module Pione
|
|
24
28
|
rule(:expr) {
|
25
29
|
( expr_operator_application |
|
26
30
|
assignment |
|
27
|
-
(
|
28
|
-
(index | message).repeat(1).as(:messages)) |
|
31
|
+
expr_prepositional_messages.as(:reverse_messages) >> pad? >> expr.as(:receiver) |
|
29
32
|
expr_element
|
30
33
|
).as(:expr)
|
31
34
|
}
|
32
35
|
|
36
|
+
|
37
|
+
# @!attribute [r] expr_prepositional_messages
|
38
|
+
# +expr_messages+ matches prepositional messages.
|
39
|
+
# @return [Parslet::Atoms::Entity] +expr_prepositional_messages+ atom
|
40
|
+
rule(:expr_prepositional_messages) {
|
41
|
+
(pad? >> reverse_message).repeat(1)
|
42
|
+
}
|
43
|
+
|
44
|
+
# @!attribute [r] expr_postpositional_messages
|
45
|
+
# +expr_messages+ matches postpositional messages.
|
46
|
+
# @return [Parslet::Atoms::Entity] +expr_post_positional_messages+ atom
|
47
|
+
rule(:expr_postpositional_messages) {
|
48
|
+
(pad? >> (index | message | parameters.as(:postpositional_parameters))).repeat(1)
|
49
|
+
}
|
50
|
+
|
33
51
|
# @!attribute [r] expr_element
|
34
52
|
# +expr_element+ matches simple expressions.
|
35
53
|
# @return [Parslet::Atoms::Entity] +expr_element+ atom
|
36
54
|
# @example
|
37
55
|
# true
|
38
56
|
# @example
|
39
|
-
#
|
57
|
+
# (1 + 1)
|
40
58
|
# @example
|
41
|
-
#
|
59
|
+
# ("abc".index(1, 1))
|
60
|
+
rule(:expr_element) {
|
61
|
+
expr_basic_element.as(:receiver) >> expr_postpositional_messages.as(:messages) |
|
62
|
+
expr_basic_element
|
63
|
+
}
|
64
|
+
|
65
|
+
# @!attribute [r] expr_element
|
66
|
+
# +expr_element+ matches simple expressions.
|
67
|
+
# @return [Parslet::Atoms::Entity] +expr_element+ atom
|
68
|
+
# @example
|
69
|
+
# true
|
42
70
|
# @example
|
43
71
|
# (1 + 1)
|
44
72
|
# @example
|
45
73
|
# ("abc".index(1, 1))
|
46
|
-
rule(:
|
47
|
-
|
48
|
-
|
49
|
-
atomic_expr |
|
50
|
-
lparen >> expr >> rparen
|
51
|
-
)
|
74
|
+
rule(:expr_basic_element) {
|
75
|
+
atomic_expr |
|
76
|
+
lparen >> expr >> rparen
|
52
77
|
}
|
53
78
|
|
54
79
|
# @!attribute [r] atomic_expr
|
@@ -57,6 +82,8 @@ module Pione
|
|
57
82
|
# @example
|
58
83
|
# true
|
59
84
|
# @example
|
85
|
+
# false
|
86
|
+
# @example
|
60
87
|
# 0.1
|
61
88
|
# @example
|
62
89
|
# 1
|
@@ -67,6 +94,8 @@ module Pione
|
|
67
94
|
# @example
|
68
95
|
# '*.txt'
|
69
96
|
# @example
|
97
|
+
# null
|
98
|
+
# @example
|
70
99
|
# {var: 1}
|
71
100
|
# @example
|
72
101
|
# $abc:test
|
@@ -77,6 +106,7 @@ module Pione
|
|
77
106
|
float |
|
78
107
|
integer |
|
79
108
|
string |
|
109
|
+
ticket |
|
80
110
|
data_name |
|
81
111
|
rule_expr |
|
82
112
|
feature_expr |
|
@@ -106,10 +136,12 @@ module Pione
|
|
106
136
|
# @example
|
107
137
|
# :=, ==, !=, >=, >, <=, <, &&, ||, +, -, *, /, %, or, and
|
108
138
|
rule(:expr_operator) {
|
139
|
+
equals >> equals >> greater_than |
|
109
140
|
equals >> equals |
|
110
141
|
exclamation >> equals |
|
111
142
|
less_than >> equals |
|
112
143
|
less_than |
|
144
|
+
greater_than >> greater_than >> greater_than |
|
113
145
|
greater_than >> equals |
|
114
146
|
greater_than |
|
115
147
|
ampersand >> ampersand |
|
@@ -151,21 +183,12 @@ module Pione
|
|
151
183
|
).as(:assignment)
|
152
184
|
}
|
153
185
|
|
154
|
-
# @!attribute [r] messages
|
155
|
-
# +messages+ matches message list.
|
156
|
-
# @return [Parslet::Atoms::Entity] +messages+ atom
|
157
|
-
# @example
|
158
|
-
# .params("-w").sync
|
159
|
-
rule(:messages) {
|
160
|
-
message.repeat(1).as(:messages)
|
161
|
-
}
|
162
|
-
|
163
186
|
# @!attribute [r] message
|
164
187
|
# +message+ matches message sending.
|
165
188
|
# @return [Parslet::Atoms::Entity] +message+ atom
|
166
189
|
# @example
|
167
190
|
# # message with no arguments
|
168
|
-
# .
|
191
|
+
# .as_string
|
169
192
|
# @example
|
170
193
|
# # message with arguments
|
171
194
|
# .params("-w")
|
@@ -176,6 +199,23 @@ module Pione
|
|
176
199
|
).as(:message)
|
177
200
|
}
|
178
201
|
|
202
|
+
# @!attribute [r] reverse_message
|
203
|
+
# +message+ matches reverse message sending.
|
204
|
+
# @return [Parslet::Atoms::Entity] +reverse_message+ atom
|
205
|
+
# @example
|
206
|
+
# # message with no arguments
|
207
|
+
# as_string ::
|
208
|
+
# @example
|
209
|
+
# # message with arguments
|
210
|
+
# params("-w") ::
|
211
|
+
rule(:reverse_message) {
|
212
|
+
( identifier.as(:message_name) >>
|
213
|
+
message_parameters.maybe >>
|
214
|
+
pad? >>
|
215
|
+
colon >> colon
|
216
|
+
).as(:message)
|
217
|
+
}
|
218
|
+
|
179
219
|
# @!attribute [r] message_parameters
|
180
220
|
# +message_parameters+ matches message parameters.
|
181
221
|
# @return [Parslet::Atoms::Entity] +message_parameters+ atom
|
@@ -211,14 +251,9 @@ module Pione
|
|
211
251
|
pad? >> comma >> pad? >> expr
|
212
252
|
}
|
213
253
|
|
214
|
-
#
|
215
|
-
#
|
216
|
-
#
|
217
|
-
# @example
|
218
|
-
# [1][2][3]
|
219
|
-
rule(:indexes) {
|
220
|
-
index.repeat(1).as(:indexes)
|
221
|
-
}
|
254
|
+
#
|
255
|
+
# INDEX
|
256
|
+
#
|
222
257
|
|
223
258
|
# @!attribute [r] index
|
224
259
|
# +index+ matches object index.
|
@@ -227,13 +262,17 @@ module Pione
|
|
227
262
|
# [1]
|
228
263
|
# [1,1]
|
229
264
|
# [1,2,3]
|
265
|
+
# ["a"]
|
266
|
+
# ["a", "b", "c"]
|
267
|
+
# @example
|
268
|
+
# [Var: 1]
|
230
269
|
rule(:index) {
|
231
270
|
( lsbracket >>
|
232
|
-
|
271
|
+
pad? >>
|
233
272
|
( index_arguments.as(:index) |
|
234
273
|
syntax_error("it should be index arguments", :expr)) >>
|
235
|
-
|
236
|
-
rsbracket
|
274
|
+
pad? >>
|
275
|
+
(rsbracket | syntax_error("it should be index end ']'"))
|
237
276
|
)
|
238
277
|
}
|
239
278
|
|
@@ -245,21 +284,19 @@ module Pione
|
|
245
284
|
# 1,1
|
246
285
|
# 1,2,3
|
247
286
|
rule(:index_arguments) {
|
248
|
-
expr.repeat(1,1) >>
|
287
|
+
expr.repeat(1,1) >> pad? >> index_arguments_rest.repeat
|
249
288
|
}
|
250
289
|
|
251
290
|
# @!attribute [r] index_arguments_rest
|
252
|
-
# +index_arguments_rest+ matches
|
291
|
+
# +index_arguments_rest+ matches tail elements in index expression.
|
253
292
|
# @return [Parslet::Atoms::Entity] +index_arguments_rest+ atom
|
254
293
|
# @example
|
255
294
|
# ,1
|
256
295
|
rule(:index_arguments_rest) {
|
257
|
-
|
296
|
+
pad? >>
|
258
297
|
comma >>
|
259
|
-
|
260
|
-
( expr
|
261
|
-
syntax_error("it should be expr", :expr)
|
262
|
-
)
|
298
|
+
pad? >>
|
299
|
+
(expr | syntax_error("it should be expr", :expr))
|
263
300
|
}
|
264
301
|
end
|
265
302
|
end
|
@@ -177,6 +177,20 @@ module Pione
|
|
177
177
|
syntax_error("it should be parameter key", :identifier)
|
178
178
|
)
|
179
179
|
}
|
180
|
+
|
181
|
+
# @!attribute [r] ticket
|
182
|
+
# +ticket+ matches ticket object.
|
183
|
+
#
|
184
|
+
# @return [Parslet::Atoms::Entity] +ticket+ atom
|
185
|
+
# @example
|
186
|
+
# &Main
|
187
|
+
rule(:ticket) {
|
188
|
+
less_than >>
|
189
|
+
space? >>
|
190
|
+
identifier.as(:ticket) >>
|
191
|
+
space? >>
|
192
|
+
greater_than
|
193
|
+
}
|
180
194
|
end
|
181
195
|
end
|
182
196
|
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
module Pione
|
2
|
+
module Parser
|
3
|
+
# ParserError is raised when the parser finds syntax error.
|
4
|
+
class ParserError < Parslet::ParseFailed
|
5
|
+
# Creates an error.
|
6
|
+
# @param [String] str
|
7
|
+
# target string
|
8
|
+
# @param [Array<String>] expected
|
9
|
+
# expected names
|
10
|
+
# @param [Parslet::Source] source
|
11
|
+
# parser source
|
12
|
+
def initialize(str, expected, source)
|
13
|
+
@str = str
|
14
|
+
@expected = expected
|
15
|
+
@source = source
|
16
|
+
super(str)
|
17
|
+
end
|
18
|
+
|
19
|
+
# @api private
|
20
|
+
def message
|
21
|
+
line, column = @source.line_and_column
|
22
|
+
expected = @expected.join(", ")
|
23
|
+
left = @source.consume(@source.chars_left)
|
24
|
+
"%s(expected: %s, line: %s, column: %s):\n%s" % [
|
25
|
+
@str, expected, line, column, left
|
26
|
+
]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# @api private
|
31
|
+
class SyntaxErrorAtom < Parslet::Atoms::Base
|
32
|
+
def initialize(msg, expected_elements=[], ignore_error)
|
33
|
+
@msg = msg
|
34
|
+
@expected_elements = expected_elements
|
35
|
+
@ignore_error = ignore_error
|
36
|
+
end
|
37
|
+
|
38
|
+
def try(source, context, _)
|
39
|
+
raise ParserError.new(@msg, @expected_elements, source)
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_s_inner(prec)
|
43
|
+
"SYNTAX_ERROR"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class IgnoreErrorAtom < Parslet::Atoms::Base
|
48
|
+
def initialize(atom)
|
49
|
+
@atom = atom
|
50
|
+
end
|
51
|
+
|
52
|
+
def try(source, context)
|
53
|
+
begin
|
54
|
+
@atom.apply(source, context)
|
55
|
+
rescue ParserError
|
56
|
+
context.err(self, source, "", [])
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def to_s_inner(prec)
|
61
|
+
"IGNORE_ERROR"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# SyntaxError provides notification methods for syntax error.
|
66
|
+
module SyntaxError
|
67
|
+
# Raises syntax error. This method returns a dummy atom and the parser
|
68
|
+
# evaluates it as error.
|
69
|
+
# @param [String] msg
|
70
|
+
# error message
|
71
|
+
# @param [Array<String>] expected_elements
|
72
|
+
# expected name list
|
73
|
+
# @return [SyntaxErrorAtom]
|
74
|
+
# dummy atom for parser
|
75
|
+
def syntax_error(msg, *expected_elements)
|
76
|
+
SyntaxErrorAtom.new(msg, expected_elements, $ignore_error)
|
77
|
+
end
|
78
|
+
|
79
|
+
def ignore_error(&b)
|
80
|
+
res = yield
|
81
|
+
return IgnoreErrorAtom.new(res)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
class IgnoreAtom < Parslet::Atoms::Base
|
86
|
+
def initialize(atom)
|
87
|
+
@atom = atom
|
88
|
+
end
|
89
|
+
|
90
|
+
def try(source, context, consume_all)
|
91
|
+
success, _ = result = @atom.try(source, context, consume_all)
|
92
|
+
return sucess ? succ(nil) : result
|
93
|
+
end
|
94
|
+
|
95
|
+
def to_s_inner(prec)
|
96
|
+
"IGNORE"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
module Ignore
|
101
|
+
def ignore
|
102
|
+
IgnoreAtom.new(self)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
class ExceptionAtom < Parslet::Atoms::Base
|
107
|
+
def initialize(atom, exception)
|
108
|
+
@atom = atom
|
109
|
+
@exception = exception
|
110
|
+
end
|
111
|
+
|
112
|
+
def try(source, context)
|
113
|
+
success, value = result = @atom.apply(source, context)
|
114
|
+
if success
|
115
|
+
esuccess, _ = @exception.apply(source, context)
|
116
|
+
p @exception
|
117
|
+
p source
|
118
|
+
p esuccess
|
119
|
+
if esuccess
|
120
|
+
return result
|
121
|
+
end
|
122
|
+
end
|
123
|
+
return result
|
124
|
+
end
|
125
|
+
|
126
|
+
def to_s_inner(prec)
|
127
|
+
"EXCEPTION"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
module Exception
|
132
|
+
def except(exception)
|
133
|
+
#ExceptionAtom.new(self, exception)
|
134
|
+
ExceptionAtom.new(self, exception)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
class Parslet::Atoms::Base
|
141
|
+
include Pione::Parser::Ignore
|
142
|
+
include Pione::Parser::Exception
|
143
|
+
end
|
@@ -69,10 +69,35 @@ module Pione
|
|
69
69
|
|
70
70
|
# Finds applicable flow-element rules with inputs and variables.
|
71
71
|
def find_applicable_rules(callees)
|
72
|
-
callees.inject([]) do |
|
73
|
-
#
|
74
|
-
|
72
|
+
callees = callees.inject([]) do |list, callee|
|
73
|
+
# evaluate callee expr by handling rule context
|
74
|
+
# and expand compositional rule expressions as simple rule expressions
|
75
|
+
list + callee.eval(@variable_table).expr.to_set.to_a.map{|expr| CallRule.new(expr)}
|
76
|
+
end
|
77
|
+
|
78
|
+
# ticket check
|
79
|
+
callees = callees.inject([]) do |list, callee|
|
80
|
+
target = nil
|
81
|
+
# check if tickets exist in the domain
|
82
|
+
names = callee.expr.input_ticket_expr.names
|
83
|
+
if not(names.empty?)
|
84
|
+
if names.all? do |name|
|
85
|
+
begin
|
86
|
+
read0(Tuple[:ticket].new(@domain, name))
|
87
|
+
true
|
88
|
+
rescue Rinda::RequestExpiredError
|
89
|
+
false # when the ticket doesn't exist
|
90
|
+
end
|
91
|
+
end
|
92
|
+
target = callee
|
93
|
+
end
|
94
|
+
else
|
95
|
+
target = callee
|
96
|
+
end
|
97
|
+
target ? list << callee : list
|
98
|
+
end
|
75
99
|
|
100
|
+
callees.inject([]) do |combinations, callee|
|
76
101
|
# find callee rule
|
77
102
|
rule = find_callee_rule(callee)
|
78
103
|
|
@@ -211,6 +236,11 @@ module Pione
|
|
211
236
|
# copy data from task domain to this domain
|
212
237
|
@finished << finished
|
213
238
|
copy_data_into_domain(finished.outputs, @domain)
|
239
|
+
|
240
|
+
# output ticket
|
241
|
+
callee.expr.output_ticket_expr.names.each do |name|
|
242
|
+
write(Tuple[:ticket].new(@domain, name))
|
243
|
+
end
|
214
244
|
end
|
215
245
|
|
216
246
|
user_message_end("End Task Distribution: %s" % handler_digest)
|
data/lib/pione/system/global.rb
CHANGED
@@ -21,10 +21,10 @@ module Pione
|
|
21
21
|
# @param [Object] val
|
22
22
|
# default value
|
23
23
|
# @return [void]
|
24
|
-
def define_item(name,
|
24
|
+
def define_item(name, configurable, val=nil, &b)
|
25
25
|
@__names__ << name
|
26
|
-
if
|
27
|
-
@__config__[name] =
|
26
|
+
if configurable
|
27
|
+
@__config__[name] = configurable ? name : config
|
28
28
|
end
|
29
29
|
|
30
30
|
singleton_class.module_eval do |mod|
|
@@ -90,6 +90,13 @@ module Pione
|
|
90
90
|
# system
|
91
91
|
#
|
92
92
|
|
93
|
+
# @!method monitor
|
94
|
+
# Global monitor object for PIONE system.
|
95
|
+
#
|
96
|
+
# @return [Monitor]
|
97
|
+
# monitor object
|
98
|
+
define_item(:monitor, false, Monitor.new)
|
99
|
+
|
93
100
|
# .pione dir
|
94
101
|
define_item(:dot_pione_dir, true) do
|
95
102
|
Pathname.new("~/.pione").expand_path.tap {|path|
|