# 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