linmeric 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/linmeric +547 -0
- data/doc/Instructions_en.html +231 -0
- data/doc/Instructions_en.txt +208 -0
- data/doc/Instructions_it.html +231 -0
- data/doc/Instructions_it.txt +214 -0
- data/doc/README_en.html +177 -0
- data/doc/README_en.txt +30 -0
- data/doc/README_it.html +187 -0
- data/doc/README_it.txt +32 -0
- data/lib/linmeric/Archive.rb +50 -0
- data/lib/linmeric/CnGal_Matrix_class.rb +358 -0
- data/lib/linmeric/CnGal_new_classes.rb +231 -0
- data/lib/linmeric/CnGal_tools.rb +80 -0
- data/lib/linmeric/Error_print.rb +66 -0
- data/lib/linmeric/Function_class.rb +249 -0
- data/lib/linmeric/Integrators.rb +76 -0
- data/lib/linmeric/LU.rb +84 -0
- data/lib/linmeric/Lexer.rb +54 -0
- data/lib/linmeric/Listener.rb +191 -0
- data/lib/linmeric/Parser.rb +118 -0
- data/lib/linmeric/Scopify.rb +206 -0
- data/lib/linmeric/Sizer.rb +328 -0
- data/lib/linmeric/Token.rb +53 -0
- data/lib/linmeric.rb +10 -0
- metadata +76 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
#! /usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require_relative 'CnGal_new_classes.rb'
|
|
4
|
+
|
|
5
|
+
class Parser
|
|
6
|
+
def initialize()
|
|
7
|
+
@d = 0
|
|
8
|
+
@error = false
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def reset()
|
|
12
|
+
@d = 0
|
|
13
|
+
@error = false
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def parse(expr)
|
|
17
|
+
array = Array.new
|
|
18
|
+
until @d == expr.length
|
|
19
|
+
c = expr[@d]
|
|
20
|
+
case c
|
|
21
|
+
when "("
|
|
22
|
+
@d += 1
|
|
23
|
+
calc = parse(expr)
|
|
24
|
+
array.push calc if calc != nil
|
|
25
|
+
when ")"
|
|
26
|
+
@d += 1
|
|
27
|
+
return array
|
|
28
|
+
when /[\*\/]/
|
|
29
|
+
@d +=1
|
|
30
|
+
array.push c.to_sym
|
|
31
|
+
when /[\+\-\^]/
|
|
32
|
+
@d+=1
|
|
33
|
+
array.push c.to_sym
|
|
34
|
+
when /\=/
|
|
35
|
+
@d += 1
|
|
36
|
+
array.push c.to_sym
|
|
37
|
+
when /\>/
|
|
38
|
+
@d += 1
|
|
39
|
+
array.push c.to_sym
|
|
40
|
+
when /\"/
|
|
41
|
+
@d += 1
|
|
42
|
+
array.push extract(expr)
|
|
43
|
+
when /\~/
|
|
44
|
+
@d += 1
|
|
45
|
+
if expr[@d] == "("
|
|
46
|
+
@d +=1
|
|
47
|
+
calc = parse(expr)
|
|
48
|
+
array.push calc unless calc == nil
|
|
49
|
+
else
|
|
50
|
+
array.push expr[@d]
|
|
51
|
+
@d += 1
|
|
52
|
+
end
|
|
53
|
+
when /\./
|
|
54
|
+
if expr[@d-1] =~ /[0-9]+/
|
|
55
|
+
x = array.pop.to_s + c + expr[@d+1]
|
|
56
|
+
array.push x.to_n
|
|
57
|
+
else
|
|
58
|
+
unless @error
|
|
59
|
+
@error = true
|
|
60
|
+
puts "Problem evaluating expression at index:#{@d}"
|
|
61
|
+
puts "Invalid char '#{expr[@d]}' in string variable"
|
|
62
|
+
end
|
|
63
|
+
return
|
|
64
|
+
end
|
|
65
|
+
@d+=2
|
|
66
|
+
when /\:/
|
|
67
|
+
if expr[@d - 1] =~ /[a-zA-Z]+/ then
|
|
68
|
+
x = array.pop.to_s + c
|
|
69
|
+
array.push x.downcase.to_sym
|
|
70
|
+
else
|
|
71
|
+
unless @error
|
|
72
|
+
@error = true
|
|
73
|
+
puts "Problem evaluating expression at index:#{@d}"
|
|
74
|
+
puts "Invalid char '#{expr[@d]}' in numeric variable"
|
|
75
|
+
end
|
|
76
|
+
return
|
|
77
|
+
end
|
|
78
|
+
@d += 1
|
|
79
|
+
when /\_/
|
|
80
|
+
@d += 1
|
|
81
|
+
x = array.pop.to_s + c
|
|
82
|
+
array.push x
|
|
83
|
+
when /\p{Alnum}/
|
|
84
|
+
if expr[@d-1] =~ /[0-9\.x]/ && array.count>0
|
|
85
|
+
x = array.pop.to_s + c
|
|
86
|
+
array.push x.to_n
|
|
87
|
+
elsif (expr[@d-1] =~ /[a-z\A-Z]/ or expr[@d-1] == '_') && array.count>0
|
|
88
|
+
x = array.pop.to_s + c
|
|
89
|
+
array.push x
|
|
90
|
+
else
|
|
91
|
+
array.push c.to_n if c =~ /[0-9\.x]/
|
|
92
|
+
array.push c if c =~ /[a-zA-Z]/
|
|
93
|
+
end
|
|
94
|
+
@d += 1
|
|
95
|
+
else
|
|
96
|
+
unless @error
|
|
97
|
+
@error = true
|
|
98
|
+
puts "Problem evaluating expression at index:#{@d}"
|
|
99
|
+
puts "Char '#{expr[@d]}' not recognized"
|
|
100
|
+
end
|
|
101
|
+
return
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
return array
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def extract(expr)
|
|
109
|
+
ext = '"'
|
|
110
|
+
while expr[@d] != '"' do
|
|
111
|
+
ext += expr[@d]
|
|
112
|
+
@d += 1
|
|
113
|
+
end
|
|
114
|
+
@d += 1
|
|
115
|
+
return ext + '"'
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
#! /usr/bin/env ruby
|
|
2
|
+
require_relative 'CnGal_new_classes.rb'
|
|
3
|
+
# per poter computare un'espressione in formato stringa
|
|
4
|
+
# devo prima creare un albero con un parsing.
|
|
5
|
+
# per poter fare queste operazioni necessito di racchiudere
|
|
6
|
+
# le operazioni con priorità maggiore tra parentesi; es:
|
|
7
|
+
# 1+2*3 => 1+(2*3)
|
|
8
|
+
# 1+2*9^4 => 1+(2*(9^(4))) N.B. anche l'argomento di una potenza
|
|
9
|
+
# deve essere tra parentesi.
|
|
10
|
+
# valgono le stesse regole per le parti di espressione tra parentesi; es:
|
|
11
|
+
# 3*(1+2/3) => (3*(1+(2/3)))
|
|
12
|
+
# non importa se ci sono parentesi inutili in più, basta che
|
|
13
|
+
# siano coerenti.
|
|
14
|
+
# se c'è un uguale le parti a sx e a dx devono essere chiuse tra
|
|
15
|
+
# parentesi; es: a=b*c => (a)=((b*c))
|
|
16
|
+
# per quanto riguarda le parole chiavi, la parola chive e il
|
|
17
|
+
# suo argomento vengono messi tra parentesi; es t: a => (t: a)
|
|
18
|
+
class Scp
|
|
19
|
+
def initialize
|
|
20
|
+
@i = 0
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def scopify(expr)
|
|
24
|
+
expr = insert_b(expr)
|
|
25
|
+
@i = 0
|
|
26
|
+
n_expr = ""
|
|
27
|
+
last_empty = 0
|
|
28
|
+
open_b = 0
|
|
29
|
+
open_p_b = 0
|
|
30
|
+
open_m_b = 0
|
|
31
|
+
eq = false
|
|
32
|
+
stack = Array.new
|
|
33
|
+
last_e = Array.new
|
|
34
|
+
state = 0
|
|
35
|
+
while @i < expr.size
|
|
36
|
+
case expr[@i]
|
|
37
|
+
# ogni parte racchiusa tra parentesi viene interpretata come
|
|
38
|
+
# una sotto espressione, e la sistemo a parte con una ricorsione
|
|
39
|
+
when '('
|
|
40
|
+
scp = Scp.new
|
|
41
|
+
n_expr += expr[@i] + scp.scopify(extract(expr[(@i + 1)...expr.length]))
|
|
42
|
+
@i += scp.count
|
|
43
|
+
when /[\*\/]/
|
|
44
|
+
# se ho parentesi aperte da operazioni con priorità superiore
|
|
45
|
+
# le chiudo
|
|
46
|
+
if open_m_b > 0
|
|
47
|
+
n_expr += ')' * open_m_b
|
|
48
|
+
last_empty = last_e.pop
|
|
49
|
+
open_m_b = 0
|
|
50
|
+
#open_b -= 1
|
|
51
|
+
end
|
|
52
|
+
if state == 2
|
|
53
|
+
n_expr += ')' * open_p_b
|
|
54
|
+
open_p_b = 0
|
|
55
|
+
state = (stack.size > 0 ? stack.pop : 0)
|
|
56
|
+
end
|
|
57
|
+
# se non ho già in corso un inserimento di parentesi per
|
|
58
|
+
# moltiplicazione, le aggiungo
|
|
59
|
+
unless state == 1
|
|
60
|
+
n_expr.insert last_empty, '('
|
|
61
|
+
state = 1
|
|
62
|
+
open_b += 1
|
|
63
|
+
end
|
|
64
|
+
n_expr += expr[@i]
|
|
65
|
+
last_empty = n_expr.size # + 1
|
|
66
|
+
when /[\+\-]/
|
|
67
|
+
# chiudo le parentesi delle operazioni con priorità superiore
|
|
68
|
+
# faccio lo shift di last_empty
|
|
69
|
+
n_expr += ')' * open_p_b if open_p_b > 0
|
|
70
|
+
n_expr += ')' * open_b if open_b > 0
|
|
71
|
+
state = 0
|
|
72
|
+
open_b = 0
|
|
73
|
+
open_p_b = 0
|
|
74
|
+
n_expr += expr[@i]
|
|
75
|
+
last_empty = n_expr.size
|
|
76
|
+
when /\^/
|
|
77
|
+
# comincio a mettere tra parentesi l'operazione e il suo esponente
|
|
78
|
+
|
|
79
|
+
if open_m_b > 0 then
|
|
80
|
+
n_expr += ")" * open_m_b
|
|
81
|
+
last_empty = last_e.pop
|
|
82
|
+
#open_b -= 1
|
|
83
|
+
open_m_b = 0
|
|
84
|
+
end
|
|
85
|
+
n_expr.insert last_empty, '(' unless state == 2
|
|
86
|
+
last_empty += 1 unless state == 2
|
|
87
|
+
n_expr += expr[@i] + (expr[@i+1] == '(' ? '' : '(')
|
|
88
|
+
open_p_b += (expr[@i+1] == '(' ? 1 : (state == 2 ? 1:2))
|
|
89
|
+
stack.push state unless state == 2
|
|
90
|
+
state = 2
|
|
91
|
+
when /\=/
|
|
92
|
+
# metto tra parentesi la parte a sx dell'uguale e comincio a
|
|
93
|
+
# mettere tra parentesi quella a dx
|
|
94
|
+
# chiudendo eventuali parentesi di potenza o di prodotto
|
|
95
|
+
n_expr += ')' * open_p_b if open_p_b > 0
|
|
96
|
+
n_expr += ')' * open_b if open_b > 0
|
|
97
|
+
open_b = 0
|
|
98
|
+
open_p_b = 0
|
|
99
|
+
n_expr = '(' + n_expr + ')' + expr[@i]
|
|
100
|
+
n_expr += '('
|
|
101
|
+
last_empty = n_expr.size
|
|
102
|
+
state = 0
|
|
103
|
+
eq = true
|
|
104
|
+
when /\>/
|
|
105
|
+
n_expr += ')' * open_p_b if open_p_b > 0
|
|
106
|
+
n_expr += ')' * open_b if open_b > 0
|
|
107
|
+
open_b = 0
|
|
108
|
+
open_p_b = 0
|
|
109
|
+
n_expr = '(' + n_expr + ')' + expr[@i]
|
|
110
|
+
last_empty = n_expr.size
|
|
111
|
+
when /\:/
|
|
112
|
+
n_expr.insert last_empty, '('
|
|
113
|
+
n_expr += expr[@i]
|
|
114
|
+
last_k = n_expr[(last_empty+1)...n_expr.size]
|
|
115
|
+
open_m_b += 1 if "mx:integ:as:from:".include? last_k
|
|
116
|
+
last_e.pop if last_e.count > 0 and (last_k == "mx:" or last_k == "integ:")# or last_k == "solve:")
|
|
117
|
+
last_e.push last_empty if last_k == "mx:" or last_k == "integ:"# or last_k == "solve:"
|
|
118
|
+
last_empty = n_expr.size
|
|
119
|
+
open_b += 1 unless "mx:integ:as:from:".include? last_k
|
|
120
|
+
when /\"/
|
|
121
|
+
n_expr += expr[@i]
|
|
122
|
+
@i += 1
|
|
123
|
+
n_expr += discard(expr)
|
|
124
|
+
last_empty = n_expr.length
|
|
125
|
+
when /\~/
|
|
126
|
+
n_expr += ')' * open_p_b if open_p_b > 0
|
|
127
|
+
n_expr += ')' * (open_b - 1 ) if open_b - 1 > 0
|
|
128
|
+
open_p_b = 0
|
|
129
|
+
open_b = 1
|
|
130
|
+
state = (stack.size > 0 ? stack.pop : 0)
|
|
131
|
+
n_expr += expr[@i]
|
|
132
|
+
last_empty = n_expr.size
|
|
133
|
+
else
|
|
134
|
+
n_expr += expr[@i]
|
|
135
|
+
end
|
|
136
|
+
@i += 1
|
|
137
|
+
end
|
|
138
|
+
# chiudo parentesi aperte, e quella dell'uguale se stata aperta
|
|
139
|
+
n_expr += ')' * open_m_b if open_m_b > 0
|
|
140
|
+
n_expr += ')' * open_p_b if open_p_b > 0
|
|
141
|
+
n_expr += ')' * open_b if open_b > 0
|
|
142
|
+
n_expr += ')' if eq
|
|
143
|
+
return n_expr
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def count()
|
|
147
|
+
return @i
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def insert_b(expr)
|
|
151
|
+
@i = 0
|
|
152
|
+
string = false
|
|
153
|
+
while @i < expr.size
|
|
154
|
+
string = (expr[@i] == "\"") ? (string ? false : true) : (string)
|
|
155
|
+
if (expr[@i] == '-' or expr[@i] == '+') and ((expr[@i - 1] == '(') or (@i == 0)) and !string then
|
|
156
|
+
expr.insert @i, '()'
|
|
157
|
+
end
|
|
158
|
+
@i += 1
|
|
159
|
+
end
|
|
160
|
+
return expr
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
private
|
|
164
|
+
|
|
165
|
+
def extract(expr)
|
|
166
|
+
n_expr = ""
|
|
167
|
+
i = 0
|
|
168
|
+
open_b = 0
|
|
169
|
+
until (i == expr.size) or ((expr[i] == ')') and (open_b == 0))
|
|
170
|
+
n_expr += expr[i]
|
|
171
|
+
open_b += 1 if expr[i] == '('
|
|
172
|
+
open_b -= 1 if expr[i] == ')' and (i < expr.size - 1)
|
|
173
|
+
i += 1
|
|
174
|
+
end
|
|
175
|
+
return n_expr + ')'
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def discard(expr)
|
|
179
|
+
extract = ""
|
|
180
|
+
while expr[@i] != '"' do
|
|
181
|
+
extract += expr[@i]
|
|
182
|
+
@i += 1
|
|
183
|
+
end
|
|
184
|
+
return extract + expr[@i]
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
#####################################
|
|
190
|
+
# Tests #
|
|
191
|
+
#####################################
|
|
192
|
+
=begin
|
|
193
|
+
print ">"
|
|
194
|
+
inp = gets.chomp.compact
|
|
195
|
+
scp = Scp.new
|
|
196
|
+
|
|
197
|
+
while inp != 'exit'
|
|
198
|
+
puts scp.scopify(inp)
|
|
199
|
+
print '>'; inp = gets.chomp.compact
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
=end
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
#! /usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require_relative 'Token.rb'
|
|
4
|
+
require_relative 'Lexer.rb'
|
|
5
|
+
require_relative 'Error_print.rb'
|
|
6
|
+
require_relative 'CnGal_new_classes.rb'
|
|
7
|
+
|
|
8
|
+
class Sizer
|
|
9
|
+
def initialize()
|
|
10
|
+
@lexer = Lexer.new
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def analyze(string, equal = true)
|
|
14
|
+
@i = 0
|
|
15
|
+
state = 0
|
|
16
|
+
return false if string == ""
|
|
17
|
+
@@string = string if string.is_a? String
|
|
18
|
+
unless string.is_a? Array
|
|
19
|
+
unless balanced_brackets? string
|
|
20
|
+
puts "Sintax Error: unbalanced brackets"
|
|
21
|
+
return false
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
token = @lexer.tokenize(string) unless string.is_a? Array
|
|
25
|
+
token = string if string.is_a? Array
|
|
26
|
+
while @i < token.size
|
|
27
|
+
#puts "#{token[@i].me}";puts
|
|
28
|
+
case state
|
|
29
|
+
# beginning state
|
|
30
|
+
when 0
|
|
31
|
+
case token[@i].attribute
|
|
32
|
+
when "SUM_OPERATOR"
|
|
33
|
+
state = 1
|
|
34
|
+
when "VARIABLE"
|
|
35
|
+
state = 2
|
|
36
|
+
when "NUMBER"
|
|
37
|
+
state = 2
|
|
38
|
+
when "L_BRACE"
|
|
39
|
+
sizer = Sizer.new
|
|
40
|
+
return false unless sizer.analyze(token[(@i+1)...token.size])
|
|
41
|
+
@i += sizer.count + 1
|
|
42
|
+
state = 2
|
|
43
|
+
when "KEYWORD"
|
|
44
|
+
case token[@i].me
|
|
45
|
+
when "mx:"
|
|
46
|
+
state = 6
|
|
47
|
+
when "integ:"
|
|
48
|
+
state = 7
|
|
49
|
+
when "shwvar:"
|
|
50
|
+
unless equal
|
|
51
|
+
PrintError.reduced(token[@i],@@string)
|
|
52
|
+
return false
|
|
53
|
+
end
|
|
54
|
+
state = 5
|
|
55
|
+
when "solve:"
|
|
56
|
+
state = 8
|
|
57
|
+
when "f:"
|
|
58
|
+
state = 4
|
|
59
|
+
else
|
|
60
|
+
if ["t:","det:","norm:","id_mx:","shw:"].include? token[@i].me then
|
|
61
|
+
unless equal or token[@i].me != "shw:"
|
|
62
|
+
PrintError.reduced(token[@i],@@string)
|
|
63
|
+
return false
|
|
64
|
+
end
|
|
65
|
+
state = 3
|
|
66
|
+
elsif not Tool.keys.include? token[@i].me then
|
|
67
|
+
PrintError.unknown(token[@i],@@string)
|
|
68
|
+
return false
|
|
69
|
+
else
|
|
70
|
+
PrintError.reduced(token[@i],@@string)
|
|
71
|
+
return false
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
else
|
|
75
|
+
PrintError.default(token[@i],@@string)
|
|
76
|
+
return false
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# expecting numbers,variables, keywords (
|
|
80
|
+
when 1
|
|
81
|
+
case token[@i].attribute
|
|
82
|
+
when "NUMBER"
|
|
83
|
+
state = 2
|
|
84
|
+
when "VARIABLE"
|
|
85
|
+
state = 2
|
|
86
|
+
when "L_BRACE"
|
|
87
|
+
sizer = Sizer.new
|
|
88
|
+
return false unless sizer.analyze(token[(@i+1)...token.size])
|
|
89
|
+
@i += sizer.count + 1
|
|
90
|
+
state = 2
|
|
91
|
+
when "KEYWORD"
|
|
92
|
+
case token[@i].me
|
|
93
|
+
when "mx:"
|
|
94
|
+
state = 6
|
|
95
|
+
when "integ:"
|
|
96
|
+
state = 7
|
|
97
|
+
when "shwvar:"
|
|
98
|
+
state = 5
|
|
99
|
+
when "solve:"
|
|
100
|
+
state = 8
|
|
101
|
+
when "f:"
|
|
102
|
+
state = 4
|
|
103
|
+
else
|
|
104
|
+
if ["t:","det:","norm:","id_mx:"].include? token[@i].me then
|
|
105
|
+
state = 3
|
|
106
|
+
elsif not Tool.keys.include? token[@i].me then
|
|
107
|
+
PrintError.unknown(token[@i],@@string)
|
|
108
|
+
return false
|
|
109
|
+
else
|
|
110
|
+
PrintError.reduced(token[@i],@@string)
|
|
111
|
+
return false
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
else
|
|
115
|
+
PrintError.default(token[@i],@@string)
|
|
116
|
+
return false
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# expecting operators, )
|
|
120
|
+
when 2
|
|
121
|
+
case token[@i].attribute
|
|
122
|
+
when "OPERATOR"
|
|
123
|
+
state = 1
|
|
124
|
+
when "SUM_OPERATOR"
|
|
125
|
+
state = 1
|
|
126
|
+
when "EQUAL_OP"
|
|
127
|
+
if equal
|
|
128
|
+
unless @i + 1 >= token.size
|
|
129
|
+
sizer = Sizer.new
|
|
130
|
+
return sizer.analyze(token[(@i+1)...token.size],false)
|
|
131
|
+
end
|
|
132
|
+
PrintError.missing_expression_after_equal(@i+1,@@string)
|
|
133
|
+
return false
|
|
134
|
+
else
|
|
135
|
+
PrintError.default(token[@i],@@string)
|
|
136
|
+
return false
|
|
137
|
+
end
|
|
138
|
+
when "TO_FILE_OP"
|
|
139
|
+
unless equal
|
|
140
|
+
PrintError.default(token[@i],@@string)
|
|
141
|
+
return false
|
|
142
|
+
end
|
|
143
|
+
state = 4
|
|
144
|
+
when "R_BRACE"
|
|
145
|
+
return true
|
|
146
|
+
else
|
|
147
|
+
PrintError.default(token[@i],@@string)
|
|
148
|
+
return false
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# expecting only variables or numbers
|
|
152
|
+
when 3
|
|
153
|
+
case token[@i].attribute
|
|
154
|
+
when "VARIABLE"
|
|
155
|
+
state = 2
|
|
156
|
+
when "NUMBER"
|
|
157
|
+
state = 2
|
|
158
|
+
else
|
|
159
|
+
PrintError.default(token[@i],@@string)
|
|
160
|
+
return false
|
|
161
|
+
end
|
|
162
|
+
state = 5 if token[@i-1].me == "shw:"
|
|
163
|
+
|
|
164
|
+
# expects blocks (full chek) than nothing
|
|
165
|
+
when 4
|
|
166
|
+
return false unless check_block(token)
|
|
167
|
+
state = 5
|
|
168
|
+
|
|
169
|
+
# expects nothing
|
|
170
|
+
when 5
|
|
171
|
+
PrintError.default(token[@i],@@string)
|
|
172
|
+
return false
|
|
173
|
+
|
|
174
|
+
# checking mx arguments (full)
|
|
175
|
+
when 6
|
|
176
|
+
case token[@i].attribute
|
|
177
|
+
when "KEYWORD"
|
|
178
|
+
if token[@i].me == "from:" then
|
|
179
|
+
@i += 1
|
|
180
|
+
unless @i < token.size
|
|
181
|
+
PrintError.missing(token[@i-1],@@string)
|
|
182
|
+
return false
|
|
183
|
+
end
|
|
184
|
+
return false unless check_block(token)
|
|
185
|
+
state = 2
|
|
186
|
+
else
|
|
187
|
+
PrintError.missmatch(token[@i],@@string,"keyword 'from:' or block")
|
|
188
|
+
return false
|
|
189
|
+
end
|
|
190
|
+
when "QUOTES"
|
|
191
|
+
return false unless check_block(token)
|
|
192
|
+
unless @i+1 >= token.size
|
|
193
|
+
if token[@i+1].attribute == "KEYWORD" then
|
|
194
|
+
@i += 1
|
|
195
|
+
unless @i < token.size
|
|
196
|
+
PrintError.missing(token[@i-1],@@string)
|
|
197
|
+
return false
|
|
198
|
+
end
|
|
199
|
+
unless token[@i].me == "as:"
|
|
200
|
+
PrintError.missmatch(token[@i],@@string,"keyword 'as:' or operator")
|
|
201
|
+
return false
|
|
202
|
+
end
|
|
203
|
+
@i += 1
|
|
204
|
+
unless @i < token.size
|
|
205
|
+
PrintError.missing_general_string(token[@i-1].position+token[@i-1],@@string)
|
|
206
|
+
return false
|
|
207
|
+
end
|
|
208
|
+
return false unless check_block(token)
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
state = 2
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# checking integ arguments (full)
|
|
215
|
+
when 7
|
|
216
|
+
unless @i < token.size
|
|
217
|
+
PrintError.missing(token[@i-1],@@string)
|
|
218
|
+
return false
|
|
219
|
+
end
|
|
220
|
+
if token[@i].attribute == "QUOTES" then
|
|
221
|
+
return false unless check_block(token)
|
|
222
|
+
elsif token[@i].attribute != "VARIABLE" then
|
|
223
|
+
PrintError.missmatch(token[@i],@@string,"variable or block")
|
|
224
|
+
return false
|
|
225
|
+
end
|
|
226
|
+
@i += 1
|
|
227
|
+
unless @i < token.size
|
|
228
|
+
PrintError.missing_integ_range(token[@i-1].position+1,@@string)
|
|
229
|
+
return false
|
|
230
|
+
end
|
|
231
|
+
return false unless check_block(token)
|
|
232
|
+
@i += 1
|
|
233
|
+
unless @i < token.size
|
|
234
|
+
PrintError.numPoint_missing(token[@i-1].position+1,@@string)
|
|
235
|
+
return false
|
|
236
|
+
end
|
|
237
|
+
unless @i + 1 >= token.size
|
|
238
|
+
if token[@i+1].attribute == "QUOTES" then
|
|
239
|
+
@i += 1
|
|
240
|
+
return false unless check_block(token)
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
state = 2
|
|
244
|
+
|
|
245
|
+
# checking solve args (full)
|
|
246
|
+
when 8
|
|
247
|
+
inner_state = 0
|
|
248
|
+
while !(token[@i].attribute == "EQUALS_TO") and @i < token.size
|
|
249
|
+
case inner_state
|
|
250
|
+
when 0
|
|
251
|
+
if token[@i].attribute == "VARIABLE" or token[@i].attribute == "NUMBER" then
|
|
252
|
+
inner_state = 1
|
|
253
|
+
elsif token[@i].attribute == "L_BRACE"
|
|
254
|
+
sizer = Sizer.new
|
|
255
|
+
return false unless sizer.analyze(token[(@i+1)...token.size])
|
|
256
|
+
@i += sizer.count + 1
|
|
257
|
+
else
|
|
258
|
+
PrintError.unexpected_token_in_solve(token[@i],@@string)
|
|
259
|
+
return false
|
|
260
|
+
end
|
|
261
|
+
when 1
|
|
262
|
+
if token[@i].attribute == "OPERATOR" then
|
|
263
|
+
inner_state = 0
|
|
264
|
+
else
|
|
265
|
+
PrintError.unexpected_token_in_solve(token[@i],@@string)
|
|
266
|
+
return false
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
@i += 1
|
|
270
|
+
end
|
|
271
|
+
state = 1
|
|
272
|
+
end
|
|
273
|
+
@i += 1
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
unless state == 2 or state == 5
|
|
277
|
+
if token[@i-1].attribute == "R_BRACE" then
|
|
278
|
+
tk = token[@i-2]
|
|
279
|
+
else
|
|
280
|
+
tk = token[@i-1]
|
|
281
|
+
end
|
|
282
|
+
PrintError.missing(tk,@@string)
|
|
283
|
+
return false
|
|
284
|
+
end
|
|
285
|
+
return true
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
def count
|
|
289
|
+
return @i
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
private
|
|
293
|
+
def balanced_brackets?(exp)
|
|
294
|
+
open_b = 0
|
|
295
|
+
for i in 0...exp.size
|
|
296
|
+
open_b += 1 if exp[i] == "("
|
|
297
|
+
open_b -= 1 if exp[i] == ")"
|
|
298
|
+
end
|
|
299
|
+
open_b == 0 ? (return true) : (return false)
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
def check_block(token)
|
|
303
|
+
unless token[@i].attribute == "QUOTES" then
|
|
304
|
+
PrintError.missmatch(token[@i],@@string,"quotes for block")
|
|
305
|
+
return false
|
|
306
|
+
end
|
|
307
|
+
@i += 1
|
|
308
|
+
unless @i < token.size
|
|
309
|
+
PrintError.missing_general_string(token[@i-1].position+token[@i-1].me.size,@@string,)
|
|
310
|
+
return false
|
|
311
|
+
end
|
|
312
|
+
unless token[@i].attribute == "GENERAL_STRING" then
|
|
313
|
+
PrintError.missmatch(token[@i],@@string,"block argument")
|
|
314
|
+
return false
|
|
315
|
+
end
|
|
316
|
+
@i += 1
|
|
317
|
+
unless @i < token.size
|
|
318
|
+
PrintError.no_final_quotes(@@string,token[@i-1].position+token[@i-1].me.size)
|
|
319
|
+
return false
|
|
320
|
+
end
|
|
321
|
+
unless token[@i].attribute == "QUOTES" then
|
|
322
|
+
PrintError.missmatch(token[@i],@@string,"quotes for block")
|
|
323
|
+
return false
|
|
324
|
+
end
|
|
325
|
+
return true
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#! /usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require_relative 'CnGal_tools.rb'
|
|
4
|
+
require_relative 'CnGal_new_classes.rb'
|
|
5
|
+
|
|
6
|
+
class Token
|
|
7
|
+
OPERATORS = Tool.operators
|
|
8
|
+
VARIABLE = /[a-zA-Z_][a-zA-Z0-9_]*/
|
|
9
|
+
def initialize(to_token,pos,sugg = "")
|
|
10
|
+
@My_pos = pos
|
|
11
|
+
if OPERATORS.include? to_token then
|
|
12
|
+
@My_att = "OPERATOR" unless [">","=","+","-"].include? to_token
|
|
13
|
+
@My_att = "EQUAL_OP" if to_token == "="
|
|
14
|
+
@My_att = "TO_FILE_OP" if to_token == ">"
|
|
15
|
+
@My_att = "SUM_OPERATOR" if '+-'.include? to_token
|
|
16
|
+
elsif sugg != ""
|
|
17
|
+
@My_att = sugg
|
|
18
|
+
elsif to_token == "~"
|
|
19
|
+
@My_att = "EQUALS_TO"
|
|
20
|
+
elsif to_token.include? ":" then
|
|
21
|
+
@My_att = "KEYWORD"
|
|
22
|
+
elsif to_token.match(VARIABLE).to_s.size == to_token.size then
|
|
23
|
+
@My_att = "VARIABLE"
|
|
24
|
+
elsif to_token.number? then
|
|
25
|
+
@My_att = "NUMBER"
|
|
26
|
+
elsif to_token == "(" then
|
|
27
|
+
@My_att = "L_BRACE"
|
|
28
|
+
elsif to_token == ")" then
|
|
29
|
+
@My_att = "R_BRACE"
|
|
30
|
+
elsif to_token == '"' then
|
|
31
|
+
@My_att = "QUOTES"
|
|
32
|
+
else
|
|
33
|
+
@My_att = "GENERAL_STRING"
|
|
34
|
+
end
|
|
35
|
+
@My_self = (to_token.include? ':') ? (to_token.downcase) : (to_token)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def attribute
|
|
39
|
+
return @My_att
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def position
|
|
43
|
+
return @My_pos
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def me
|
|
47
|
+
return @My_self
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def show
|
|
51
|
+
return [@My_att,@My_pos,@My_self]
|
|
52
|
+
end
|
|
53
|
+
end
|