Class: RParsec::Operators

Inherits:
Object
  • Object
show all
Defined in:
lib/rparsec/operators.rb

Overview

This class helps building lexer and parser for operators. The case that one operator (++ for example) contains another operator (+) is automatically handled so client code don’t have to worry about ambiguity.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ops, &block) ⇒ Operators

To create an instance of Operators for the given operators. The block parameter, if present, is used to convert the token text to another object when the token is recognized during grammar parsing phase.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/rparsec/operators.rb', line 20

def initialize(ops, &block)
  @lexers = {}
  @parsers = {}
  sorted = Operators.sort(ops)
  lexers = sorted.map do |op|
    symbol = op.to_sym
    result = nil
    if op.length == 1
      result = Parsers.char(op)
    else
      result = Parsers.str(op)
    end
    result = result.token(symbol)
    @lexers[symbol] = result
    @parsers[symbol] = Parsers.token(symbol, &block)
    result
  end
  @lexer = Parsers.sum(*lexers)
end

Class Method Details

.sort(ops) ⇒ Object

Sort an array of operators so that contained operator appears after containers. When no containment exist between two operators, the shorter one takes precedence.



64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/rparsec/operators.rb', line 64

def self.sort(ops)
  #sort the array by longer-string-first.
  i = 0
  ordered = ops.sort_by { |x| [x.length, i += 1] }.reverse
  suites = []
  # loop from the longer to shorter string
  ordered.each do |s|
    populate_suites(suites, s)
  end
  # suites are populated with bigger suite first
  to_array suites
end

Instance Method Details

#lexer(op = nil) ⇒ Object

Get the lexer that lexes operators. If an operator is specified, the lexer for that operator is returned.



55
56
57
58
# File 'lib/rparsec/operators.rb', line 55

def lexer(op = nil)
  return @lexer if op.nil?
  @lexers[op.to_sym]
end

#parser(op) ⇒ Object Also known as: []

Get the parser for the given operator.

Raises:

  • (ArgumentError)


43
44
45
46
47
# File 'lib/rparsec/operators.rb', line 43

def parser(op)
  result = @parsers[op.to_sym]
  raise ArgumentError, "parser not found for #{op}" if result.nil?
  result
end