Module Citrus::GrammarMethods

  1. lib/citrus.rb

Contains methods that are available to Grammar modules at the class level.

Public class methods

extend_object (obj)
[show source]
     # File lib/citrus.rb, line 377
377:     def self.extend_object(obj)
378:       raise ArgumentError, "Grammars must be Modules" unless Module === obj
379:       super
380:     end

Public instance methods

all (*args, &block)

Creates a new Sequence using all arguments. A block may be provided to specify semantic behavior (via ext).

[show source]
     # File lib/citrus.rb, line 549
549:     def all(*args, &block)
550:       ext(Sequence.new(args), block)
551:     end
andp (rule, &block)

Creates a new AndPredicate using the given rule. A block may be provided to specify semantic behavior (via ext).

[show source]
     # File lib/citrus.rb, line 509
509:     def andp(rule, &block)
510:       ext(AndPredicate.new(rule), block)
511:     end
any (*args, &block)

Creates a new Choice using all arguments. A block may be provided to specify semantic behavior (via ext).

[show source]
     # File lib/citrus.rb, line 555
555:     def any(*args, &block)
556:       ext(Choice.new(args), block)
557:     end
butp (rule, &block)

Creates a new ButPredicate using the given rule. A block may be provided to specify semantic behavior (via ext).

[show source]
     # File lib/citrus.rb, line 521
521:     def butp(rule, &block)
522:       ext(ButPredicate.new(rule), block)
523:     end
dot (&block)

Creates a new rule that will match any single character. A block may be provided to specify semantic behavior (via ext).

[show source]
     # File lib/citrus.rb, line 497
497:     def dot(&block)
498:       ext(Rule.for(DOT), block)
499:     end
ext (rule, mod=nil, &block)

Specifies a Module that will be used to extend all matches created with the given rule. A block may also be given that will be used to create an anonymous module. See Rule#extension=.

[show source]
     # File lib/citrus.rb, line 570
570:     def ext(rule, mod=nil, &block)
571:       rule = Rule.for(rule)
572:       mod = block if block
573:       rule.extension = mod if mod
574:       rule
575:     end
has_rule? (name)

Returns true if this grammar has a rule with the given name.

[show source]
     # File lib/citrus.rb, line 425
425:     def has_rule?(name)
426:       rules.key?(name.to_sym)
427:     end
included_grammars ()

Returns an array of all grammars that have been included in this grammar in the reverse order they were included.

[show source]
     # File lib/citrus.rb, line 409
409:     def included_grammars
410:       included_modules.select {|mod| mod.include?(Grammar) }
411:     end
label (rule, label, &block)

Adds label to the given rule. A block may be provided to specify semantic behavior (via ext).

[show source]
     # File lib/citrus.rb, line 561
561:     def label(rule, label, &block)
562:       rule = ext(rule, block)
563:       rule.label = label
564:       rule
565:     end
mod (rule, &block)

Creates a new Module from the given block and sets it to be the extension of the given rule. See Rule#extension=.

[show source]
     # File lib/citrus.rb, line 579
579:     def mod(rule, &block)
580:       rule.extension = Module.new(&block)
581:       rule
582:     end
name ()

Returns the name of this grammar as a string.

[show source]
     # File lib/citrus.rb, line 403
403:     def name
404:       super.to_s
405:     end
notp (rule, &block)

Creates a new NotPredicate using the given rule. A block may be provided to specify semantic behavior (via ext).

[show source]
     # File lib/citrus.rb, line 515
515:     def notp(rule, &block)
516:       ext(NotPredicate.new(rule), block)
517:     end
one_or_more (rule, &block)

An alias for rep.

[show source]
     # File lib/citrus.rb, line 533
533:     def one_or_more(rule, &block)
534:       rep(rule, &block)
535:     end
parse (source, options={})

Parses the given source using this grammar’s root rule. Accepts the same options as Rule#parse, plus the following:

root:The name of the root rule to start parsing at. Defaults to this grammar’s root.
[show source]
     # File lib/citrus.rb, line 387
