Class: Scp
- Inherits:
-
Object
- Object
- Scp
- Defined in:
- lib/linmeric/Scopify.rb
Overview
This class manipulates a string representing an algebric expression underlining the higher priority operations putting them between brackets. Scp prepares strings to be parsed. It must work associated with Sizer. These rules are followed:
-
… = … => (…) = (…) (same with ‘>`)
-
a + b * c => a + (b * c) (same with ‘/`)
-
a ^ b => (a ^ (b))
-
<keyword>: <argument> => (<keyword>: <argument>)
- Author
-
Massimiliano Dal Mas ([email protected])
- License
-
Distributed under MIT license
Instance Method Summary collapse
-
#count ⇒ Object
Returns the current value of the counter.
-
#initialize ⇒ Scp
constructor
Initializes a new counter.
-
#insert_b(expr) ⇒ Object
Inserts a couple of brackets ‘()` before non-binary sum and diff.
-
#scopify(expr) ⇒ Object
Main function that analyzes the string and puts the brackets where it is necessary.
Constructor Details
#initialize ⇒ Scp
Initializes a new counter
20 21 22 |
# File 'lib/linmeric/Scopify.rb', line 20 def initialize @i = 0 end |
Instance Method Details
#count ⇒ Object
Returns the current value of the counter
154 155 156 |
# File 'lib/linmeric/Scopify.rb', line 154 def count() return @i end |
#insert_b(expr) ⇒ Object
Inserts a couple of brackets ‘()` before non-binary sum and diff. operators
-
argument: string to be checked and manipulated
-
returns: manipulated string
163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/linmeric/Scopify.rb', line 163 def insert_b(expr) @i = 0 string = false while @i < expr.size string = (expr[@i] == "\"") ? (string ? false : true) : (string) if (expr[@i] == '-' or expr[@i] == '+') and ((expr[@i - 1] == '(') or (@i == 0)) and !string then expr.insert @i, '()' end @i += 1 end return expr end |
#scopify(expr) ⇒ Object
Main function that analyzes the string and puts the brackets where it is necessary.
-
argument: string to be manipulated
-
returns: manipulated string
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 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 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/linmeric/Scopify.rb', line 29 def scopify(expr) expr = insert_b(expr) @i = 0 n_expr = "" last_empty = 0 open_b = 0 open_p_b = 0 open_m_b = 0 eq = false stack = Array.new last_e = Array.new state = 0 while @i < expr.size case expr[@i] # Each part between brackets is seen as a subexpression # and it is analyzed recoursively. when '(' scp = Scp.new n_expr += expr[@i] + scp.scopify(extract(expr[(@i + 1)...expr.length])) @i += scp.count when /[\*\/]/ # If there are open brackets of higher opertions # it closes them if open_m_b > 0 n_expr += ')' * open_m_b last_empty = last_e.pop open_m_b = 0 #open_b -= 1 end if state == 2 n_expr += ')' * open_p_b open_p_b = 0 state = (stack.size > 0 ? stack.pop : 0) end # If it is not still analyzing a multiplication, it adds the brackets # following the rules unless state == 1 n_expr.insert last_empty, '(' state = 1 open_b += 1 end n_expr += expr[@i] last_empty = n_expr.size # + 1 when /[\+\-]/ # higher priority operation brackets are closed # last_empty is shifted n_expr += ')' * open_p_b if open_p_b > 0 n_expr += ')' * open_b if open_b > 0 state = 0 open_b = 0 open_p_b = 0 n_expr += expr[@i] last_empty = n_expr.size when /\^/ # It begins to put between brackets the operation and its exponent if open_m_b > 0 then n_expr += ")" * open_m_b last_empty = last_e.pop #open_b -= 1 open_m_b = 0 end n_expr.insert last_empty, '(' unless state == 2 last_empty += 1 unless state == 2 n_expr += expr[@i] + (expr[@i+1] == '(' ? '' : '(') open_p_b += (expr[@i+1] == '(' ? 1 : (state == 2 ? 1:2)) stack.push state unless state == 2 state = 2 when /\=/ # The expression at the left of `=` is put between brackets # and a bracket at the right is opened # It closes previously opened brackets n_expr += ')' * open_p_b if open_p_b > 0 n_expr += ')' * open_b if open_b > 0 n_expr += ')' * open_m_b if open_m_b >0 open_b = 0 open_p_b = 0 open_m_b = 0 n_expr = '(' + n_expr + ')' + expr[@i] n_expr += '(' last_empty = n_expr.size state = 0 eq = true when /\>/ n_expr += ')' * open_p_b if open_p_b > 0 n_expr += ')' * open_b if open_b > 0 open_b = 0 open_p_b = 0 n_expr = '(' + n_expr + ')' + expr[@i] last_empty = n_expr.size when /\:/ n_expr.insert last_empty, '(' n_expr += expr[@i] last_k = n_expr[(last_empty+1)...n_expr.size] open_m_b += 1 if "mx:integ:as:from:".include? last_k last_e.pop if last_e.count > 0 and (last_k == "mx:" or last_k == "integ:")# or last_k == "solve:") last_e.push last_empty if last_k == "mx:" or last_k == "integ:"# or last_k == "solve:" last_empty = n_expr.size open_b += 1 unless "mx:integ:as:from:".include? last_k when /\"/ n_expr += expr[@i] @i += 1 n_expr += discard(expr) last_empty = n_expr.length when /\~/ n_expr += ')' * open_p_b if open_p_b > 0 n_expr += ')' * (open_b - 1 ) if open_b - 1 > 0 open_p_b = 0 open_b = 1 state = (stack.size > 0 ? stack.pop : 0) n_expr += expr[@i] last_empty = n_expr.size else n_expr += expr[@i] end @i += 1 end # it closes all the opened brackets n_expr += ')' * open_m_b if open_m_b > 0 n_expr += ')' * open_p_b if open_p_b > 0 n_expr += ')' * open_b if open_b > 0 n_expr += ')' if eq return n_expr end |