gisele 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,6 @@
1
+ module Gisele
2
+ module Language
3
+
4
+ end # module Language
5
+ end # module Gisele
6
+ require_relative 'language/parser'
@@ -0,0 +1,4 @@
1
+ require "citrus"
2
+ require "epath"
3
+ require "quickl"
4
+ require "awesome_print"
@@ -0,0 +1,14 @@
1
+ module Gisele
2
+ module Version
3
+
4
+ MAJOR = 0
5
+ MINOR = 0
6
+ TINY = 1
7
+
8
+ def self.to_s
9
+ [ MAJOR, MINOR, TINY ].join('.')
10
+ end
11
+
12
+ end
13
+ VERSION = Version.to_s
14
+ end
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,2 @@
1
+ gisele 0.0.1 (c) The University of Louvain
2
+ SystemExit
@@ -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
+ ]
@@ -0,0 +1,9 @@
1
+ task Simple
2
+ fluent diagKnown {Diagnosis:start}, {Treatment:end}
3
+ refinement
4
+ if not(diagKnown)
5
+ Diagnosis
6
+ end
7
+ Treatment
8
+ end
9
+ end
@@ -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