module Citrus::GrammarMethods
Contains methods that are available to Grammar modules at the class level.
Public Class Methods
# File lib/citrus.rb, line 376 def self.extend_object(obj) raise ArgumentError, "Grammars must be Modules" unless Module === obj super end
Public Instance Methods
Creates a new AndPredicate using the given
rule
. A block may be provided to specify semantic behavior
(via ext).
# File lib/citrus.rb, line 508 def andp(rule, &block) ext(AndPredicate.new(rule), block) end
Creates a new ButPredicate using the given
rule
. A block may be provided to specify semantic behavior
(via ext).
# File lib/citrus.rb, line 520 def butp(rule, &block) ext(ButPredicate.new(rule), block) end
Creates a new rule that will match any single character. A block may be provided to specify semantic behavior (via ext).
# File lib/citrus.rb, line 496 def dot(&block) ext(Rule.for(DOT), block) end
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 Citrus::Rule#extension=.
# File lib/citrus.rb, line 569 def ext(rule, mod=nil, &block) rule = Rule.for(rule) mod = block if block rule.extension = mod if mod rule end
Returns true
if this grammar has a rule with the given
name
.
# File lib/citrus.rb, line 424 def has_rule?(name) rules.key?(name.to_sym) end
Returns an array of all grammars that have been included in this grammar in the reverse order they were included.
# File lib/citrus.rb, line 408 def included_grammars included_modules.select {|mod| mod.include?(Grammar) } end
Adds label
to the given rule
. A block may be
provided to specify semantic behavior (via ext).
# File lib/citrus.rb, line 560 def label(rule, label, &block) rule = ext(rule, block) rule.label = label rule end
Creates a new Module from the given block
and sets it to be
the extension of the given rule
. See Citrus::Rule#extension=.
# File lib/citrus.rb, line 578 def mod(rule, &block) rule.extension = Module.new(&block) rule end
Returns the name of this grammar as a string.
# File lib/citrus.rb, line 402 def name super.to_s end
Creates a new NotPredicate using the given
rule
. A block may be provided to specify semantic behavior
(via ext).
# File lib/citrus.rb, line 514 def notp(rule, &block) ext(NotPredicate.new(rule), block) end
An alias for rep.
# File lib/citrus.rb, line 532 def one_or_more(rule, &block) rep(rule, &block) end
Parses the given source
using this grammar's root rule.
Accepts the same options
as Citrus::Rule#parse, plus the following:
- root
-
The name of the root rule to start parsing at. Defaults to this grammar's root.
# File lib/citrus.rb, line 386 def parse(source, options={}) rule_name = options.delete(:root) || root raise Error, "No root rule specified" unless rule_name rule = rule(rule_name) raise Error, "No rule named \"#{rule_name}\"" unless rule rule.parse(source, options) end
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).
# File lib/citrus.rb, line 527 def rep(rule, min=1, max=Infinity, &block) ext(Repeat.new(rule, min, max), block) end
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.
# File lib/citrus.rb, line 481 def root(name=nil) if name @root = name.to_sym else # The first rule in a grammar is the default root. if instance_variable_defined?(:@root) @root else rule_names.first end end end
Gets/sets the rule with the given name
. If obj
is
given the rule will be set to the value of obj
passed through
Citrus::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.
# File lib/citrus.rb, line 458 def rule(name, obj=nil, &block) sym = name.to_sym obj = block.call if block if obj rule_names << sym unless has_rule?(sym) rule = Rule.for(obj) rule.name = name setup_super(rule, name) rule.grammar = self rules[sym] = rule end rules[sym] || super_rule(sym) rescue => e e.message.replace("Cannot create rule \"#{name}\": #{e.message}") raise e end
Returns an array of all names of rules in this grammar as symbols ordered in the same way they were declared.
# File lib/citrus.rb, line 414 def rule_names @rule_names ||= [] end
Returns a hash of all Rule objects in this grammar, keyed by rule name.
# File lib/citrus.rb, line 419 def rules @rules ||= {} end
Searches the inheritance hierarchy of this grammar for a rule named
name
and returns it on success. Returns nil
on
failure.
# File lib/citrus.rb, line 442 def super_rule(name) sym = name.to_sym included_grammars.each do |grammar| rule = grammar.rule(sym) return rule if rule end nil end
An alias for rep with a minimum of 0.
# File lib/citrus.rb, line 537 def zero_or_more(rule, &block) rep(rule, 0, &block) end
An alias for rep with a minimum of 0 and a maximum of 1.
# File lib/citrus.rb, line 542 def zero_or_one(rule, &block) rep(rule, 0, 1, &block) end