citrus 2.2.2 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -70,31 +70,30 @@ of Ruby modules. Rules use these modules to extend the matches they create.
70
70
 
71
71
  ## Grammars
72
72
 
73
- A grammar is a container for rules. Usually the rules in a grammar collectively
74
- form a complete specification for some language, or a well-defined subset
75
- thereof.
73
+ A [Grammar](api/classes/Citrus/Grammar.html) is a container for rules. Usually
74
+ the rules in a grammar collectively form a complete specification for some
75
+ language, or a well-defined subset thereof.
76
76
 
77
77
  A Citrus grammar is really just a souped-up Ruby
78
78
  [module](http://ruby-doc.org/core/classes/Module.html). These modules may be
79
79
  included in other grammar modules in the same way that Ruby modules are normally
80
80
  used. This property allows you to divide a complex grammar into more manageable,
81
- reusable pieces that may be combined at runtime. Any grammar rule with the same
82
- name as a rule in an included grammar may access that rule with a mechanism
83
- similar to Ruby's super keyword.
81
+ reusable pieces that may be combined at runtime. Any rule with the same name as
82
+ a rule in an included grammar may access that rule with a mechanism similar to
83
+ Ruby's `super` keyword.
84
84
 
85
85
  ## Matches
86
86
 
87
- Matches are created by rule objects when they match on the input. A
88
- [Match](api/classes/Citrus/Match.html) is actually a
89
- [String](http://ruby-doc.org/core/classes/String.html) object with some extra
90
- information attached such as the name(s) of the rule(s) from which it was
91
- generated and any submatches it may contain.
87
+ A [Match](api/classes/Citrus/Match.html) object represents a successful
88
+ recognition of some piece of the input. Matches are created by rule objects during a parse.
92
89
 
93
- During a parse, matches are arranged in a tree structure where any match may
94
- contain any number of other matches. This structure is determined by the way in
95
- which the rule that generated each match is used in the grammar. For example, a
96
- match that is created from a non-terminal rule that contains several other
97
- terminals will likewise contain several matches, one for each terminal.
90
+ Matches are arranged in a tree structure where any match may contain any number
91
+ of other matches. Each match contains information about its own subtree. The
92
+ structure of the tree is determined by the way in which the rule that generated
93
+ each match is used in the grammar. For example, a match that is created from a
94
+ nonterminal rule that contains several other terminals will likewise contain
95
+ several matches, one for each terminal. However, this is an implementation
96
+ detail and should be relatively transparent to the user.
98
97
 
99
98
  Match objects may be extended with semantic information in the form of methods.
100
99
  These methods should provide various interpretations for the semantic value of a
@@ -130,6 +129,9 @@ match in a case-insensitive manner.
130
129
 
131
130
  `abc` # match "abc" in any case
132
131
 
132
+ Besides case sensitivity, case-insensitive strings have the same behavior as
133
+ double quoted strings.
134
+
133
135
  See [Terminal](api/classes/Citrus/Terminal.html) and
134
136
  [StringTerminal](api/classes/Citrus/StringTerminal.html) for more information.
135
137
 
@@ -172,6 +174,9 @@ that does not match a given expression.
172
174
  ~'a' # match all characters until an "a"
173
175
  ~/xyz/ # match all characters until /xyz/ matches
174
176
 
177
+ When using this operator (the tilde), at least one character must be consumed
178
+ for the rule to succeed.
179
+
175
180
  See [AndPredicate](api/classes/Citrus/AndPredicate.html),
176
181
  [NotPredicate](api/classes/Citrus/NotPredicate.html), and
177
182
  [ButPredicate](api/classes/Citrus/ButPredicate.html) for more information.
@@ -201,25 +206,25 @@ levels of precedence is below.
201
206
 
202
207
  See [Choice](api/classes/Citrus/Choice.html) for more information.
203
208
 
209
+ ## Grouping
210
+
211
+ As is common in many programming languages, parentheses may be used to override
212
+ the normal binding order of operators. In the following example parentheses are
213
+ used to make the vertical bar between `'b'` and `'c'` bind tighter than the
214
+ space between `'a'` and `'b'`.
215
+
216
+ 'a' ('b' | 'c') # match "a", then "b" or "c"
217
+
204
218
  ## Labels
205
219
 
206
220
  Match objects may be referred to by a different name than the rule that
207
- originally generated them. Labels are created by placing the label and a colon
221
+ originally generated them. Labels are added by placing the label and a colon
208
222
  immediately preceding any expression.
209
223
 
210
224
  chars:/[a-z]+/ # the characters matched by the regular expression
211
225
  # may be referred to as "chars" in an extension
212
226
  # method
213
227
 
214
- See [Label](api/classes/Citrus/Label.html) for more information.
215
-
216
- ## Grouping
217
-
218
- As is common in many programming languages, parentheses may be used to override
219
- the normal binding order of operators.
220
-
221
- 'a' ('b' | 'c') # match "a", then "b" or "c"
222
-
223
228
  ## Extensions
224
229
 
225
230
  Extensions may be specified using either "module" or "block" syntax. When using
@@ -231,17 +236,16 @@ in between less than and greater than symbols.
231
236
  # times and extend the match with the
232
237
  # CouponCode module
233
238
 
234
- Additionally, extensions may be specified inline using curly braces. Inside the
235
- curly braces you may embed method definitions that will be used to extend match
236
- objects.
239
+ Additionally, extensions may be specified inline using curly braces. When using
240
+ this method, the code inside the curly braces may be invoked by calling the
241
+ `value` method on the match object.
237
242
 
238
- # match any digit and return its integer value when calling the
239
- # #value method on the match object
240
- [0-9] {
241
- def value
242
- to_i
243
- end
244
- }
243
+ [0-9] { to_i } # match any digit and return its integer value when
244
+ # calling the #value method on the match object
245
+
246
+ Note that when using the inline block method you may also specify arguments in
247
+ between vertical bars immediately following the opening curly brace, just like
248
+ in Ruby blocks.
245
249
 
246
250
  ## Super
247
251
 
@@ -249,6 +253,24 @@ When including a grammar inside another, all rules in the child that have the
249
253
  same name as a rule in the parent also have access to the `super` keyword to
250
254
  invoke the parent rule.
251
255
 
256
+ grammar Number
257
+ def number
258
+ [0-9]+
259
+ end
260
+ end
261
+
262
+ grammar FloatingPoint
263
+ include Number
264
+
265
+ rule number
266
+ super ('.' super)?
267
+ end
268
+ end
269
+
270
+ In the example above, the `FloatingPoint` grammar includes `Number`. Both have a
271
+ rule named `number`, so `FloatingPoint#number` has access to `Number#number` by
272
+ means of using `super`.
273
+
252
274
  See [Super](api/classes/Citrus/Super.html) for more information.
253
275
 
254
276
  ## Precedence
@@ -258,22 +280,22 @@ their precedence. A higher precedence indicates tighter binding.
258
280
 
259
281
  Operator | Name | Precedence
260
282
  --------- | ------------------------- | ----------
261
- '' | String (single quoted) | 6
262
- "" | String (double quoted) | 6
263
- `` | String (case insensitive) | 6
264
- [] | Character class | 6
265
- . | Dot (any character) | 6
266
- // | Regular expression | 6
267
- () | Grouping | 6
268
- * | Repetition (arbitrary) | 5
269
- + | Repetition (one or more) | 5
270
- ? | Repetition (zero or one) | 5
271
- & | And predicate | 4
272
- ! | Not predicate | 4
273
- ~ | But predicate | 4
274
- : | Label | 4
275
- <> | Extension (module name) | 3
276
- {} | Extension (literal) | 3
283
+ '' | String (single quoted) | 7
284
+ "" | String (double quoted) | 7
285
+ `` | String (case insensitive) | 7
286
+ [] | Character class | 7
287
+ . | Dot (any character) | 7
288
+ // | Regular expression | 7
289
+ () | Grouping | 7
290
+ * | Repetition (arbitrary) | 6
291
+ + | Repetition (one or more) | 6
292
+ ? | Repetition (zero or one) | 6
293
+ & | And predicate | 5
294
+ ! | Not predicate | 5
295
+ ~ | But predicate | 5
296
+ <> | Extension (module name) | 4
297
+ {} | Extension (literal) | 4
298
+ : | Label | 3
277
299
  e1 e2 | Sequence | 2
278
300
  e1 | e2 | Ordered choice | 1
279
301
 
@@ -288,15 +310,15 @@ integers separated by any amount of white space and a `+` symbol.
288
310
  rule additive
289
311
  number plus (additive | number)
290
312
  end
291
-
313
+
292
314
  rule number
293
315
  [0-9]+ space
294
316
  end
295
-
317
+
296
318
  rule plus
297
319
  '+' space
298
320
  end
299
-
321
+
300
322
  rule space
301
323
  [ \t]*
302
324
  end
@@ -305,7 +327,7 @@ integers separated by any amount of white space and a `+` symbol.
305
327
  Several things to note about the above example:
306
328
 
307
329
  * Grammar and rule declarations end with the `end` keyword
308
- * A Sequence of rules is created by separating expressions with a space
330
+ * A sequence of rules is created by separating expressions with a space
309
331
  * Likewise, ordered choice is represented with a vertical bar
310
332
  * Parentheses may be used to override the natural binding order
311
333
  * Rules may refer to other rules in their own definitions simply by using the
@@ -326,58 +348,54 @@ Submatches are created whenever a rule contains another rule. For example, in
326
348
  the grammar above `number` matches a string of digits followed by white space.
327
349
  Thus, a match generated by this rule will contain two submatches.
328
350
 
329
- We can define methods inside a set of curly braces that will be used to extend
330
- matches when they are created. This works in similar fashion to using Ruby's
351
+ We can define a method inside a set of curly braces that will be used to extend
352
+ a particular rule's matches. This works in similar fashion to using Ruby's
331
353
  blocks. Let's extend the `Addition` grammar using this technique.
332
354
 
333
355
  grammar Addition
334
356
  rule additive
335
357
  (number plus term:(additive | number)) {
336
- def value
337
- number.value + term.value
338
- end
358
+ number.value + term.value
339
359
  }
340
360
  end
341
-
361
+
342
362
  rule number
343
363
  ([0-9]+ space) {
344
- def value
345
- strip.to_i
346
- end
364
+ to_i
347
365
  }
348
366
  end
349
-
367
+
350
368
  rule plus
351
369
  '+' space
352
370
  end
353
-
371
+
354
372
  rule space
355
373
  [ \t]*
356
374
  end
357
375
  end
358
376
 
359
377
  In this version of the grammar we have added two semantic blocks, one each for
360
- the additive and number rules. These blocks contain methods that will be present
361
- on all match objects that result from matches of those particular rules. It's
378
+ the `additive` and `number` rules. These blocks contain code that we can
379
+ execute by calling `value` on match objects that result from those rules. It's
362
380
  easiest to explain what is going on here by starting with the lowest level
363
- block, which is defined within the number rule.
381
+ block, which is defined within `number`.
364
382
 
365
- The semantic block associated with the number rule defines one method, `value`.
366
- Inside this method, we can see that the value of a number match is determined to
367
- be its text value, stripped of white space and converted to an integer.
368
- [Remember](background.html) that matches are simply strings, so the `strip`
369
- method in this case is actually
370
- [String#strip](http://ruby-doc.org/core/classes/String.html#M000820).
383
+ Inside this block we see a call to another method, namely `to_i`. When called in
384
+ the context of a match object, methods that are not defined may be called on a
385
+ match's internal string object via `method_missing`. Thus, the call to `to_i`
386
+ should return the integer value of the match.
371
387
 
372
- The `additive` rule also extends its matches with a `value` method. Notice the
373
- use of the `term` label within the rule definition. This label allows the match
374
- that is created by either the additive or the number rule to be retrieved using
375
- the `term` label. The value of an additive is determined to be the values of its
376
- `number` and `term` matches added together using Ruby's addition operator.
388
+ Similarly, matches created by `additive` will also have a `value` method. Notice
389
+ the use of the `term` label within the rule definition. This label allows the
390
+ match that is created by the choice between `additive` and `number` to be
391
+ retrieved using the `term` method. The value of an additive match is determined
392
+ to be the values of its `number` and `term` matches added together using Ruby's
393
+ addition operator.
377
394
 
378
- Since additive is the first rule defined in the grammar, any match that results
379
- from parsing a string with this grammar will have a `value` method that can be
380
- used to recursively calculate the collective value of the entire match tree.
395
+ Since `additive` is the first rule defined in the grammar, any match that
396
+ results from parsing a string with this grammar will have a `value` method that
397
+ can be used to recursively calculate the collective value of the entire match
398
+ tree.
381
399
 
382
400
  To give it a try, save the code for the `Addition` grammar in a file called
383
401
  addition.citrus. Next, assuming you have the Citrus
@@ -408,29 +426,73 @@ Take a look at
408
426
  for an example of a calculator that is able to parse and evaluate more complex
409
427
  mathematical expressions.
410
428
 
411
- ## Implicit Value
429
+ ## Additional Methods
412
430
 
413
- It is very common for a grammar to only have one interpretation for a given
414
- symbol. For this reason, you may find yourself writing a `value` method for
415
- every rule in your grammar. Because this can be tedious, Citrus allows you to
416
- omit defining such a method if you choose. For example, the `additive` and
417
- `number` rules from the simple calculator example above could also be written
418
- as:
431
+ If you need more than just a `value` method on your match object, you can attach
432
+ additional methods as well. There are two ways to do this. The first lets you
433
+ define additional methods inline in your semantic block. This block will be used
434
+ to create a new Module using [Module#new](http://ruby-doc.org/core/classes/Module.html#M001682). Using the
435
+ `Addition` example above, we might refactor the `additive` rule to look like
436
+ this:
419
437
 
420
438
  rule additive
421
439
  (number plus term:(additive | number)) {
422
- number.value + term.value
440
+ def lhs
441
+ number.value
442
+ end
443
+
444
+ def rhs
445
+ term.value
446
+ end
447
+
448
+ def value
449
+ lhs + rhs
450
+ end
423
451
  }
424
452
  end
425
453
 
426
- rule number
427
- ([0-9]+ space) {
428
- strip.to_i
429
- }
454
+ Now, in addition to having a `value` method, matches that result from the
455
+ `additive` rule will have a `lhs` and a `rhs` method as well. Although not
456
+ particularly useful in this example, this technique can be useful when unit
457
+ testing more complex rules. For example, using this method you might make the
458
+ following assertions in a unit test:
459
+
460
+ match = Addition.parse('1 + 4')
461
+ assert_equal(1, match.lhs)
462
+ assert_equal(4, match.rhs)
463
+ assert_equal(5, match.value)
464
+
465
+ If you would like to abstract away the code in a semantic block, simply create
466
+ a separate Ruby module (in another file) that contains the extension methods you
467
+ want and use the angle bracket notation to indicate that a rule should use that
468
+ module when extending matches.
469
+
470
+ To demonstrate this method with the above example, in a Ruby file you would
471
+ define the following module.
472
+
473
+ module Additive
474
+ def lhs
475
+ number.value
476
+ end
477
+
478
+ def rhs
479
+ term.value
480
+ end
481
+
482
+ def value
483
+ lhs + rhs
484
+ end
430
485
  end
431
486
 
432
- Since no method name is explicitly specified in the semantic blocks, they may be
433
- called using the `value` method.
487
+ Then, in your Citrus grammar file the rule definition would look like this:
488
+
489
+ rule additive
490
+ (number plus term:(additive | number)) <Additive>
491
+ end
492
+
493
+ This method of defining extensions can help keep your grammar files cleaner.
494
+ However, you do need to make sure that your extension modules are already loaded
495
+ before using `Citrus.load` to load your grammar file.
434
496
 
435
497
 
436
498
  # Testing
@@ -43,31 +43,30 @@ of Ruby modules. Rules use these modules to extend the matches they create.
43
43
 
44
44
  ## Grammars
45
45
 
46
- A grammar is a container for rules. Usually the rules in a grammar collectively
47
- form a complete specification for some language, or a well-defined subset
48
- thereof.
46
+ A [Grammar](api/classes/Citrus/Grammar.html) is a container for rules. Usually
47
+ the rules in a grammar collectively form a complete specification for some
48
+ language, or a well-defined subset thereof.
49
49
 
50
50
  A Citrus grammar is really just a souped-up Ruby
51
51
  [module](http://ruby-doc.org/core/classes/Module.html). These modules may be
52
52
  included in other grammar modules in the same way that Ruby modules are normally
53
53
  used. This property allows you to divide a complex grammar into more manageable,
54
- reusable pieces that may be combined at runtime. Any grammar rule with the same
55
- name as a rule in an included grammar may access that rule with a mechanism
56
- similar to Ruby's super keyword.
54
+ reusable pieces that may be combined at runtime. Any rule with the same name as
55
+ a rule in an included grammar may access that rule with a mechanism similar to
56
+ Ruby's `super` keyword.
57
57
 
58
58
  ## Matches
59
59
 
60
- Matches are created by rule objects when they match on the input. A
61
- [Match](api/classes/Citrus/Match.html) is actually a
62
- [String](http://ruby-doc.org/core/classes/String.html) object with some extra
63
- information attached such as the name(s) of the rule(s) from which it was
64
- generated and any submatches it may contain.
65
-
66
- During a parse, matches are arranged in a tree structure where any match may
67
- contain any number of other matches. This structure is determined by the way in
68
- which the rule that generated each match is used in the grammar. For example, a
69
- match that is created from a non-terminal rule that contains several other
70
- terminals will likewise contain several matches, one for each terminal.
60
+ A [Match](api/classes/Citrus/Match.html) object represents a successful
61
+ recognition of some piece of the input. Matches are created by rule objects during a parse.
62
+
63
+ Matches are arranged in a tree structure where any match may contain any number
64
+ of other matches. Each match contains information about its own subtree. The
65
+ structure of the tree is determined by the way in which the rule that generated
66
+ each match is used in the grammar. For example, a match that is created from a
67
+ nonterminal rule that contains several other terminals will likewise contain
68
+ several matches, one for each terminal. However, this is an implementation
69
+ detail and should be relatively transparent to the user.
71
70
 
72
71
  Match objects may be extended with semantic information in the form of methods.
73
72
  These methods should provide various interpretations for the semantic value of a
data/doc/example.markdown CHANGED
@@ -8,15 +8,15 @@ integers separated by any amount of white space and a `+` symbol.
8
8
  rule additive
9
9
  number plus (additive | number)
10
10
  end
11
-
11
+
12
12
  rule number
13
13
  [0-9]+ space
14
14
  end
15
-
15
+
16
16
  rule plus
17
17
  '+' space
18
18
  end
19
-
19
+
20
20
  rule space
21
21
  [ \t]*
22
22
  end
@@ -25,7 +25,7 @@ integers separated by any amount of white space and a `+` symbol.
25
25
  Several things to note about the above example:
26
26
 
27
27
  * Grammar and rule declarations end with the `end` keyword
28
- * A Sequence of rules is created by separating expressions with a space
28
+ * A sequence of rules is created by separating expressions with a space
29
29
  * Likewise, ordered choice is represented with a vertical bar
30
30
  * Parentheses may be used to override the natural binding order
31
31
  * Rules may refer to other rules in their own definitions simply by using the
@@ -46,58 +46,54 @@ Submatches are created whenever a rule contains another rule. For example, in
46
46
  the grammar above `number` matches a string of digits followed by white space.
47
47
  Thus, a match generated by this rule will contain two submatches.
48
48
 
49
- We can define methods inside a set of curly braces that will be used to extend
50
- matches when they are created. This works in similar fashion to using Ruby's
49
+ We can define a method inside a set of curly braces that will be used to extend
50
+ a particular rule's matches. This works in similar fashion to using Ruby's
51
51
  blocks. Let's extend the `Addition` grammar using this technique.
52
52
 
53
53
  grammar Addition
54
54
  rule additive
55
55
  (number plus term:(additive | number)) {
56
- def value
57
- number.value + term.value
58
- end
56
+ number.value + term.value
59
57
  }
60
58
  end
61
-
59
+
62
60
  rule number
63
61
  ([0-9]+ space) {
64
- def value
65
- strip.to_i
66
- end
62
+ to_i
67
63
  }
68
64
  end
69
-
65
+
70
66
  rule plus
71
67
  '+' space
72
68
  end
73
-
69
+
74
70
  rule space
75
71
  [ \t]*
76
72
  end
77
73
  end
78
74
 
79
75
  In this version of the grammar we have added two semantic blocks, one each for
80
- the additive and number rules. These blocks contain methods that will be present
81
- on all match objects that result from matches of those particular rules. It's
76
+ the `additive` and `number` rules. These blocks contain code that we can
77
+ execute by calling `value` on match objects that result from those rules. It's
82
78
  easiest to explain what is going on here by starting with the lowest level
83
- block, which is defined within the number rule.
79
+ block, which is defined within `number`.
84
80
 
85
- The semantic block associated with the number rule defines one method, `value`.
86
- Inside this method, we can see that the value of a number match is determined to
87
- be its text value, stripped of white space and converted to an integer.
88
- [Remember](background.html) that matches are simply strings, so the `strip`
89
- method in this case is actually
90
- [String#strip](http://ruby-doc.org/core/classes/String.html#M000820).
81
+ Inside this block we see a call to another method, namely `to_i`. When called in
82
+ the context of a match object, methods that are not defined may be called on a
83
+ match's internal string object via `method_missing`. Thus, the call to `to_i`
84
+ should return the integer value of the match.
91
85
 
92
- The `additive` rule also extends its matches with a `value` method. Notice the
93
- use of the `term` label within the rule definition. This label allows the match
94
- that is created by either the additive or the number rule to be retrieved using
95
- the `term` label. The value of an additive is determined to be the values of its
96
- `number` and `term` matches added together using Ruby's addition operator.
86
+ Similarly, matches created by `additive` will also have a `value` method. Notice
87
+ the use of the `term` label within the rule definition. This label allows the
88
+ match that is created by the choice between `additive` and `number` to be
89
+ retrieved using the `term` method. The value of an additive match is determined
90
+ to be the values of its `number` and `term` matches added together using Ruby's
91
+ addition operator.
97
92
 
98
- Since additive is the first rule defined in the grammar, any match that results
99
- from parsing a string with this grammar will have a `value` method that can be
100
- used to recursively calculate the collective value of the entire match tree.
93
+ Since `additive` is the first rule defined in the grammar, any match that
94
+ results from parsing a string with this grammar will have a `value` method that
95
+ can be used to recursively calculate the collective value of the entire match
96
+ tree.
101
97
 
102
98
  To give it a try, save the code for the `Addition` grammar in a file called
103
99
  addition.citrus. Next, assuming you have the Citrus
@@ -128,26 +124,70 @@ Take a look at
128
124
  for an example of a calculator that is able to parse and evaluate more complex
129
125
  mathematical expressions.
130
126
 
131
- ## Implicit Value
127
+ ## Additional Methods
132
128
 
133
- It is very common for a grammar to only have one interpretation for a given
134
- symbol. For this reason, you may find yourself writing a `value` method for
135
- every rule in your grammar. Because this can be tedious, Citrus allows you to
136
- omit defining such a method if you choose. For example, the `additive` and
137
- `number` rules from the simple calculator example above could also be written
138
- as:
129
+ If you need more than just a `value` method on your match object, you can attach
130
+ additional methods as well. There are two ways to do this. The first lets you
131
+ define additional methods inline in your semantic block. This block will be used
132
+ to create a new Module using [Module#new](http://ruby-doc.org/core/classes/Module.html#M001682). Using the
133
+ `Addition` example above, we might refactor the `additive` rule to look like
134
+ this:
139
135
 
140
136
  rule additive
141
137
  (number plus term:(additive | number)) {
142
- number.value + term.value
138
+ def lhs
139
+ number.value
140
+ end
141
+
142
+ def rhs
143
+ term.value
144
+ end
145
+
146
+ def value
147
+ lhs + rhs
148
+ end
143
149
  }
144
150
  end
145
151
 
146
- rule number
147
- ([0-9]+ space) {
148
- strip.to_i
149
- }
152
+ Now, in addition to having a `value` method, matches that result from the
153
+ `additive` rule will have a `lhs` and a `rhs` method as well. Although not
154
+ particularly useful in this example, this technique can be useful when unit
155
+ testing more complex rules. For example, using this method you might make the
156
+ following assertions in a unit test:
157
+
158
+ match = Addition.parse('1 + 4')
159
+ assert_equal(1, match.lhs)
160
+ assert_equal(4, match.rhs)
161
+ assert_equal(5, match.value)
162
+
163
+ If you would like to abstract away the code in a semantic block, simply create
164
+ a separate Ruby module (in another file) that contains the extension methods you
165
+ want and use the angle bracket notation to indicate that a rule should use that
166
+ module when extending matches.
167
+
168
+ To demonstrate this method with the above example, in a Ruby file you would
169
+ define the following module.
170
+
171
+ module Additive
172
+ def lhs
173
+ number.value
174
+ end
175
+
176
+ def rhs
177
+ term.value
178
+ end
179
+
180
+ def value
181
+ lhs + rhs
182
+ end
150
183
  end
151
184
 
152
- Since no method name is explicitly specified in the semantic blocks, they may be
153
- called using the `value` method.
185
+ Then, in your Citrus grammar file the rule definition would look like this:
186
+
187
+ rule additive
188
+ (number plus term:(additive | number)) <Additive>
189
+ end
190
+
191
+ This method of defining extensions can help keep your grammar files cleaner.
192
+ However, you do need to make sure that your extension modules are already loaded
193
+ before using `Citrus.load` to load your grammar file.