gisele 0.0.1
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/CHANGELOG.md +5 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +31 -0
- data/LICENCE.md +22 -0
- data/Manifest.txt +16 -0
- data/README.md +30 -0
- data/Rakefile +23 -0
- data/bin/gisele +8 -0
- data/examples/meeting-scheduler/MeetingScheduling.gis +73 -0
- data/gisele.gemspec +191 -0
- data/gisele.noespec +36 -0
- data/lib/gisele/command.rb +63 -0
- data/lib/gisele/language/grammar.citrus +246 -0
- data/lib/gisele/language/parser.rb +30 -0
- data/lib/gisele/language.rb +6 -0
- data/lib/gisele/loader.rb +4 -0
- data/lib/gisele/version.rb +14 -0
- data/lib/gisele.rb +14 -0
- data/spec/command/main/gisele_ast_ruby.cmd +1 -0
- data/spec/command/main/gisele_ast_ruby.stdout +44 -0
- data/spec/command/main/gisele_help.cmd +1 -0
- data/spec/command/main/gisele_help.stdout +22 -0
- data/spec/command/main/gisele_version.cmd +1 -0
- data/spec/command/main/gisele_version.stdout +2 -0
- data/spec/command/test_command.rb +27 -0
- data/spec/fixtures/tasks/simple.ast +15 -0
- data/spec/fixtures/tasks/simple.gis +9 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/test_examples.rb +14 -0
- data/spec/unit/language/test_ast.rb +264 -0
- data/spec/unit/language/test_grammar.rb +329 -0
- data/spec/unit/language/test_parser.rb +27 -0
- data/spec/unit/test_gisele.rb +8 -0
- data/tasks/debug_mail.rake +75 -0
- data/tasks/debug_mail.txt +13 -0
- data/tasks/gem.rake +68 -0
- data/tasks/spec_test.rake +71 -0
- data/tasks/unit_test.rake +76 -0
- data/tasks/yard.rake +51 -0
- metadata +196 -0
@@ -0,0 +1,246 @@
|
|
1
|
+
grammar Gisele::Language::Grammar
|
2
|
+
|
3
|
+
### Units
|
4
|
+
|
5
|
+
rule task_unit
|
6
|
+
(spacing defn:task_def spacing){
|
7
|
+
defn.value
|
8
|
+
}
|
9
|
+
end
|
10
|
+
|
11
|
+
### Task definitions
|
12
|
+
|
13
|
+
rule task_def
|
14
|
+
('task' spaces tname:task_name spaces
|
15
|
+
signature:(task_signature spaces)?
|
16
|
+
refinement:(task_refinement spaces)?
|
17
|
+
'end'){
|
18
|
+
sigvalue = [:signature] + (signature.empty? ? [] : signature.first.first.value)
|
19
|
+
refvalue = [:refinement, (refinement.empty? ? [] : refinement.first.first.value)]
|
20
|
+
[:task, tname.value, sigvalue, refvalue]
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
rule task_signature
|
25
|
+
(front:task_signature_element tail:(spaces task_signature)?){
|
26
|
+
[front.value] + (tail.empty? ? [] : tail.first.matches.last.value)
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
rule task_signature_element
|
31
|
+
fluent_def | trackvar_def
|
32
|
+
end
|
33
|
+
|
34
|
+
rule task_refinement
|
35
|
+
('refinement' spaces main:process_statement spaces 'end'){
|
36
|
+
main.value
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
### Process statements
|
41
|
+
|
42
|
+
rule process_statement
|
43
|
+
implicit_seq_statement | explicit_statement
|
44
|
+
end
|
45
|
+
|
46
|
+
rule implicit_seq_statement
|
47
|
+
(front:explicit_statement spaces tail:statement_list){
|
48
|
+
[:seq, front.value] + tail.value
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
rule statement_list
|
53
|
+
(f:explicit_statement t:(spaces statement_list)?){
|
54
|
+
[f.value] + (t.empty? ? [] : t.first.matches.last.value)
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
rule explicit_statement
|
59
|
+
if_statement
|
60
|
+
| while_statement
|
61
|
+
| seq_statement
|
62
|
+
| par_statement
|
63
|
+
| task_call_statement
|
64
|
+
end
|
65
|
+
|
66
|
+
rule if_statement
|
67
|
+
('if' spaces cond:bool_expr spaces
|
68
|
+
dost:process_statement spaces
|
69
|
+
elsifclauses:elsif_clause*
|
70
|
+
elseclause:else_clause?
|
71
|
+
'end'){
|
72
|
+
elsifs = elsifclauses.matches.map{|c| c.value}
|
73
|
+
elsec = elseclause.empty? ? [] : [elseclause.first.value]
|
74
|
+
[:if, cond.value, dost.value] + elsifs + elsec
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
rule elsif_clause
|
79
|
+
('elsif' spaces cond:bool_expr spaces dost:process_statement spaces){
|
80
|
+
[:elsif, cond.value, dost.value]
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
rule else_clause
|
85
|
+
('else' spaces dost:process_statement spaces){
|
86
|
+
[:else, dost.value]
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
rule while_statement
|
91
|
+
('while' spaces cond:bool_expr spaces
|
92
|
+
dost:process_statement spaces
|
93
|
+
'end'){
|
94
|
+
[:while, cond.value, dost.value]
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
98
|
+
rule seq_statement
|
99
|
+
('seq' spaces list:statement_list spaces 'end'){
|
100
|
+
[:seq] + list.value
|
101
|
+
}
|
102
|
+
end
|
103
|
+
|
104
|
+
rule par_statement
|
105
|
+
('par' spaces list:statement_list spaces 'end'){
|
106
|
+
[:par] + list.value
|
107
|
+
}
|
108
|
+
end
|
109
|
+
|
110
|
+
rule task_call_statement
|
111
|
+
(task_name){
|
112
|
+
[:task_call, strip]
|
113
|
+
}
|
114
|
+
end
|
115
|
+
|
116
|
+
### Boolean expressions
|
117
|
+
|
118
|
+
rule bool_expr
|
119
|
+
bool_or
|
120
|
+
end
|
121
|
+
|
122
|
+
rule bool_or
|
123
|
+
(left:bool_and spaces 'or' spaces right:bool_or){
|
124
|
+
[:or, left.value, right.value]
|
125
|
+
}
|
126
|
+
| bool_and
|
127
|
+
end
|
128
|
+
|
129
|
+
rule bool_and
|
130
|
+
(left:bool_not spaces 'and' spaces right:bool_and){
|
131
|
+
[:and, left.value, right.value]
|
132
|
+
}
|
133
|
+
| bool_not
|
134
|
+
end
|
135
|
+
|
136
|
+
rule bool_not
|
137
|
+
('not' &([ \t\n] | '(') spacing term:bool_not){
|
138
|
+
[:not, term.value]
|
139
|
+
}
|
140
|
+
| bool_term
|
141
|
+
end
|
142
|
+
|
143
|
+
rule bool_term
|
144
|
+
bool_parenthesed | boolean_literal | bool_varref
|
145
|
+
end
|
146
|
+
|
147
|
+
rule bool_parenthesed
|
148
|
+
('(' spacing expr:bool_expr spacing ')'){
|
149
|
+
expr.value
|
150
|
+
}
|
151
|
+
end
|
152
|
+
|
153
|
+
rule bool_varref
|
154
|
+
(variable_name){
|
155
|
+
[:varref, strip]
|
156
|
+
}
|
157
|
+
end
|
158
|
+
|
159
|
+
### Variables
|
160
|
+
|
161
|
+
rule variable_def
|
162
|
+
trackvar_def | fluent_def
|
163
|
+
end
|
164
|
+
|
165
|
+
rule trackvar_def
|
166
|
+
('trackvar' spaces name:variable_name spacing
|
167
|
+
init:event_set term:(spacing ',' spacing event_set)?
|
168
|
+
initially:initially_def?){
|
169
|
+
termval = term.empty? ? [:event_set] : term.first.matches.last.value
|
170
|
+
initval = initially.empty? ? nil : initially.first.value
|
171
|
+
[:trackvar, name.value, init.value, termval, initval]
|
172
|
+
}
|
173
|
+
end
|
174
|
+
|
175
|
+
rule fluent_def
|
176
|
+
('fluent' spaces name:variable_name spacing
|
177
|
+
init:event_set spacing ',' spacing term:event_set initially:initially_def?){
|
178
|
+
initval = initially.empty? ? nil : initially.first.value
|
179
|
+
[:fluent, name.value, init.value, term.value, initval]
|
180
|
+
}
|
181
|
+
end
|
182
|
+
|
183
|
+
rule initially_def
|
184
|
+
(spaces 'initially' spaces lit:boolean_literal){
|
185
|
+
lit.value
|
186
|
+
}
|
187
|
+
end
|
188
|
+
|
189
|
+
### Events
|
190
|
+
|
191
|
+
rule event_set
|
192
|
+
('{' spacing list:event_commalist? spacing '}'){
|
193
|
+
[:event_set] + (list.empty? ? [] : list.first.value)
|
194
|
+
}
|
195
|
+
end
|
196
|
+
|
197
|
+
rule event_commalist
|
198
|
+
(front:event tail:(spacing ',' spacing event_commalist)?){
|
199
|
+
tailval = tail.empty? ? [] : tail.first.matches.last.value
|
200
|
+
[ front.value ] + tailval
|
201
|
+
}
|
202
|
+
end
|
203
|
+
|
204
|
+
rule event
|
205
|
+
task_start_or_end | event_name
|
206
|
+
end
|
207
|
+
|
208
|
+
rule task_start_or_end
|
209
|
+
task_name ':' ('start' | 'end')
|
210
|
+
end
|
211
|
+
|
212
|
+
### Names
|
213
|
+
|
214
|
+
rule task_name
|
215
|
+
[A-Z] [A-Za-z0-9_]*
|
216
|
+
end
|
217
|
+
|
218
|
+
rule variable_name
|
219
|
+
[a-z] [A-Za-z0-9_]*
|
220
|
+
end
|
221
|
+
|
222
|
+
rule event_name
|
223
|
+
[a-z] [a-z0-9_]*
|
224
|
+
end
|
225
|
+
|
226
|
+
### Literals
|
227
|
+
|
228
|
+
rule boolean_literal
|
229
|
+
('true' | 'false'){ strip == "true" ? true : false }
|
230
|
+
end
|
231
|
+
|
232
|
+
### Spacing
|
233
|
+
|
234
|
+
rule comment
|
235
|
+
"#" (![\n] .)*
|
236
|
+
end
|
237
|
+
|
238
|
+
rule spaces
|
239
|
+
(comment | [ \t\n])+
|
240
|
+
end
|
241
|
+
|
242
|
+
rule spacing
|
243
|
+
(comment | [ \t\n])*
|
244
|
+
end
|
245
|
+
|
246
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Gisele
|
2
|
+
module Language
|
3
|
+
Citrus.load(File.expand_path('../grammar', __FILE__))
|
4
|
+
class Parser
|
5
|
+
|
6
|
+
def self.parse(input)
|
7
|
+
new.parse(input)
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(input)
|
11
|
+
return input if input.is_a?(Array)
|
12
|
+
grammar.parse(parsing_source(input)).value
|
13
|
+
end
|
14
|
+
alias :parse :call
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def grammar
|
19
|
+
Gisele::Language::Grammar
|
20
|
+
end
|
21
|
+
|
22
|
+
def parsing_source(input)
|
23
|
+
input = File.read(input.to_path) if input.respond_to?(:to_path)
|
24
|
+
input = input.to_str if input.respond_to?(:to_str)
|
25
|
+
input
|
26
|
+
end
|
27
|
+
|
28
|
+
end # class Parser
|
29
|
+
end # module Language
|
30
|
+
end # module Gisele
|
data/lib/gisele.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative "gisele/version"
|
2
|
+
require_relative "gisele/loader"
|
3
|
+
#
|
4
|
+
# Gisele is a Process Analyzer Toolset
|
5
|
+
#
|
6
|
+
module Gisele
|
7
|
+
|
8
|
+
def parse(input)
|
9
|
+
Language::Parser::parse(input)
|
10
|
+
end
|
11
|
+
module_function :parse
|
12
|
+
|
13
|
+
end # module Gisele
|
14
|
+
require_relative 'gisele/language'
|
@@ -0,0 +1 @@
|
|
1
|
+
gisele --ast=ruby tasks/simple.gis
|
@@ -0,0 +1,44 @@
|
|
1
|
+
[
|
2
|
+
:task,
|
3
|
+
"Simple",
|
4
|
+
[
|
5
|
+
:signature,
|
6
|
+
[
|
7
|
+
:fluent,
|
8
|
+
"diagKnown",
|
9
|
+
[
|
10
|
+
:event_set,
|
11
|
+
"Diagnosis:start"
|
12
|
+
],
|
13
|
+
[
|
14
|
+
:event_set,
|
15
|
+
"Treatment:end"
|
16
|
+
],
|
17
|
+
nil
|
18
|
+
]
|
19
|
+
],
|
20
|
+
[
|
21
|
+
:refinement,
|
22
|
+
[
|
23
|
+
:seq,
|
24
|
+
[
|
25
|
+
:if,
|
26
|
+
[
|
27
|
+
:not,
|
28
|
+
[
|
29
|
+
:varref,
|
30
|
+
"diagKnown"
|
31
|
+
]
|
32
|
+
],
|
33
|
+
[
|
34
|
+
:task_call,
|
35
|
+
"Diagnosis"
|
36
|
+
]
|
37
|
+
],
|
38
|
+
[
|
39
|
+
:task_call,
|
40
|
+
"Treatment"
|
41
|
+
]
|
42
|
+
]
|
43
|
+
]
|
44
|
+
]
|
@@ -0,0 +1 @@
|
|
1
|
+
gisele --help
|
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
Gisele - A Process Analyzer Toolset
|
3
|
+
|
4
|
+
SYNOPSIS
|
5
|
+
gisele [--version] [--help]
|
6
|
+
gisele [--ast] PROCESS_FILE
|
7
|
+
|
8
|
+
OPTIONS
|
9
|
+
--ast=[MODE] Prints the process abstract syntax tree (debug,ruby)
|
10
|
+
--help Show this help message
|
11
|
+
--version Show version and exit
|
12
|
+
|
13
|
+
DESCRIPTION
|
14
|
+
The Gisele process analyzer toolset provides tools and technique to model and analyze
|
15
|
+
complex process models such as care processes.
|
16
|
+
|
17
|
+
When --ast is used, the command parses a process file and prints its Abstract Syntax
|
18
|
+
Tree (AST) on standard output. By default, this option prints the AST for manual
|
19
|
+
debugging, that is with colors and extra information. Use --ast=ruby to get a ruby
|
20
|
+
array for automatic processing.
|
21
|
+
|
22
|
+
SystemExit
|
@@ -0,0 +1 @@
|
|
1
|
+
gisele --version
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'gisele/command'
|
3
|
+
module Gisele
|
4
|
+
describe 'the `gisele` commandline tool' do
|
5
|
+
|
6
|
+
Path.dir.glob("**/*.cmd").each do |cmdfile|
|
7
|
+
|
8
|
+
it "executes `#{cmdfile}` as expected" do
|
9
|
+
command = cmdfile.read.strip
|
10
|
+
argv = Quickl.parse_commandline_args(command)[1..-1]
|
11
|
+
stdout = cmdfile.sub_ext('.stdout').read
|
12
|
+
|
13
|
+
out, err = capture_io do
|
14
|
+
begin
|
15
|
+
Dir.chdir(fixtures_dir){ Command.run(argv) }
|
16
|
+
rescue SystemExit
|
17
|
+
puts "SystemExit"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
out.should eq stdout
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
[:task, "Simple",
|
2
|
+
[:signature,
|
3
|
+
[:fluent, "diagKnown",
|
4
|
+
[:event_set, "Diagnosis:start"],
|
5
|
+
[:event_set, "Treatment:end"],
|
6
|
+
nil ]
|
7
|
+
],
|
8
|
+
[:refinement,
|
9
|
+
[:seq,
|
10
|
+
[:if,
|
11
|
+
[:not, [:varref, "diagKnown"]],
|
12
|
+
[:task_call, "Diagnosis"] ],
|
13
|
+
[:task_call, "Treatment"]]
|
14
|
+
]
|
15
|
+
]
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
+
require 'gisele'
|
3
|
+
require 'epath'
|
4
|
+
|
5
|
+
def capture_io
|
6
|
+
stdout, stderr = $stdout, $stderr
|
7
|
+
$stdout, $stderr = StringIO.new, StringIO.new
|
8
|
+
yield
|
9
|
+
[$stdout.string, $stderr.string]
|
10
|
+
ensure
|
11
|
+
$stdout, $stderr = stdout, stderr
|
12
|
+
end
|
13
|
+
|
14
|
+
module Helpers
|
15
|
+
|
16
|
+
def fixtures_dir
|
17
|
+
(Path.dir/:fixtures)
|
18
|
+
end
|
19
|
+
|
20
|
+
def fixture_files(glob)
|
21
|
+
fixtures_dir.glob(glob)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
RSpec.configure do |c|
|
27
|
+
c.extend Helpers
|
28
|
+
c.include Helpers
|
29
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
describe "The examples" do
|
3
|
+
|
4
|
+
(Path.backfind(".[examples]")/:examples).glob("**/*.gis").each do |file|
|
5
|
+
|
6
|
+
describe file do
|
7
|
+
it 'parses without any error' do
|
8
|
+
Gisele::parse(file).should be_a(Array)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|