surpass 0.0.4 → 0.0.6
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.
- data/History.txt +4 -0
- data/README.txt +3 -20
- data/Rakefile +2 -13
- data/bin/surpass +8 -0
- data/examples/big-16mb.rb +25 -0
- data/examples/big-random-strings.rb +28 -0
- data/examples/blanks.rb +34 -0
- data/examples/blanks.xls +0 -0
- data/examples/col_width.rb +16 -0
- data/examples/col_width.xls +0 -0
- data/examples/dates.rb +31 -0
- data/examples/dates.xls +0 -0
- data/examples/format.rb +23 -0
- data/examples/format.xls +0 -0
- data/examples/hello-world.rb +9 -0
- data/examples/hello-world.xls +0 -0
- data/examples/image.rb +10 -0
- data/examples/image.xls +0 -0
- data/examples/merged.rb +36 -0
- data/examples/merged.xls +0 -0
- data/examples/merged0.rb +27 -0
- data/examples/merged0.xls +0 -0
- data/examples/merged1.rb +99 -0
- data/examples/merged1.xls +0 -0
- data/examples/num_formats.rb +55 -0
- data/examples/num_formats.xls +0 -0
- data/examples/numbers.rb +24 -0
- data/examples/numbers.xls +0 -0
- data/examples/outline.rb +110 -0
- data/examples/outline.xls +0 -0
- data/examples/panes.rb +48 -0
- data/examples/panes.xls +0 -0
- data/examples/protection.rb +132 -0
- data/examples/protection.xls +0 -0
- data/examples/python.bmp +0 -0
- data/examples/row_styles.rb +16 -0
- data/examples/row_styles.xls +0 -0
- data/examples/row_styles_empty.rb +15 -0
- data/examples/row_styles_empty.xls +0 -0
- data/examples/set_cell_and_range_style.rb +12 -0
- data/examples/set_cell_and_range_style.xls +0 -0
- data/examples/wrapped-text.rb +13 -0
- data/examples/wrapped-text.xls +0 -0
- data/examples/write_arrays.rb +22 -0
- data/examples/write_arrays.xls +0 -0
- data/examples/ws_props.rb +80 -0
- data/lib/surpass/ExcelFormula.g +366 -0
- data/lib/surpass/ExcelFormula.tokens +30 -0
- data/lib/surpass/ExcelFormulaLexer.rb +922 -0
- data/lib/surpass/ExcelFormulaParser.rb +602 -0
- data/lib/{biff_record.rb → surpass/biff_record.rb} +0 -0
- data/lib/{bitmap.rb → surpass/bitmap.rb} +0 -0
- data/lib/{cell.rb → surpass/cell.rb} +2 -34
- data/lib/{chart.rb → surpass/chart.rb} +0 -0
- data/lib/{column.rb → surpass/column.rb} +0 -0
- data/lib/{document.rb → surpass/document.rb} +0 -0
- data/lib/surpass/excel_formula.rb +23 -0
- data/lib/{excel_magic.rb → surpass/excel_magic.rb} +0 -0
- data/lib/{formatting.rb → surpass/formatting.rb} +93 -53
- data/lib/{row.rb → surpass/row.rb} +0 -0
- data/lib/{style.rb → surpass/style.rb} +2 -1
- data/lib/surpass/tokens.txt +2 -0
- data/lib/{utilities.rb → surpass/utilities.rb} +0 -0
- data/lib/{workbook.rb → surpass/workbook.rb} +0 -0
- data/lib/{worksheet.rb → surpass/worksheet.rb} +15 -6
- data/lib/surpass.rb +1 -1
- data/spec/biff_record_spec.rb +268 -0
- data/spec/cell_spec.rb +56 -0
- data/spec/data/random-strings.txt +10000 -0
- data/spec/document_spec.rb +168 -0
- data/spec/excel_formula_spec.rb +27 -0
- data/spec/formatting_spec.rb +53 -0
- data/spec/output/cells-rk.xls +0 -0
- data/spec/output/cells.xls +0 -0
- data/spec/output/mini.xls +0 -0
- data/spec/reference/P-0508-0000507647-3280-5298.xls +0 -0
- data/spec/reference/all-cell-styles.bin +0 -0
- data/spec/reference/all-number-formats.bin +0 -0
- data/spec/reference/all-styles.bin +0 -0
- data/spec/reference/mini.xls +0 -0
- data/spec/row_spec.rb +19 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/style_spec.rb +89 -0
- data/spec/surpass_spec.rb +7 -0
- data/spec/utilities_spec.rb +57 -0
- data/spec/workbook_spec.rb +48 -0
- data/spec/worksheet_spec.rb +0 -0
- data/stats/cloc.txt +8 -0
- data/stats/rcov.txt +0 -0
- data/stats/specdoc.txt +158 -0
- data/surpass.gemspec +40 -0
- data/tasks/setup.rb +1 -1
- data/tasks/zentest.rake +36 -0
- data/webby/README.txt +6 -0
- data/webby/Sitefile +43 -0
- data/webby/content/css/pygments.txt +6 -0
- data/webby/content/css/style.css +279 -0
- data/webby/content/examples/autoformat.png +0 -0
- data/webby/content/examples/autoformat.rb +32 -0
- data/webby/content/examples/autoformat.xls +0 -0
- data/webby/content/examples/borders.png +0 -0
- data/webby/content/examples/borders.rb +15 -0
- data/webby/content/examples/borders.xls +0 -0
- data/webby/content/examples/colours.png +0 -0
- data/webby/content/examples/colours.rb +23 -0
- data/webby/content/examples/colours.xls +0 -0
- data/webby/content/examples/data.png +0 -0
- data/webby/content/examples/data.rb +11 -0
- data/webby/content/examples/data.xls +0 -0
- data/webby/content/examples/formatting.png +0 -0
- data/webby/content/examples/formatting.rb +78 -0
- data/webby/content/examples/formatting.xls +0 -0
- data/webby/content/examples/hello-world.png +0 -0
- data/webby/content/examples/hello-world.py +8 -0
- data/webby/content/examples/hello-world.rb +9 -0
- data/webby/content/examples/hello-world.xls +0 -0
- data/webby/content/examples/number-format-string.png +0 -0
- data/webby/content/examples/number-format-string.rb +14 -0
- data/webby/content/examples/number-format-string.xls +0 -0
- data/webby/content/examples/patterns.png +0 -0
- data/webby/content/examples/patterns.rb +26 -0
- data/webby/content/examples/patterns.xls +0 -0
- data/webby/content/examples/show-greens.sh +1 -0
- data/webby/content/examples/surpass-info.sh +1 -0
- data/webby/content/img/Thumbs.db +0 -0
- data/webby/content/img/bg_menu.gif +0 -0
- data/webby/content/img/bg_t.gif +0 -0
- data/webby/content/img/bullet.gif +0 -0
- data/webby/content/img/logo.png +0 -0
- data/webby/content/img/logo_.jpg +0 -0
- data/webby/content/img/top_bg.gif +0 -0
- data/webby/content/img/top_bg_.gif +0 -0
- data/webby/content/index.txt +16 -0
- data/webby/content/installation/index.txt +24 -0
- data/webby/content/source/ExcelFormulaLexer.txt +7 -0
- data/webby/content/source/ExcelFormulaParser.txt +7 -0
- data/webby/content/source/biff_record.txt +7 -0
- data/webby/content/source/bitmap.txt +7 -0
- data/webby/content/source/cell.txt +7 -0
- data/webby/content/source/chart.txt +7 -0
- data/webby/content/source/column.txt +7 -0
- data/webby/content/source/document.txt +7 -0
- data/webby/content/source/excel_formula.txt +7 -0
- data/webby/content/source/excel_magic.txt +7 -0
- data/webby/content/source/formatting.txt +7 -0
- data/webby/content/source/row.txt +7 -0
- data/webby/content/source/style.txt +7 -0
- data/webby/content/source/utilities.txt +7 -0
- data/webby/content/source/workbook.txt +7 -0
- data/webby/content/source/worksheet.txt +7 -0
- data/webby/content/surpass-manual.erb +198 -0
- data/webby/layouts/book.txt +29 -0
- data/webby/layouts/default.txt +27 -0
- data/webby/layouts/two_column.txt +25 -0
- data/webby/layouts/web.txt +66 -0
- data/webby/output/.cairn +0 -0
- data/webby/output/css/blueprint/ie.css +26 -0
- data/webby/output/css/blueprint/plugins/buttons/icons/cross.png +0 -0
- data/webby/output/css/blueprint/plugins/buttons/icons/key.png +0 -0
- data/webby/output/css/blueprint/plugins/buttons/icons/tick.png +0 -0
- data/webby/output/css/blueprint/plugins/buttons/readme.txt +32 -0
- data/webby/output/css/blueprint/plugins/buttons/screen.css +97 -0
- data/webby/output/css/blueprint/plugins/fancy-type/readme.txt +14 -0
- data/webby/output/css/blueprint/plugins/fancy-type/screen.css +71 -0
- data/webby/output/css/blueprint/plugins/link-icons/icons/doc.png +0 -0
- data/webby/output/css/blueprint/plugins/link-icons/icons/email.png +0 -0
- data/webby/output/css/blueprint/plugins/link-icons/icons/external.png +0 -0
- data/webby/output/css/blueprint/plugins/link-icons/icons/feed.png +0 -0
- data/webby/output/css/blueprint/plugins/link-icons/icons/im.png +0 -0
- data/webby/output/css/blueprint/plugins/link-icons/icons/pdf.png +0 -0
- data/webby/output/css/blueprint/plugins/link-icons/icons/visited.png +0 -0
- data/webby/output/css/blueprint/plugins/link-icons/icons/xls.png +0 -0
- data/webby/output/css/blueprint/plugins/link-icons/readme.txt +18 -0
- data/webby/output/css/blueprint/plugins/link-icons/screen.css +40 -0
- data/webby/output/css/blueprint/plugins/rtl/readme.txt +10 -0
- data/webby/output/css/blueprint/plugins/rtl/screen.css +109 -0
- data/webby/output/css/blueprint/print.css +30 -0
- data/webby/output/css/blueprint/screen.css +251 -0
- data/webby/output/css/blueprint/src/forms.css +49 -0
- data/webby/output/css/blueprint/src/grid.css +212 -0
- data/webby/output/css/blueprint/src/grid.png +0 -0
- data/webby/output/css/blueprint/src/ie.css +59 -0
- data/webby/output/css/blueprint/src/print.css +85 -0
- data/webby/output/css/blueprint/src/reset.css +38 -0
- data/webby/output/css/blueprint/src/typography.css +105 -0
- data/webby/output/css/pygments.css +59 -0
- data/webby/output/css/site.css +62 -0
- data/webby/output/css/style.css +279 -0
- data/webby/output/examples/autoformat.png +0 -0
- data/webby/output/examples/autoformat.rb +32 -0
- data/webby/output/examples/autoformat.xls +0 -0
- data/webby/output/examples/borders.png +0 -0
- data/webby/output/examples/borders.rb +15 -0
- data/webby/output/examples/borders.xls +0 -0
- data/webby/output/examples/colours.png +0 -0
- data/webby/output/examples/colours.rb +23 -0
- data/webby/output/examples/colours.xls +0 -0
- data/webby/output/examples/data.png +0 -0
- data/webby/output/examples/data.rb +11 -0
- data/webby/output/examples/data.xls +0 -0
- data/webby/output/examples/formatting.png +0 -0
- data/webby/output/examples/formatting.rb +78 -0
- data/webby/output/examples/formatting.xls +0 -0
- data/webby/output/examples/hello-world.png +0 -0
- data/webby/output/examples/hello-world.py +8 -0
- data/webby/output/examples/hello-world.rb +9 -0
- data/webby/output/examples/hello-world.xls +0 -0
- data/webby/output/examples/number-format-string.png +0 -0
- data/webby/output/examples/number-format-string.rb +14 -0
- data/webby/output/examples/number-format-string.xls +0 -0
- data/webby/output/examples/patterns.png +0 -0
- data/webby/output/examples/patterns.rb +26 -0
- data/webby/output/examples/patterns.xls +0 -0
- data/webby/output/examples/show-greens.sh +1 -0
- data/webby/output/examples/surpass-info.sh +1 -0
- data/webby/output/img/Thumbs.db +0 -0
- data/webby/output/img/bg_menu.gif +0 -0
- data/webby/output/img/bg_t.gif +0 -0
- data/webby/output/img/bullet.gif +0 -0
- data/webby/output/img/logo.png +0 -0
- data/webby/output/img/logo_.jpg +0 -0
- data/webby/output/img/top_bg.gif +0 -0
- data/webby/output/img/top_bg_.gif +0 -0
- data/webby/output/index.html +138 -0
- data/webby/output/installation/index.html +64 -0
- data/webby/output/installation/installation.html +1 -0
- data/webby/output/installation.html +1 -0
- data/webby/output/source/ExcelFormulaLexer.html +981 -0
- data/webby/output/source/ExcelFormulaParser.html +661 -0
- data/webby/output/source/biff_record.html +462 -0
- data/webby/output/source/bitmap.html +277 -0
- data/webby/output/source/cell.html +241 -0
- data/webby/output/source/chart.html +64 -0
- data/webby/output/source/column.html +99 -0
- data/webby/output/source/document.html +465 -0
- data/webby/output/source/excel_formula.html +82 -0
- data/webby/output/source/excel_magic.html +1072 -0
- data/webby/output/source/formatting.html +664 -0
- data/webby/output/source/row.html +169 -0
- data/webby/output/source/style.html +158 -0
- data/webby/output/source/surpass.html +110 -0
- data/webby/output/source/utilities.html +145 -0
- data/webby/output/source/workbook.html +265 -0
- data/webby/output/source/worksheet.html +331 -0
- data/webby/output/surpass-manual-0-0-5.pdf +0 -0
- data/webby/output/surpass-manual.aux +50 -0
- data/webby/output/surpass-manual.log +366 -0
- data/webby/output/surpass-manual.out +20 -0
- data/webby/output/surpass-manual.tex +582 -0
- data/webby/output/surpass-manual.toc +20 -0
- data/webby/rsync-exclude +7 -0
- data/webby/tasks/latex.rake +14 -0
- data/webby/tasks/screenshots.rb +58 -0
- data/webby/templates/article.erb +15 -0
- data/webby/templates/book.erb +16 -0
- data/webby/templates/page.erb +9 -0
- metadata +302 -24
- data/bin/surpass-info +0 -20
- data/lib/excel_formula.rb +0 -6
@@ -0,0 +1,602 @@
|
|
1
|
+
# ExcelFormulaParser (ExcelFormula.g)
|
2
|
+
# Generated by ANTLR 3.1.2-2008-10-21 on 2009-06-15 23:03:59
|
3
|
+
|
4
|
+
require 'ExcelFormulaLexer' unless defined?(ExcelFormulaLexer)
|
5
|
+
|
6
|
+
class ExcelFormulaParser
|
7
|
+
attr_reader :lexer
|
8
|
+
|
9
|
+
TOKENS = [
|
10
|
+
["EQ", 1],
|
11
|
+
["CONCAT", 2],
|
12
|
+
["ADD", 3],
|
13
|
+
["SUB", 4],
|
14
|
+
["MUL", 5],
|
15
|
+
["DIV", 6],
|
16
|
+
["POWER", 7],
|
17
|
+
["PERCENT", 8],
|
18
|
+
["TRUE_CONST", 9],
|
19
|
+
["FALSE_CONST", 10],
|
20
|
+
["STR_CONST", 11],
|
21
|
+
["INT_CONST", 12],
|
22
|
+
["NUM_CONST", 13],
|
23
|
+
["REF2D", 14],
|
24
|
+
["COLON", 15],
|
25
|
+
["LT", 16],
|
26
|
+
["GT", 17],
|
27
|
+
["NE", 18],
|
28
|
+
["LE", 19],
|
29
|
+
["GE", 20],
|
30
|
+
["SEMICOLON", 21],
|
31
|
+
["COMMA", 22],
|
32
|
+
["LP", 23],
|
33
|
+
["RP", 24],
|
34
|
+
["BANG", 25],
|
35
|
+
["DIGIT", 26],
|
36
|
+
["NAME", 27],
|
37
|
+
["QUOTENAME", 28],
|
38
|
+
["FUNC_IF", 29],
|
39
|
+
["FUNC_CHOOSE", 30]
|
40
|
+
].inject({}) { |hash, pair|
|
41
|
+
name = pair[0]
|
42
|
+
index = pair[1] + 3 # hardcoded for now... no way to get this value from ANTLR
|
43
|
+
|
44
|
+
if name[0] == ?'
|
45
|
+
hash[:"T__#{index}"] = index
|
46
|
+
else
|
47
|
+
hash[:"#{name}"] = index
|
48
|
+
end
|
49
|
+
|
50
|
+
hash
|
51
|
+
}
|
52
|
+
|
53
|
+
TOKENS[:EOF] = -1
|
54
|
+
|
55
|
+
def initialize(input)
|
56
|
+
if input.respond_to?(:to_str) || input.respond_to?(:read)
|
57
|
+
input = ExcelFormulaLexer.new(input)
|
58
|
+
end
|
59
|
+
|
60
|
+
@lexer = input
|
61
|
+
@input = TokenStream.new(input)
|
62
|
+
@backtracking = 0
|
63
|
+
@failed = false
|
64
|
+
|
65
|
+
|
66
|
+
@rpn = ''
|
67
|
+
@sheet_references = []
|
68
|
+
@xcall_references = []
|
69
|
+
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
# 22:1: formula : expr[\"V\"] ;
|
74
|
+
def formula()
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
# 23:7: expr[\"V\"]
|
79
|
+
expr("V")
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
# 26:1: expr[arg_type] : prec0_expr[arg_type] ( ( EQ ) prec0_expr[arg_type] )* ;
|
87
|
+
def expr(arg_type)
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
# 27:7: prec0_expr[arg_type] ( ( EQ ) prec0_expr[arg_type] )*
|
92
|
+
prec0_expr(arg_type)
|
93
|
+
|
94
|
+
# 28:9: ( ( EQ ) prec0_expr[arg_type] )*
|
95
|
+
while true
|
96
|
+
alt1 = 2
|
97
|
+
#
|
98
|
+
look_ahead1_0 = look_ahead(1)
|
99
|
+
if look_ahead1_0 == :EQ
|
100
|
+
alt1 = 1
|
101
|
+
end
|
102
|
+
case alt1
|
103
|
+
when 1
|
104
|
+
# 29:13: ( EQ ) prec0_expr[arg_type]
|
105
|
+
# 30:19: EQ
|
106
|
+
match(:EQ)
|
107
|
+
op = [PTGEQ].pack('C')
|
108
|
+
prec0_expr(arg_type)
|
109
|
+
|
110
|
+
@rpn += op
|
111
|
+
else
|
112
|
+
break
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
# 42:1: prec0_expr[arg_type] : prec1_expr[arg_type] ( ( CONCAT ) prec1_expr[arg_type] )* ;
|
121
|
+
def prec0_expr(arg_type)
|
122
|
+
|
123
|
+
|
124
|
+
|
125
|
+
# 43:7: prec1_expr[arg_type] ( ( CONCAT ) prec1_expr[arg_type] )*
|
126
|
+
prec1_expr(arg_type)
|
127
|
+
|
128
|
+
# 44:9: ( ( CONCAT ) prec1_expr[arg_type] )*
|
129
|
+
while true
|
130
|
+
alt2 = 2
|
131
|
+
#
|
132
|
+
look_ahead2_0 = look_ahead(1)
|
133
|
+
if look_ahead2_0 == :CONCAT
|
134
|
+
alt2 = 1
|
135
|
+
end
|
136
|
+
case alt2
|
137
|
+
when 1
|
138
|
+
# 45:13: ( CONCAT ) prec1_expr[arg_type]
|
139
|
+
# 46:17: CONCAT
|
140
|
+
match(:CONCAT)
|
141
|
+
op = [PTGCONCAT].pack('C')
|
142
|
+
prec1_expr(arg_type)
|
143
|
+
|
144
|
+
@rpn += op
|
145
|
+
else
|
146
|
+
break
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
# 52:1: prec1_expr[arg_type] : prec2_expr[arg_type] ( ( ADD | SUB ) prec2_expr[arg_type] )* ;
|
155
|
+
def prec1_expr(arg_type)
|
156
|
+
|
157
|
+
|
158
|
+
|
159
|
+
# 53:7: prec2_expr[arg_type] ( ( ADD | SUB ) prec2_expr[arg_type] )*
|
160
|
+
prec2_expr(arg_type)
|
161
|
+
|
162
|
+
# 54:9: ( ( ADD | SUB ) prec2_expr[arg_type] )*
|
163
|
+
while true
|
164
|
+
alt4 = 2
|
165
|
+
#
|
166
|
+
look_ahead4_0 = look_ahead(1)
|
167
|
+
if (TOKENS[look_ahead4_0] >= 6 && TOKENS[look_ahead4_0] <= 7)
|
168
|
+
alt4 = 1
|
169
|
+
end
|
170
|
+
case alt4
|
171
|
+
when 1
|
172
|
+
# 55:13: ( ADD | SUB ) prec2_expr[arg_type]
|
173
|
+
# 55:13: ( ADD | SUB )
|
174
|
+
alt3 = 2
|
175
|
+
#
|
176
|
+
look_ahead3_0 = look_ahead(1)
|
177
|
+
if look_ahead3_0 == :ADD
|
178
|
+
alt3 = 1
|
179
|
+
elsif look_ahead3_0 == :SUB
|
180
|
+
alt3 = 2
|
181
|
+
else
|
182
|
+
raise "Expected: "
|
183
|
+
end
|
184
|
+
case alt3
|
185
|
+
when 1
|
186
|
+
# 56:19: ADD
|
187
|
+
match(:ADD)
|
188
|
+
op = [PTGADD].pack('C')
|
189
|
+
when 2
|
190
|
+
# 57:19: SUB
|
191
|
+
match(:SUB)
|
192
|
+
op = [PTGSUB].pack('C')
|
193
|
+
end
|
194
|
+
prec2_expr(arg_type)
|
195
|
+
|
196
|
+
@rpn += op
|
197
|
+
else
|
198
|
+
break
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
|
203
|
+
|
204
|
+
end
|
205
|
+
|
206
|
+
# 64:1: prec2_expr[arg_type] : prec3_expr[arg_type] ( ( MUL | DIV ) prec3_expr[arg_type] )* ;
|
207
|
+
def prec2_expr(arg_type)
|
208
|
+
|
209
|
+
|
210
|
+
|
211
|
+
# 65:7: prec3_expr[arg_type] ( ( MUL | DIV ) prec3_expr[arg_type] )*
|
212
|
+
prec3_expr(arg_type)
|
213
|
+
|
214
|
+
# 66:9: ( ( MUL | DIV ) prec3_expr[arg_type] )*
|
215
|
+
while true
|
216
|
+
alt6 = 2
|
217
|
+
#
|
218
|
+
look_ahead6_0 = look_ahead(1)
|
219
|
+
if (TOKENS[look_ahead6_0] >= 8 && TOKENS[look_ahead6_0] <= 9)
|
220
|
+
alt6 = 1
|
221
|
+
end
|
222
|
+
case alt6
|
223
|
+
when 1
|
224
|
+
# 67:13: ( MUL | DIV ) prec3_expr[arg_type]
|
225
|
+
# 67:13: ( MUL | DIV )
|
226
|
+
alt5 = 2
|
227
|
+
#
|
228
|
+
look_ahead5_0 = look_ahead(1)
|
229
|
+
if look_ahead5_0 == :MUL
|
230
|
+
alt5 = 1
|
231
|
+
elsif look_ahead5_0 == :DIV
|
232
|
+
alt5 = 2
|
233
|
+
else
|
234
|
+
raise "Expected: "
|
235
|
+
end
|
236
|
+
case alt5
|
237
|
+
when 1
|
238
|
+
# 68:19: MUL
|
239
|
+
match(:MUL)
|
240
|
+
op = [PTGMUL].pack('C')
|
241
|
+
when 2
|
242
|
+
# 69:19: DIV
|
243
|
+
match(:DIV)
|
244
|
+
op = [PTGDIV].pack('C')
|
245
|
+
end
|
246
|
+
prec3_expr(arg_type)
|
247
|
+
|
248
|
+
@rpn += op
|
249
|
+
else
|
250
|
+
break
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
|
255
|
+
|
256
|
+
end
|
257
|
+
|
258
|
+
# 75:1: prec3_expr[arg_type] : prec5_expr[arg_type] ( ( POWER ) prec5_expr[arg_type] )* ;
|
259
|
+
def prec3_expr(arg_type)
|
260
|
+
|
261
|
+
|
262
|
+
|
263
|
+
# 76:7: prec5_expr[arg_type] ( ( POWER ) prec5_expr[arg_type] )*
|
264
|
+
prec5_expr(arg_type)
|
265
|
+
|
266
|
+
# 77:9: ( ( POWER ) prec5_expr[arg_type] )*
|
267
|
+
while true
|
268
|
+
alt7 = 2
|
269
|
+
#
|
270
|
+
look_ahead7_0 = look_ahead(1)
|
271
|
+
if look_ahead7_0 == :POWER
|
272
|
+
alt7 = 1
|
273
|
+
end
|
274
|
+
case alt7
|
275
|
+
when 1
|
276
|
+
# 78:13: ( POWER ) prec5_expr[arg_type]
|
277
|
+
# 79:17: POWER
|
278
|
+
match(:POWER)
|
279
|
+
op = [PTGPOWER].pack('C')
|
280
|
+
prec5_expr(arg_type)
|
281
|
+
|
282
|
+
@rpn += op
|
283
|
+
else
|
284
|
+
break
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
|
289
|
+
|
290
|
+
end
|
291
|
+
|
292
|
+
# 85:1: prec4_expr[arg_type] : prec5_expr[arg_type] ( PERCENT )? ;
|
293
|
+
def prec4_expr(arg_type)
|
294
|
+
|
295
|
+
|
296
|
+
|
297
|
+
# 86:7: prec5_expr[arg_type] ( PERCENT )?
|
298
|
+
prec5_expr(arg_type)
|
299
|
+
|
300
|
+
# 87:9: ( PERCENT )?
|
301
|
+
alt8 = 2
|
302
|
+
#
|
303
|
+
look_ahead8_0 = look_ahead(1)
|
304
|
+
|
305
|
+
if look_ahead8_0 == :PERCENT
|
306
|
+
alt8 = 1
|
307
|
+
end
|
308
|
+
case alt8
|
309
|
+
when 1
|
310
|
+
# 88:13: PERCENT
|
311
|
+
match(:PERCENT)
|
312
|
+
@rpn += [PTGPERCENT].pack('C')
|
313
|
+
end
|
314
|
+
|
315
|
+
|
316
|
+
|
317
|
+
end
|
318
|
+
|
319
|
+
# 92:1: prec5_expr[arg_type] : ( primary[arg_type] | SUB primary[arg_type] );
|
320
|
+
def prec5_expr(arg_type)
|
321
|
+
|
322
|
+
|
323
|
+
|
324
|
+
# 93:5: ( primary[arg_type] | SUB primary[arg_type] )
|
325
|
+
alt9 = 2
|
326
|
+
#
|
327
|
+
look_ahead9_0 = look_ahead(1)
|
328
|
+
if (TOKENS[look_ahead9_0] >= 12 && TOKENS[look_ahead9_0] <= 17)
|
329
|
+
alt9 = 1
|
330
|
+
elsif look_ahead9_0 == :SUB
|
331
|
+
alt9 = 2
|
332
|
+
else
|
333
|
+
raise "Expected: "
|
334
|
+
end
|
335
|
+
case alt9
|
336
|
+
when 1
|
337
|
+
# 93:7: primary[arg_type]
|
338
|
+
primary(arg_type)
|
339
|
+
|
340
|
+
when 2
|
341
|
+
# 94:7: SUB primary[arg_type]
|
342
|
+
match(:SUB)
|
343
|
+
primary(arg_type)
|
344
|
+
|
345
|
+
@rpn += [PTGUMINUS].pack('C')
|
346
|
+
end
|
347
|
+
|
348
|
+
|
349
|
+
|
350
|
+
end
|
351
|
+
|
352
|
+
# 97:1: primary[arg_type] : ( TRUE_CONST | FALSE_CONST | str_tok= STR_CONST | int_tok= INT_CONST | num_tok= NUM_CONST | ref2d_tok= REF2D | ref2d1_tok= REF2D COLON ref2d2_tok= REF2D );
|
353
|
+
def primary(arg_type)
|
354
|
+
_str_tok = nil
|
355
|
+
_int_tok = nil
|
356
|
+
_num_tok = nil
|
357
|
+
_ref2d_tok = nil
|
358
|
+
_ref2d1_tok = nil
|
359
|
+
_ref2d2_tok = nil
|
360
|
+
|
361
|
+
|
362
|
+
|
363
|
+
|
364
|
+
# 98:5: ( TRUE_CONST | FALSE_CONST | str_tok= STR_CONST | int_tok= INT_CONST | num_tok= NUM_CONST | ref2d_tok= REF2D | ref2d1_tok= REF2D COLON ref2d2_tok= REF2D )
|
365
|
+
alt10 = 7
|
366
|
+
alt10 = DFA10.predict(self, @input)
|
367
|
+
case alt10
|
368
|
+
when 1
|
369
|
+
# 98:7: TRUE_CONST
|
370
|
+
match(:TRUE_CONST)
|
371
|
+
|
372
|
+
@rpn += [PTGBOOL, 1].pack("C2")
|
373
|
+
|
374
|
+
when 2
|
375
|
+
# 102:7: FALSE_CONST
|
376
|
+
match(:FALSE_CONST)
|
377
|
+
|
378
|
+
@rpn += [PTGBOOL, 0].pack("C2")
|
379
|
+
|
380
|
+
when 3
|
381
|
+
# 106:7: str_tok= STR_CONST
|
382
|
+
_str_tok = @input.look_ahead(1)
|
383
|
+
match(:STR_CONST)
|
384
|
+
|
385
|
+
@rpn += [PTGSTR].pack('C') + upack1(str_tok.text[1, -1]) #TODO
|
386
|
+
|
387
|
+
when 4
|
388
|
+
# 110:7: int_tok= INT_CONST
|
389
|
+
_int_tok = @input.look_ahead(1)
|
390
|
+
match(:INT_CONST)
|
391
|
+
|
392
|
+
int_value = int_tok.text.to_i
|
393
|
+
if int_value <= 65535
|
394
|
+
@rpn += [PTGINT, int_value].pack("Cv")
|
395
|
+
else
|
396
|
+
@rpn += [PTGNUM, int_value.to_f].pack("CE")
|
397
|
+
end
|
398
|
+
|
399
|
+
when 5
|
400
|
+
# 119:7: num_tok= NUM_CONST
|
401
|
+
_num_tok = @input.look_ahead(1)
|
402
|
+
match(:NUM_CONST)
|
403
|
+
|
404
|
+
@rpn += [ptgNum, num_tok.text.to_f].pack("CE")
|
405
|
+
|
406
|
+
when 6
|
407
|
+
# 123:7: ref2d_tok= REF2D
|
408
|
+
_ref2d_tok = @input.look_ahead(1)
|
409
|
+
match(:REF2D)
|
410
|
+
|
411
|
+
r, c = Utils.cell_to_packed_rowcol(ref2d_tok.text) # TODO
|
412
|
+
ptg = PTGREFR + RVA_DELTA[arg_type]
|
413
|
+
@rpn += [ptg, r, c].pack("Cv2")
|
414
|
+
|
415
|
+
when 7
|
416
|
+
# 129:7: ref2d1_tok= REF2D COLON ref2d2_tok= REF2D
|
417
|
+
_ref2d1_tok = @input.look_ahead(1)
|
418
|
+
match(:REF2D)
|
419
|
+
match(:COLON)
|
420
|
+
_ref2d2_tok = @input.look_ahead(1)
|
421
|
+
match(:REF2D)
|
422
|
+
|
423
|
+
r1, c1 = Utils.cell_to_packed_rowcol(ref2d1_tok.text) #TODO
|
424
|
+
r2, c2 = Utils.cell_to_packed_rowcol(ref2d2_tok.text) #TODO
|
425
|
+
ptg = PTGAREAR + RVA_DELTA[arg_type]
|
426
|
+
self.rpn += struct.pack("Cv4", ptg, r1, r2, c1, c2)
|
427
|
+
|
428
|
+
end
|
429
|
+
|
430
|
+
|
431
|
+
|
432
|
+
end
|
433
|
+
|
434
|
+
|
435
|
+
attr_accessor :rpn
|
436
|
+
|
437
|
+
|
438
|
+
private
|
439
|
+
|
440
|
+
class TokenStream
|
441
|
+
attr_reader :index
|
442
|
+
|
443
|
+
def initialize(input)
|
444
|
+
@buffer = []
|
445
|
+
@input = input
|
446
|
+
@channel = nil
|
447
|
+
|
448
|
+
@index = 0;
|
449
|
+
end
|
450
|
+
|
451
|
+
# returns a Token
|
452
|
+
def look_ahead(pos)
|
453
|
+
offset = @index + pos - 1
|
454
|
+
|
455
|
+
while @buffer[-1] != :EOF && @buffer.length < offset + 1
|
456
|
+
token = @input.next_token
|
457
|
+
if token == :EOF || token.channel == @channel
|
458
|
+
@buffer << token
|
459
|
+
end
|
460
|
+
end
|
461
|
+
|
462
|
+
offset = -1 if offset >= @buffer.length
|
463
|
+
if offset < @buffer.length
|
464
|
+
@buffer[offset]
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
def mark
|
469
|
+
@state = { :index => @index }
|
470
|
+
return 0
|
471
|
+
end
|
472
|
+
|
473
|
+
def rewind(marker)
|
474
|
+
@index = @state[:index]
|
475
|
+
end
|
476
|
+
|
477
|
+
def consume
|
478
|
+
look_ahead(1) # force a read from the input if necessary
|
479
|
+
@index = @index + 1
|
480
|
+
end
|
481
|
+
end
|
482
|
+
|
483
|
+
def match(token = nil)
|
484
|
+
if token.nil? || look_ahead(1) == token
|
485
|
+
@input.consume
|
486
|
+
@failed = false
|
487
|
+
return
|
488
|
+
elsif @backtracking > 0
|
489
|
+
@failed = true
|
490
|
+
else
|
491
|
+
raise "Expected #{token}"
|
492
|
+
end
|
493
|
+
end
|
494
|
+
|
495
|
+
def look_ahead(k)
|
496
|
+
token = @input.look_ahead(k)
|
497
|
+
if token != :EOF
|
498
|
+
token = token.token_type
|
499
|
+
end
|
500
|
+
|
501
|
+
token
|
502
|
+
end
|
503
|
+
|
504
|
+
|
505
|
+
class DFA
|
506
|
+
def initialize(eot, eof, min, max, accept, special, transition)
|
507
|
+
@eot = eot
|
508
|
+
@eof = eof
|
509
|
+
@min = min
|
510
|
+
@max = max
|
511
|
+
@accept = accept
|
512
|
+
@special = special
|
513
|
+
@transition = transition
|
514
|
+
end
|
515
|
+
|
516
|
+
def predict(parser, input)
|
517
|
+
mark = input.mark()
|
518
|
+
s = 0 # we always start at s0
|
519
|
+
begin
|
520
|
+
loop do
|
521
|
+
special_state = @special[s]
|
522
|
+
if special_state >= 0
|
523
|
+
s = parser.special_state_transition(special_state)
|
524
|
+
input.consume()
|
525
|
+
next
|
526
|
+
end
|
527
|
+
|
528
|
+
if @accept[s] >= 1
|
529
|
+
return @accept[s]
|
530
|
+
end
|
531
|
+
|
532
|
+
# look for a normal char transition
|
533
|
+
c = input.look_ahead(1).to_i
|
534
|
+
if c != :EOF && c >= @min[s] && c <= @max[s]
|
535
|
+
next_state = @transition[s][c - @min[s]] # move to next state
|
536
|
+
if next_state < 0
|
537
|
+
# was in range but not a normal transition
|
538
|
+
# must check EOT, which is like the else clause.
|
539
|
+
# eot[s]>=0 indicates that an EOT edge goes to another
|
540
|
+
# state.
|
541
|
+
if @eot[s] >= 0 # EOT Transition to accept state?
|
542
|
+
s = @eot[s]
|
543
|
+
input.consume()
|
544
|
+
next
|
545
|
+
end
|
546
|
+
raise "No viable alt"
|
547
|
+
end
|
548
|
+
s = next_state
|
549
|
+
input.consume()
|
550
|
+
next
|
551
|
+
end
|
552
|
+
if @eot[s] >= 0 # EOT Transition?
|
553
|
+
s = @eot[s]
|
554
|
+
input.consume()
|
555
|
+
next
|
556
|
+
end
|
557
|
+
if c == :EOF && @eof[s] >= 0 # EOF Transition to accept state?
|
558
|
+
return @accept[@eof[s]]
|
559
|
+
end
|
560
|
+
|
561
|
+
# not in range and not EOF/EOT, must be invalid symbol
|
562
|
+
raise "No viable alt"
|
563
|
+
end
|
564
|
+
ensure
|
565
|
+
input.rewind(mark)
|
566
|
+
end
|
567
|
+
end
|
568
|
+
end
|
569
|
+
|
570
|
+
DFA10 = DFA.new(
|
571
|
+
[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
|
572
|
+
[-1,-1,-1,-1,-1,-1,8,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
|
573
|
+
[12,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0],
|
574
|
+
[17,0,0,0,0,0,18,0,0,0,0,0,0,0,0,0,0],
|
575
|
+
[-1,1,2,3,4,5,-1,7,6,-1,-1,-1,-1,-1,-1,-1,-1],
|
576
|
+
[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
|
577
|
+
[
|
578
|
+
[1,2,3,4,5,6],
|
579
|
+
[],
|
580
|
+
[],
|
581
|
+
[],
|
582
|
+
[],
|
583
|
+
[],
|
584
|
+
[8,8,8,8,8,8,8,8,-1,-1,-1,-1,-1,-1,7],
|
585
|
+
[],
|
586
|
+
[],
|
587
|
+
[],
|
588
|
+
[],
|
589
|
+
[],
|
590
|
+
[],
|
591
|
+
[],
|
592
|
+
[],
|
593
|
+
[],
|
594
|
+
[]
|
595
|
+
])
|
596
|
+
|
597
|
+
def special_state_transition(s)
|
598
|
+
-1
|
599
|
+
end
|
600
|
+
|
601
|
+
public :special_state_transition
|
602
|
+
end
|
File without changes
|
File without changes
|
@@ -119,52 +119,20 @@ class MulBlankCell < Cell
|
|
119
119
|
end
|
120
120
|
|
121
121
|
class FormulaCell < Cell
|
122
|
-
attr_accessor :result
|
123
|
-
|
124
122
|
def initialize(parent, index, format_index, formula, calc_flags = 0)
|
125
|
-
@str = nil
|
126
123
|
@parent = parent
|
127
124
|
@index = index
|
128
125
|
@format_index = format_index
|
129
|
-
@options = formula.options.nil? ? parent.formula_options : formula.options
|
130
126
|
@formula = formula
|
131
|
-
@result = convert_formula_value_to_result(formula.default)
|
132
127
|
@calc_flags = calc_flags
|
133
128
|
end
|
134
129
|
|
135
130
|
def to_biff
|
136
|
-
args = [@parent.index, @index, @format_index, @
|
137
|
-
|
138
|
-
formula_data += StringRecord.new(@str).to_biff if @str
|
139
|
-
formula_data
|
140
|
-
end
|
141
|
-
|
142
|
-
# TODO move this elsewhere, either Utilities or Formula ?
|
143
|
-
def convert_formula_value_to_result(value)
|
144
|
-
@str = ''
|
145
|
-
if value.is_a?(Numeric)
|
146
|
-
ret = [value].pack('E')
|
147
|
-
else
|
148
|
-
case value
|
149
|
-
when TrueClass, FalseClass
|
150
|
-
ret = [0x01, value ? 0x01 : 0x00].pack('CxC3x')
|
151
|
-
when ErrorCode
|
152
|
-
ret = [0x02, value.to_i].pack('CxC3x')
|
153
|
-
when String
|
154
|
-
ret = [0x00, 'Cx5']
|
155
|
-
@str = value # TODO convert to unicode
|
156
|
-
when NilClass
|
157
|
-
ret = [0x03, 'Cx5']
|
158
|
-
else
|
159
|
-
raise
|
160
|
-
end
|
161
|
-
ret += [0xFFFF].pack('C')
|
162
|
-
end
|
163
|
-
ret.unpack('Q')[0]
|
131
|
+
args = [@parent.index, @index, @format_index, @formula.to_biff, @calc_flags]
|
132
|
+
FormulaRecord.new(*args).to_biff
|
164
133
|
end
|
165
134
|
end
|
166
135
|
|
167
|
-
|
168
136
|
class BooleanCell < Cell
|
169
137
|
def initialize(parent, index, format_index, number)
|
170
138
|
@parent = parent
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class ExcelFormula
|
2
|
+
NO_CALCS=0x00
|
3
|
+
RECALC_ALWAYS=0x01
|
4
|
+
CALC_ON_OPEN=0x02
|
5
|
+
PART_OF_SHARED_FORMULA=0x08
|
6
|
+
|
7
|
+
attr_reader :parser
|
8
|
+
|
9
|
+
def initialize(formula_string)
|
10
|
+
@parser = ExcelFormulaParser.new(formula_string)
|
11
|
+
# begin
|
12
|
+
@parser.formula
|
13
|
+
# rescue RuntimeError => e
|
14
|
+
# puts e
|
15
|
+
# raise "invalid Excel formula"
|
16
|
+
# end
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_biff
|
20
|
+
rpn = @parser.rpn
|
21
|
+
[rpn.size].pack('v') + rpn
|
22
|
+
end
|
23
|
+
end
|
File without changes
|