387:     def parse(source, options={})
388:       rule_name = options.delete(:root) || root
389:       raise Error, "No root rule specified" unless rule_name
390:       rule = rule(rule_name)
391:       raise Error, "No rule named \"#{rule_name}\"" unless rule
392:       rule.parse(source, options)
393:     end
parse_file (path, options={})

Parses the contents of the file at the given path using this grammar’s root rule. Accepts the same options as parse.

[show source]
     # File lib/citrus.rb, line 397
397:     def parse_file(path, options={})
398:       path = Pathname.new(path.to_str) unless Pathname === path
399:       parse(path, options)
400:     end
rep (rule, min=1, max=Infinity, &block)

Creates a new Repeat using the given rule. min and max specify the minimum and maximum number of times the rule must match. A block may be provided to specify semantic behavior (via ext).

[show source]
     # File lib/citrus.rb, line 528
528:     def rep(rule, min=1, max=Infinity, &block)
529:       ext(Repeat.new(rule, min, max), block)
530:     end
root (name=nil)

Gets/sets the name of the root rule of this grammar. If no root rule is explicitly specified, the name of this grammar’s first rule is returned.

[show source]
     # File lib/citrus.rb, line 482
482:     def root(name=nil)
483:       if name
484:         @root = name.to_sym
485:       else
486:         # The first rule in a grammar is the default root.
487:         if instance_variable_defined?(:@root)
488:           @root
489:         else
490:           rule_names.first
491:         end
492:       end
493:     end
rule (name, obj=nil, &block)

Gets/sets the rule with the given name. If obj is given the rule will be set to the value of obj passed through Rule.for. If a block is given, its return value will be used for the value of obj.

It is important to note that this method will also check any included grammars for a rule with the given name if one cannot be found in this grammar.

[show source]
     # File lib/citrus.rb, line 459
459:     def rule(name, obj=nil, &block)
460:       sym = name.to_sym
461:       obj = block.call if block
462: 
463:       if obj
464:         rule_names << sym unless has_rule?(sym)
465: 
466:         rule = Rule.for(obj)
467:         rule.name = name
468:         setup_super(rule, name)
469:         rule.grammar = self
470: 
471:         rules[sym] = rule
472:       end
473: 
474:       rules[sym] || super_rule(sym)
475:     rescue => e
476:       e.message.replace("Cannot create rule \"#{name}\": #{e.message}")
477:       raise e
478:     end
rule_names ()

Returns an array of all names of rules in this grammar as symbols ordered in the same way they were declared.

[show source]
     # File lib/citrus.rb, line 415
415:     def rule_names
416:       @rule_names ||= []
417:     end
rules ()

Returns a hash of all Rule objects in this grammar, keyed by rule name.

[show source]
     # File lib/citrus.rb, line 420
420:     def rules
421:       @rules ||= {}
422:     end
sup (&block)

Creates a new Super for the rule currently being defined in the grammar. A block may be provided to specify semantic behavior (via ext).

[show source]
     # File lib/citrus.rb, line 503
503:     def sup(&block)
504:       ext(Super.new, block)
505:     end
super_rule (name)

Searches the inheritance hierarchy of this grammar for a rule named name and returns it on success. Returns nil on failure.

[show source]
     # File lib/citrus.rb, line 443
443:     def super_rule(name)
444:       sym = name.to_sym
445:       included_grammars.each do |grammar|
446:         rule = grammar.rule(sym)
447:         return rule if rule
448:       end
449:       nil
450:     end
zero_or_more (rule, &block)

An alias for rep with a minimum of 0.

[show source]
     # File lib/citrus.rb, line 538
538:     def zero_or_more(rule, &block)
539:       rep(rule, 0, &block)
540:     end
zero_or_one (rule, &block)

An alias for rep with a minimum of 0 and a maximum of 1.

[show source]
     # File lib/citrus.rb, line 543
543:     def zero_or_one(rule, &block)
544:       rep(rule, 0, 1, &block)
545:     end