module Citrus::GrammarMethods

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

Public Class Methods

extend_object(obj) click to toggle source
Calls superclass method
# 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

all(*args, &block) click to toggle source

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

# File lib/citrus.rb, line 548
def all(*args, &block)
  ext(Sequence.new(args), block)
end
andp(rule, &block) click to toggle source

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
any(*args, &block) click to toggle source

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

# File lib/citrus.rb, line 554
def any(*args, &block)
  ext(Choice.new(args), block)
end
butp(rule, &block) click to toggle source

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
dot(&block) click to toggle source

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
ext(rule, mod=nil, &block) click to toggle source

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
has_rule?(name) click to toggle source

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
included_grammars() click to toggle source

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
label(rule, label, &block) click to toggle source

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
mod(rule, &block) click to toggle source

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
name() click to toggle source

Returns the name of this grammar as a string.

Calls superclass method
# File lib/citrus.rb, line 402
def name
  super.to_s
end
notp(rule, &block) click to toggle source

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
one_or_more(rule, &block) click to toggle source

An alias for rep.

# File lib/citrus.rb, line 532
def one_or_more(rule, &block)
  rep(rule, &block)
end
parse(source, options={}) click to toggle source

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
parse_file(path, options={}) click to toggle source

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

# File lib/citrus.rb, line 396
def parse_file(path, options={})
  path = Pathname.new(path.to_str) unless Pathname === path
  parse(path, options)
end
rep(rule, min=1, max=Infinity, &block) click to toggle source

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
root(name=nil) click to toggle source

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
rule(name, obj=nil, &block) click to toggle source

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
rule_names() click to toggle source

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
rules() click to toggle source

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

# File lib/citrus.rb, line 419
def rules
  @rules ||= {}
end
sup(&block) click to toggle source

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

# File lib/citrus.rb, line 502
def sup(&block)
  ext(Super.new, block)
end
super_rule(name) click to toggle source

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
zero_or_more(rule, &block) click to toggle source

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
zero_or_one(rule, &block) click to toggle source

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