# ExcelFormulaLexer (ExcelFormula.g)
# Generated by ANTLR 3.1.2-2008-10-21 on 2009-06-15 23:03:59
class ExcelFormulaLexer
require 'stringio'
COMMA=25
TRUE_CONST=12
PERCENT=11
POWER=10
FUNC_CHOOSE=33
BANG=28
EQ=4
QUOTENAME=31
LT=19
NE=21
GT=20
FUNC_IF=32
RP=27
FALSE_CONST=13
LP=26
GE=23
MUL=8
NUM_CONST=16
REF2D=17
SEMICOLON=24
CONCAT=5
EOF=-1
LE=22
INT_CONST=15
STR_CONST=14
COLON=18
DIV=9
DIGIT=29
SUB=7
NAME=30
ADD=6
def initialize(input)
input = StringIO.new(input) if input.respond_to?(:to_str)
@input = CharStream.new(input)
@backtracking = 0
@failed = false
end
def next_token
# TODO: catch exceptions
@token = nil
@channel = nil
@text = nil
@start = @input.index
@line = @input.line
@pos = @input.column
@type = nil
@type_int = nil
return :EOF if @input.look_ahead(1) == :EOF
match_Tokens()
if @token == nil
@text ||= @input.substring(@start, @input.index - 1)
@token = Token.new(@type, @type_int, @line, @pos, @text, @channel)
end
return @token
end
class Token
attr_reader :token_type
attr_reader :int_type
attr_reader :line
attr_reader :pos
attr_reader :text
attr_reader :channel
def initialize(token_type, int_type, line, pos, text, channel = nil)
@token_type = token_type
@int_type = int_type
@line = line
@pos = pos
@text = text
@channel = channel
end
alias :to_i :int_type
end
private
class CharStream
attr_reader :line
attr_reader :column
attr_reader :index
def initialize(input)
@buffer = ""
@input = input
@line = 1
@column = 0
@index = 0;
end
# returns a Fixnum between 0 and 0xFFFF or :EOF
def look_ahead(pos)
offset = @index + pos - 1
if @buffer.length < offset + 1
char = @input.read(offset + 1 - @buffer.length)
@buffer << char if not char.nil?
end
if offset < @buffer.length
@buffer[offset]
else
:EOF
end
end
def mark
@state = { :index => @index, :line => @line, :column => @column }
return 0
end
def rewind(marker)
@index = @state[:index]
@line = @state[:line]
@column = @state[:column]
end
def consume
look_ahead(1) # force a read from the input if necessary
@column = @column + 1
if @buffer[@index] == ?\n
@line = @line + 1
@column = 0
end
@index = @index + 1
end
def substring(start, stop)
@buffer.slice(start, stop - start + 1)
end
end
def match(value = nil)
@failed = false
case
when value.nil?
@input.consume()
when value.respond_to?(:to_str)
catch(:done) do
value.each_byte do |c|
@failed ||= !(@input.look_ahead(1) == c)
@input.consume() if !@failed
throw :done if @failed
end
end
else
@failed = !(@input.look_ahead(1) == value)
@input.consume() if !@failed
end
if @failed && @backtracking <= 0
raise "Expected #{value.respond_to?(:chr) ? value.chr : value}"
end
end
def match_range(from, to)
char = @input.look_ahead(1)
if char != :EOF && (char >= from || char <= to)
@failed = false
match()
elsif @backtracking > 0
@failed = true
else
raise "Expected [#{from.chr}..#{to.chr}]"
end
end
def match_EQ()
# 332:5: '='
match(?=)
end
def match_LT()
@type = :LT
@type_int = LT
# 333:5: '<'
match(?<)
end
def match_GT()
@type = :GT
@type_int = GT
# 334:5: '>'
match(?>)
end
def match_NE()
@type = :NE
@type_int = NE
# 335:5: '<>'
match("<>")
end
def match_LE()
@type = :LE
@type_int = LE
# 336:5: '<='
match("<=")
end
def match_GE()
@type = :GE
@type_int = GE
# 337:5: '>='
match(">=")
end
def match_ADD()
@type = :ADD
@type_int = ADD
# 339:6: '+'
match(?+)
end
def match_SUB()
@type = :SUB
@type_int = SUB
# 340:6: '-'
match(?-)
end
def match_MUL()
@type = :MUL
@type_int = MUL
# 341:6: '*'
match(?*)
end
def match_DIV()
@type = :DIV
@type_int = DIV
# 342:6: '/'
match(?/)
end
def match_COLON()
@type = :COLON
@type_int = COLON
# 344:8: ':'
match(?:)
end
def match_SEMICOLON()
@type = :SEMICOLON
@type_int = SEMICOLON
# 345:12: ';'
match(?;)
end
def match_COMMA()
@type = :COMMA
@type_int = COMMA
# 346:8: ','
match(?,)
end
def match_LP()
@type = :LP
@type_int = LP
# 348:5: '('
match(?()
end
def match_RP()
@type = :RP
@type_int = RP
# 349:5: ')'
match(?))
end
def match_CONCAT()
@type = :CONCAT
@type_int = CONCAT
# 350:9: '&'
match(?&)
end
def match_PERCENT()
@type = :PERCENT
@type_int = PERCENT
# 351:10: '%'
match(?%)
end
def match_POWER()
@type = :POWER
@type_int = POWER
# 352:8: '^'
match(?^)
end
def match_BANG()
@type = :BANG
@type_int = BANG
# 353:7: '!'
match(?!)
end
def match_DIGIT()
@type = :DIGIT
@type_int = DIGIT
# 355:8: '0' .. '9'
match_range(?0, ?9)
end
def match_INT_CONST()
@type = :INT_CONST
@type_int = INT_CONST
# 357:12: ( DIGIT )+
# 357:12: ( DIGIT )+
matchedOnce1 = false
while true
alt1 = 2
#
look_ahead1_0 = @input.look_ahead(1)
look_ahead1_0 = -1 if look_ahead1_0 == :EOF
if (look_ahead1_0 >= ?0 && look_ahead1_0 <= ?9)
alt1 = 1
end
case alt1
when 1
# 357:12: DIGIT
match_DIGIT()
else
break
end
matchedOnce1 = true
end
if !matchedOnce1
raise "Expected at least one match: 357:12: ( DIGIT )+"
end
end
def match_NUM_CONST()
@type = :NUM_CONST
@type_int = NUM_CONST
# 358:12: ( DIGIT )* '.' ( DIGIT )+ ( ( 'E' | 'e' ) ( '+' | '-' )? ( DIGIT )+ )?
# 358:12: ( DIGIT )*
while true
alt2 = 2
#
look_ahead2_0 = @input.look_ahead(1)
look_ahead2_0 = -1 if look_ahead2_0 == :EOF
if (look_ahead2_0 >= ?0 && look_ahead2_0 <= ?9)
alt2 = 1
end
case alt2
when 1
# 358:12: DIGIT
match_DIGIT()
else
break
end
end
match(?.)
# 358:23: ( DIGIT )+
matchedOnce3 = false
while true
alt3 = 2
#
look_ahead3_0 = @input.look_ahead(1)
look_ahead3_0 = -1 if look_ahead3_0 == :EOF
if (look_ahead3_0 >= ?0 && look_ahead3_0 <= ?9)
alt3 = 1
end
case alt3
when 1
# 358:23: DIGIT
match_DIGIT()
else
break
end
matchedOnce3 = true
end
if !matchedOnce3
raise "Expected at least one match: 358:23: ( DIGIT )+"
end
# 358:30: ( ( 'E' | 'e' ) ( '+' | '-' )? ( DIGIT )+ )?
alt6 = 2
#
look_ahead6_0 = @input.look_ahead(1)
look_ahead6_0 = -1 if look_ahead6_0 == :EOF
if look_ahead6_0 == ?E || look_ahead6_0 == ?e
alt6 = 1
end
case alt6
when 1
# 358:31: ( 'E' | 'e' ) ( '+' | '-' )? ( DIGIT )+
if @input.look_ahead(1) == ?E || @input.look_ahead(1) == ?e
match()
else
raise "Expected set"
end
# 358:41: ( '+' | '-' )?
alt4 = 2
#
look_ahead4_0 = @input.look_ahead(1)
look_ahead4_0 = -1 if look_ahead4_0 == :EOF
if look_ahead4_0 == ?+ || look_ahead4_0 == ?-
alt4 = 1
end
case alt4
when 1
#
if @input.look_ahead(1) == ?+ || @input.look_ahead(1) == ?-
match()
else
raise "Expected set"
end
end
# 358:52: ( DIGIT )+
matchedOnce5 = false
while true
alt5 = 2
#
look_ahead5_0 = @input.look_ahead(1)
look_ahead5_0 = -1 if look_ahead5_0 == :EOF
if (look_ahead5_0 >= ?0 && look_ahead5_0 <= ?9)
alt5 = 1
end
case alt5
when 1
# 358:52: DIGIT
match_DIGIT()
else
break
end
matchedOnce5 = true
end
if !matchedOnce5
raise "Expected at least one match: 358:52: ( DIGIT )+"
end
end
end
def match_STR_CONST()
@type = :STR_CONST
@type_int = STR_CONST
# 359:12: '\"' ~ '\"' '\"'
match(?")
if (@input.look_ahead(1) >= 0x0000 && @input.look_ahead(1) <= ?!) || (@input.look_ahead(1) >= ?# && @input.look_ahead(1) <= 0x00FF)
match()
else
raise "Expected set"
end
match(?")
end
def match_REF2D()
@type = :REF2D
@type_int = REF2D
# 360:8: ( '$' )? ( 'A' .. 'I' )? ( 'A' .. 'Z' ) ( '$' )? ( DIGIT )+
# 360:8: ( '$' )?
alt7 = 2
#
look_ahead7_0 = @input.look_ahead(1)
look_ahead7_0 = -1 if look_ahead7_0 == :EOF
if look_ahead7_0 == ?$
alt7 = 1
end
case alt7
when 1
# 360:8: '$'
match(?$)
end
# 360:13: ( 'A' .. 'I' )?
alt8 = 2
#
look_ahead8_0 = @input.look_ahead(1)
look_ahead8_0 = -1 if look_ahead8_0 == :EOF
if (look_ahead8_0 >= ?A && look_ahead8_0 <= ?I)
#
look_ahead8_1 = @input.look_ahead(2)
look_ahead8_1 = -1 if look_ahead8_1 == :EOF
if (look_ahead8_1 >= ?A && look_ahead8_1 <= ?Z)
alt8 = 1
end
end
case alt8
when 1
# 360:14: 'A' .. 'I'
match_range(?A, ?I)
end
# 360:26: 'A' .. 'Z'
match_range(?A, ?Z)
# 360:36: ( '$' )?
alt9 = 2
#
look_ahead9_0 = @input.look_ahead(1)
look_ahead9_0 = -1 if look_ahead9_0 == :EOF
if look_ahead9_0 == ?$
alt9 = 1
end
case alt9
when 1
# 360:36: '$'
match(?$)
end
# 360:41: ( DIGIT )+
matchedOnce10 = false
while true
alt10 = 2
#
look_ahead10_0 = @input.look_ahead(1)
look_ahead10_0 = -1 if look_ahead10_0 == :EOF
if (look_ahead10_0 >= ?0 && look_ahead10_0 <= ?9)
alt10 = 1
end
case alt10
when 1
# 360:41: DIGIT
match_DIGIT()
else
break
end
matchedOnce10 = true
end
if !matchedOnce10
raise "Expected at least one match: 360:41: ( DIGIT )+"
end
end
def match_TRUE_CONST()
@type = :TRUE_CONST
@type_int = TRUE_CONST
# 361:13: ( 'T' | 't' ) ( 'R' | 'r' ) ( 'U' | 'u' ) ( 'E' | 'e' )
if @input.look_ahead(1) == ?T || @input.look_ahead(1) == ?t
match()
else
raise "Expected set"
end
if @input.look_ahead(1) == ?R || @input.look_ahead(1) == ?r
match()
else
raise "Expected set"
end
if @input.look_ahead(1) == ?U || @input.look_ahead(1) == ?u
match()
else
raise "Expected set"
end
if @input.look_ahead(1) == ?E || @input.look_ahead(1) == ?e
match()
else
raise "Expected set"
end
end
def match_FALSE_CONST()
@type = :FALSE_CONST
@type_int = FALSE_CONST
# 362:14: ( 'F' | 'f' ) ( 'A' | 'a' ) ( 'L' | 'l' ) ( 'S' | 's' ) ( 'E' | 'e' )
if @input.look_ahead(1) == ?F || @input.look_ahead(1) == ?f
match()
else
raise "Expected set"
end
if @input.look_ahead(1) == ?A || @input.look_ahead(1) == ?a
match()
else
raise "Expected set"
end
if @input.look_ahead(1) == ?L || @input.look_ahead(1) == ?l
match()
else
raise "Expected set"
end
if @input.look_ahead(1) == ?S || @input.look_ahead(1) == ?s
match()
else
raise "Expected set"
end
if @input.look_ahead(1) == ?E || @input.look_ahead(1) == ?e
match()
else
raise "Expected set"
end
end
def match_NAME()
@type = :NAME
@type_int = NAME
# 363:7: '\\w[\\.\\w]*'
match("w[.w]*")
end
def match_QUOTENAME()
@type = :QUOTENAME
@type_int = QUOTENAME
# 364:12: '\\'(?:[^\\']|\\'\\')*\\''
match("'(?:[^']|'')*'")
end
def match_FUNC_IF()
@type = :FUNC_IF
@type_int = FUNC_IF
# 365:10: 'IF'
match("IF")
end
def match_FUNC_CHOOSE()
@type = :FUNC_CHOOSE
@type_int = FUNC_CHOOSE
# 366:14: 'CHOOSE'
match("CHOOSE")
end
def match_Tokens()
# 1:8: ( LT | GT | NE | LE | GE | ADD | SUB | MUL | DIV | COLON | SEMICOLON | COMMA | LP | RP | CONCAT | PERCENT | POWER | BANG | DIGIT | INT_CONST | NUM_CONST | STR_CONST | REF2D | TRUE_CONST | FALSE_CONST | NAME | QUOTENAME | FUNC_IF | FUNC_CHOOSE )
alt11 = 29
alt11 = DFA11.predict(self, @input)
case alt11
when 1
# 1:10: LT
match_LT()
when 2
# 1:13: GT
match_GT()
when 3
# 1:16: NE
match_NE()
when 4
# 1:19: LE
match_LE()
when 5
# 1:22: GE
match_GE()
when 6
# 1:25: ADD
match_ADD()
when 7
# 1:29: SUB
match_SUB()
when 8
# 1:33: MUL
match_MUL()
when 9
# 1:37: DIV
match_DIV()
when 10
# 1:41: COLON
match_COLON()
when 11
# 1:47: SEMICOLON
match_SEMICOLON()
when 12
# 1:57: COMMA
match_COMMA()
when 13
# 1:63: LP
match_LP()
when 14
# 1:66: RP
match_RP()
when 15
# 1:69: CONCAT
match_CONCAT()
when 16
# 1:76: PERCENT
match_PERCENT()
when 17
# 1:84: POWER
match_POWER()
when 18
# 1:90: BANG
match_BANG()
when 19
# 1:95: DIGIT
match_DIGIT()
when 20
# 1:101: INT_CONST
match_INT_CONST()
when 21
# 1:111: NUM_CONST
match_NUM_CONST()
when 22
# 1:121: STR_CONST
match_STR_CONST()
when 23
# 1:131: REF2D
match_REF2D()
when 24
# 1:137: TRUE_CONST
match_TRUE_CONST()
when 25
# 1:148: FALSE_CONST
match_FALSE_CONST()
when 26
# 1:160: NAME
match_NAME()
when 27
# 1:165: QUOTENAME
match_QUOTENAME()
when 28
# 1:175: FUNC_IF
match_FUNC_IF()
when 29
# 1:183: FUNC_CHOOSE
match_FUNC_CHOOSE()
end
end
class DFA
def initialize(eot, eof, min, max, accept, special, transition)
@eot = eot
@eof = eof
@min = min
@max = max
@accept = accept
@special = special
@transition = transition
end
def predict(parser, input)
mark = input.mark()
s = 0 # we always start at s0
begin
loop do
special_state = @special[s]
if special_state >= 0
s = parser.special_state_transition(special_state)
input.consume()
next
end
if @accept[s] >= 1
return @accept[s]
end
# look for a normal char transition
c = input.look_ahead(1).to_i
if c != :EOF && c >= @min[s] && c <= @max[s]
next_state = @transition[s][c - @min[s]] # move to next state
if next_state < 0
# was in range but not a normal transition
# must check EOT, which is like the else clause.
# eot[s]>=0 indicates that an EOT edge goes to another
# state.
if @eot[s] >= 0 # EOT Transition to accept state?
s = @eot[s]
input.consume()
next
end
raise "No viable alt"
end
s = next_state
input.consume()
next
end
if @eot[s] >= 0 # EOT Transition?
s = @eot[s]
input.consume()
next
end
if c == :EOF && @eof[s] >= 0 # EOF Transition to accept state?
return @accept[@eof[s]]
end
# not in range and not EOF/EOT, must be invalid symbol
raise "No viable alt"
end
ensure
input.rewind(mark)
end
end
end
DFA11 = DFA.new(
[-1,30,32,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,33,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,38,-1,39,-1,-1,-1,-1],
[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
[0,61,61,0,0,0,0,0,0,0,0,0,0,0,0,0,46,0,0,0,36,36,0,36,0,0,0,36,
0,0,0,0,0,0,46,36,36,36,0,0,0],
[116,62,61,0,0,0,0,0,0,0,0,0,0,0,0,0,57,0,0,0,97,114,0,90,0,0,0,
90,0,0,0,0,0,0,57,108,57,79,0,0,0],
[-1,-1,-1,6,7,8,9,10,11,12,13,14,15,16,17,18,-1,21,22,23,-1,-1,24,
-1,25,26,27,-1,3,4,1,5,2,19,-1,-1,-1,-1,20,28,29],
[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
[
[25,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,15,18,-1,19,13,12,
26,10,11,5,3,9,4,17,6,16,16,16,16,16,16,16,16,16,16,7,8,
1,-1,2,-1,-1,19,19,27,19,19,20,19,19,23,19,19,19,19,19,
19,19,19,19,19,21,19,19,19,19,19,19,-1,-1,-1,14,-1,-1,-1,
-1,-1,-1,-1,24,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22],
[29,28],
[31],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[17,-1,34,34,34,34,34,34,34,34,34,34],
[],
[],
[],
[19,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,19,19,19,19,19,19,19,19,
19,19,-1,-1,-1,-1,-1,-1,-1,35,19,19,19,19,19,19,19,19,19,
19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,-1,-1,-1,
-1,-1,-1,24],
[19,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,19,19,19,19,19,19,19,19,
19,19,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,22,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,22],
[],
[19,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,19,19,19,19,19,19,19,19,
19,19,-1,-1,-1,-1,-1,-1,-1,19,19,19,19,19,36,19,19,19,19,
19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19],
[],
[],
[],
[19,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,19,19,19,19,19,19,19,19,
19,19,-1,-1,-1,-1,-1,-1,-1,19,19,19,19,19,19,19,37,19,19,
19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19],
[],
[],
[],
[],
[],
[],
[17,-1,34,34,34,34,34,34,34,34,34,34],
[19,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,19,19,19,19,19,19,19,19,
19,19,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,24,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,24],
[19,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,19,19,19,19,19,19,19,19,
19,19],
[19,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,19,19,19,19,19,19,19,19,
19,19,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,40],
[],
[],
[]
])
def special_state_transition(s)
-1
end
public :special_state_transition
end