diff options
author | keiju <keiju@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-07-09 11:17:17 +0000 |
---|---|---|
committer | keiju <keiju@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-07-09 11:17:17 +0000 |
commit | af064b04b1622897995fe1177aabfb60db90e6f7 (patch) | |
tree | 326cb343c08c55d2d93fa5223c01f940d3591f8b /lib/irb/ruby-lex.rb | |
parent | 93602810e93b5da1c7161fb4b5c1a4025434a9ce (diff) |
* irb 0.9
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2627 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/irb/ruby-lex.rb')
-rw-r--r-- | lib/irb/ruby-lex.rb | 161 |
1 files changed, 128 insertions, 33 deletions
diff --git a/lib/irb/ruby-lex.rb b/lib/irb/ruby-lex.rb index 3647617849..e96edef30b 100644 --- a/lib/irb/ruby-lex.rb +++ b/lib/irb/ruby-lex.rb @@ -1,6 +1,6 @@ # # irb/ruby-lex.rb - ruby lexcal analizer -# $Release Version: 0.7.3$ +# $Release Version: 0.9$ # $Revision$ # $Date$ # by Keiju ISHITSUKA([email protected]) @@ -50,6 +50,7 @@ class RubyLex @here_readed = [] @indent = 0 + @indent_stack = [] @skip_space = false @readed_auto_clean_up = false @@ -200,6 +201,7 @@ class RubyLex @ltype = nil @quoted = nil @indent = 0 + @indent_stack = [] @lex_state = EXPR_BEG @space_seen = false @here_header = false @@ -235,6 +237,7 @@ class RubyLex @exp_line_no = @line_no @indent = 0 + @indent_stack = [] prompt rescue TerminateLineInput initialize_input @@ -250,6 +253,7 @@ class RubyLex !@continue or tk.nil?) #p tk + #p @lex_state #p self end line = get_readed @@ -356,6 +360,11 @@ class RubyLex else @continue = false @lex_state = EXPR_BEG + until (@indent_stack.empty? || + [TkLPAREN, TkLBRACK, TkLBRACE, + TkfLPAREN, TkfLBRACK, TkfLBRACE].include?(@indent_stack.last)) + @indent_stack.pop + end end @here_header = false @here_readed = [] @@ -363,26 +372,44 @@ class RubyLex end @OP.def_rules("*", "**", - "!", "!=", "!~", "=", "==", "===", "=~", "<=>", "<", "<=", ">", ">=", ">>") do |op, io| - @lex_state = EXPR_BEG + case @lex_state + when EXPR_FNAME, EXPR_DOT + @lex_state = EXPR_ARG + else + @lex_state = EXPR_BEG + end + Token(op) + end + + @OP.def_rules("!", "!=", "!~") do + |op, io| + #@lex_state = EXPR_BEG Token(op) end @OP.def_rules("<<") do |op, io| + tk = nil if @lex_state != EXPR_END && @lex_state != EXPR_CLASS && (@lex_state != EXPR_ARG || @space_seen) c = peek(0) if /\S/ =~ c && (/["'`]/ =~ c || /[\w_]/ =~ c || c == "-") tk = identify_here_document end - else - tk = Token(op) + end + unless tk + tk = Token(op) + case @lex_state + when EXPR_FNAME, EXPR_DOT + @lex_state = EXPR_ARG + else + @lex_state = EXPR_BEG + end end tk end @@ -408,7 +435,7 @@ class RubyLex Token(TkQUESTION) else ch = getc - if @lex_state == EXPR_ARG && ch !~ /\s/ + if @lex_state == EXPR_ARG && ch =~ /\s/ ungetc @lex_state = EXPR_BEG; Token(TkQUESTION) @@ -437,11 +464,13 @@ class RubyLex end @OP.def_rule("+@", proc{@lex_state == EXPR_FNAME}) do - Token(TkUPLUS) + |op, io| + Token(op) end @OP.def_rule("-@", proc{@lex_state == EXPR_FNAME}) do - Token(TkUMINUS) + |op, io| + Token(op) end @OP.def_rules("+", "-") do @@ -488,6 +517,7 @@ class RubyLex |op, io| @lex_state = EXPR_END @indent -= 1 + @indent_stack.pop Token(op) end @@ -519,7 +549,7 @@ class RubyLex elsif peek(0) == '=' getc @lex_state = EXPR_BEG - Token(TkOPASGN, :/) #/) + Token(TkOPASGN, "/") #/) elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/ identify_string(op) else @@ -538,18 +568,29 @@ class RubyLex # Token(OP_ASGN, :^) # end - @OP.def_rules(",", ";") do + @OP.def_rules(",") do |op, io| @lex_state = EXPR_BEG Token(op) end + @OP.def_rules(";") do + |op, io| + @lex_state = EXPR_BEG + until (@indent_stack.empty? || + [TkLPAREN, TkLBRACK, TkLBRACE, + TkfLPAREN, TkfLBRACK, TkfLBRACE].include?(@indent_stack.last)) + @indent_stack.pop + end + Token(op) + end + @OP.def_rule("~") do @lex_state = EXPR_BEG Token("~") end - @OP.def_rule("~@", proc{@lex_state = EXPR_FNAME}) do + @OP.def_rule("~@", proc{@lex_state == EXPR_FNAME}) do @lex_state = EXPR_BEG Token("~") end @@ -558,11 +599,13 @@ class RubyLex @indent += 1 if @lex_state == EXPR_BEG || @lex_state == EXPR_MID @lex_state = EXPR_BEG - Token(TkfLPAREN) + tk_c = TkfLPAREN else @lex_state = EXPR_BEG - Token(TkLPAREN) + tk_c = TkLPAREN end + @indent_stack.push tk_c + tk = Token(tk_c) end @OP.def_rule("[]", proc{@lex_state == EXPR_FNAME}) do @@ -576,29 +619,31 @@ class RubyLex @OP.def_rule("[") do @indent += 1 if @lex_state == EXPR_FNAME - Token(TkfLBRACK) + tk_c = TkfLBRACK else if @lex_state == EXPR_BEG || @lex_state == EXPR_MID - t = Token(TkLBRACK) + tk_c = TkLBRACK elsif @lex_state == EXPR_ARG && @space_seen - t = Token(TkLBRACK) + tk_c = TkLBRACK else - t = Token(TkfLBRACK) + tk_c = TkfLBRACK end @lex_state = EXPR_BEG - t end + @indent_stack.push tk_c + Token(tk_c) end @OP.def_rule("{") do @indent += 1 if @lex_state != EXPR_END && @lex_state != EXPR_ARG - t = Token(TkLBRACE) + tk_c = TkLBRACE else - t = Token(TkfLBRACE) + tk_c = TkfLBRACE end @lex_state = EXPR_BEG - t + @indent_stack.push tk_c + Token(tk_c) end @OP.def_rule('\\') do @@ -632,7 +677,7 @@ class RubyLex end @OP.def_rule('@') do - if peek(0) =~ /[\w_]/ + if peek(0) =~ /[\w_@]/ ungetc identify_identifier else @@ -691,21 +736,32 @@ class RubyLex def identify_identifier token = "" - token.concat getc if peek(0) =~ /[$@]/ + if peek(0) =~ /[$@]/ + token.concat (c = getc) + if c == "@" and peek(0) == "@" + token.concat getc + end + end + while (ch = getc) =~ /\w|_/ print ":", ch, ":" if RubyLex.debug? token.concat ch end ungetc - if ch == "!" or ch == "?" + if (ch == "!" || ch == "?") && token[0,1] =~ /\w/ && peek(0) != "=" token.concat getc end + # almost fix token case token when /^\$/ return Token(TkGVAR, token) + when /^\@\@/ + @lex_state = EXPR_END + # p Token(TkCVAR, token) + return Token(TkCVAR, token) when /^\@/ @lex_state = EXPR_END return Token(TkIVAR, token) @@ -727,9 +783,37 @@ class RubyLex else if @lex_state != EXPR_FNAME if ENINDENT_CLAUSE.include?(token) - @indent += 1 + # check for ``class = val''. + valid = true + case token + when "class" + valid = false unless peek_match?(/^\s*(<<|\w)/) + + when "def" + valid = false if peek_match?(/^\s*(([+-\/*&\|^]|<<|>>|\|\||\&\&)?=|\&\&|\|\|)/) + when "do" + valid = false if peek_match?(/^\s*([+-\/*]?=|\*|<|>|\&)/) + when *ENINDENT_CLAUSE + valid = false if peek_match?(/^\s*([+-\/*]?=|\*|<|>|\&|\|)/) + else + # no nothing + end + if valid + if token == "do" + if ![TkFOR, TkWHILE, TkUNTIL].include?(@indent_stack.last) + @indent += 1 + @indent_stack.push token_c + end + else + @indent += 1 + @indent_stack.push token_c + end +# p @indent_stack + end + elsif DEINDENT_CLAUSE.include?(token) @indent -= 1 + @indent_stack.pop end @lex_state = trans[0] else @@ -830,9 +914,12 @@ class RubyLex @lex_state = EXPR_END if ch = getc - if peek(0) == "x" + if /[xX]/ =~ peek(0) ch = getc - match = /[0-9a-f_]/ + match = /[0-9a-fA-F_]/ + elsif /[bB]/ =~ peek(0) + ch = getc + match = /[01_]/ else match = /[0-7_]/ end @@ -878,17 +965,25 @@ class RubyLex @quoted = quoted subtype = nil begin - while ch = getc - if @quoted == ch + nest = 0 + while ch = getc + if @quoted == ch and nest == 0 break elsif @ltype != "'" && @ltype != "]" and ch == "#" subtype = true elsif ch == '\\' #' read_escape end + if PERCENT_PAREN.values.include?(@quoted) + if PERCENT_PAREN[ch] == @quoted + nest += 1 + elsif ch == @quoted + nest -= 1 + end + end end if @ltype == "/" - if peek(0) =~ /i|o|n|e|s/ + if peek(0) =~ /i|m|x|o|e|s|u|n/ getc end end @@ -908,9 +1003,9 @@ class RubyLex @ltype = "#" while ch = getc - if ch == "\\" #" - read_escape - end +# if ch == "\\" #" +# read_escape +# end if ch == "\n" @ltype = nil ungetc |