gisele 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|