Class: ReDuxml::Parser
- Inherits:
-
Object
- Object
- ReDuxml::Parser
- Defined in:
- lib/re_duxml/evaluate/parser.rb
Constant Summary
Constants included from Lexer
Instance Attribute Summary collapse
-
#arities ⇒ Object
Returns the value of attribute arities.
-
#input ⇒ Object
Returns the value of attribute input.
-
#logic ⇒ Object
readonly
Returns the value of attribute logic.
-
#op_stack ⇒ Object
Returns the value of attribute op_stack.
-
#output ⇒ Object
Returns the value of attribute output.
-
#string_hash ⇒ Object
readonly
Returns the value of attribute string_hash.
Attributes included from Lexer
Instance Method Summary collapse
-
#initialize(_logic) ⇒ Parser
constructor
A new instance of Parser.
-
#parse(expr) ⇒ Object
TODO attribute code to Dentaku.
- #to_s ⇒ Object
Methods included from Lexer
Constructor Details
#initialize(_logic) ⇒ Parser
Returns a new instance of Parser.
37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/re_duxml/evaluate/parser.rb', line 37 def initialize(_logic) if _logic load _logic @logic = {} doc.logic.Operator.each do |op| op.parent = @logic @logic[op.symbol] = op end end raise Exception if logic.nil? end |
Instance Attribute Details
#arities ⇒ Object
Returns the value of attribute arities.
28 29 30 |
# File 'lib/re_duxml/evaluate/parser.rb', line 28 def arities @arities end |
#input ⇒ Object
Returns the value of attribute input.
28 29 30 |
# File 'lib/re_duxml/evaluate/parser.rb', line 28 def input @input end |
#logic ⇒ Object (readonly)
Returns the value of attribute logic.
27 28 29 |
# File 'lib/re_duxml/evaluate/parser.rb', line 27 def logic @logic end |
#op_stack ⇒ Object
Returns the value of attribute op_stack.
28 29 30 |
# File 'lib/re_duxml/evaluate/parser.rb', line 28 def op_stack @op_stack end |
#output ⇒ Object
Returns the value of attribute output.
28 29 30 |
# File 'lib/re_duxml/evaluate/parser.rb', line 28 def output @output end |
#string_hash ⇒ Object (readonly)
Returns the value of attribute string_hash.
27 28 29 |
# File 'lib/re_duxml/evaluate/parser.rb', line 27 def string_hash @string_hash end |
Instance Method Details
#parse(expr) ⇒ Object
TODO attribute code to Dentaku
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/re_duxml/evaluate/parser.rb', line 50 def parse(expr) @input = lex(expr) @output = [] @op_stack = [] @arities = [] return nil if input.empty? while(token = input.shift) case token.type when :num, :bool, :string, :param output.push AST::Node.new(token.value) when :operator op_prop = token.value arities << op_prop.arity-1 if op_prop.symbol == '?' if op_prop.right_associative? while op_stack.last && op_prop.precedence < op_stack.last.precedence if !op_stack.last.grouping? consume else break end end else while op_stack.last && op_prop.precedence <= op_stack.last.precedence && !op_stack.last.grouping? consume end end op_stack << op_prop when :function arities << 0 op_stack << token.value when :grouping op_prop = token.value op_str = op_prop.respond_to?(:nodes) ? op_prop.symbol : op_prop.to_s case op_str when '(' if input.any? && input.first.type == :grouping && input.first.value.to_s == '(' input.shift consume(0) else op_stack << op_prop end when ')' while op_stack.any? && op_stack.last.symbol != op_prop.pair.symbol consume(arities.pop || op_stack.last.arity) end lparen = op_stack.pop fail ParseError, "Unbalanced parenthesis" unless lparen && lparen.grouping? if op_stack.last && op_stack.last.position == 'prefix' consume(arities.pop) end when ',' arities[-1] += 1 while op_stack.any? && op_stack.last.symbol != '(' consume end when ':' while op_stack.any? && op_stack.last.symbol != '?' consume(arities.pop) end arities[-1] += 1 op_stack << op_prop else fail ParseError, "Unknown grouping token #{ token.value }" end # case token.value ... when :grouping else fail ParseError, "Not implemented for tokens of type #{ token.type }" end # case token.type end # while (token = input.shift) while op_stack.any? consume end unless output.count == 1 fail ParseError, "Invalid statement" end output.first end |
#to_s ⇒ Object
33 34 35 |
# File 'lib/re_duxml/evaluate/parser.rb', line 33 def to_s doc.logic.name end |