rubylexer 0.7.1 → 0.7.2
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/COPYING +0 -0
- data/History.txt +16 -1
- data/Manifest.txt +0 -0
- data/README.txt +0 -0
- data/Rakefile +1 -1
- data/howtouse.txt +0 -0
- data/lib/assert.rb +0 -0
- data/lib/rubylexer.rb +156 -45
- data/lib/rubylexer/0.6.2.rb +0 -0
- data/lib/rubylexer/0.6.rb +0 -0
- data/lib/rubylexer/0.7.0.rb +0 -0
- data/lib/rubylexer/0.7.1.rb +0 -0
- data/lib/rubylexer/charhandler.rb +0 -0
- data/lib/rubylexer/charset.rb +0 -0
- data/lib/rubylexer/context.rb +6 -0
- data/lib/rubylexer/rubycode.rb +0 -0
- data/lib/rubylexer/rulexer.rb +3 -2
- data/lib/rubylexer/symboltable.rb +0 -0
- data/lib/rubylexer/token.rb +3 -3
- data/lib/rubylexer/tokenprinter.rb +0 -0
- data/lib/rubylexer/version.rb +1 -1
- data/rubylexer.vpj +39 -29
- data/test/code/all_the_gems.rb +0 -0
- data/test/code/all_the_raas.rb +0 -0
- data/test/code/all_the_rubies.rb +0 -0
- data/test/code/deletewarns.rb +0 -0
- data/test/code/dumptokens.rb +6 -2
- data/test/code/errscan +0 -0
- data/test/code/isolate_error.rb +0 -0
- data/test/code/lexloop +0 -0
- data/test/code/locatetest +0 -0
- data/test/code/locatetest.rb +0 -0
- data/test/code/regression.rb +0 -2
- data/test/code/rubylexervsruby.rb +0 -0
- data/test/code/strgen.rb +0 -0
- data/test/code/tarball.rb +0 -0
- data/test/code/testcases.rb +0 -0
- data/test/code/tokentest.rb +0 -0
- data/test/code/torment +0 -0
- data/test/data/1.rb.broken +0 -0
- data/test/data/23.rb +0 -0
- data/test/data/__end__.rb +0 -0
- data/test/data/__end__2.rb +0 -0
- data/test/data/__eof2.rb +0 -0
- data/test/data/__eof5.rb +0 -0
- data/test/data/__eof6.rb +0 -0
- data/test/data/and.rb +0 -0
- data/test/data/blockassigntest.rb +0 -0
- data/test/data/chunky.plain.rb +0 -0
- data/test/data/chunky_bacon.rb +0 -0
- data/test/data/chunky_bacon2.rb +0 -0
- data/test/data/chunky_bacon3.rb +0 -0
- data/test/data/chunky_bacon4.rb +0 -0
- data/test/data/cvtesc.rb +0 -0
- data/test/data/for.rb +0 -0
- data/test/data/format.rb +0 -0
- data/test/data/g.rb +0 -0
- data/test/data/hd0.rb +0 -0
- data/test/data/hdateof.rb +0 -0
- data/test/data/hdempty.rb +0 -0
- data/test/data/hdr.rb +0 -0
- data/test/data/hdr_dos.rb +0 -0
- data/test/data/hdr_dos2.rb +0 -0
- data/test/data/heart.rb +0 -0
- data/test/data/here_escnl.rb +0 -0
- data/test/data/here_escnl_dos.rb +0 -0
- data/test/data/here_squote.rb +0 -0
- data/test/data/heremonsters.rb +0 -0
- data/test/data/heremonsters.rb.broken +0 -0
- data/test/data/heremonsters.rb.broken.save +0 -0
- data/test/data/heremonsters_dos.rb +0 -0
- data/test/data/heremonsters_dos.rb.broken +0 -0
- data/test/data/if.rb +0 -0
- data/test/data/jarh.rb +0 -0
- data/test/data/lbrace.rb +0 -0
- data/test/data/lbrack.rb +0 -0
- data/test/data/make_ws_strdelim.rb +0 -0
- data/test/data/maven2_builer_test.rb +0 -0
- data/test/data/migration.rb +0 -0
- data/test/data/modl.rb +0 -0
- data/test/data/modl_dos.rb +0 -0
- data/test/data/modl_fails.rb +0 -0
- data/test/data/multilinestring.rb +0 -0
- data/test/data/newsyntax.rb +0 -0
- data/test/data/noeolatend.rb +0 -0
- data/test/data/oneliners.rb +1 -1
- data/test/data/p-op.rb +0 -0
- data/test/data/p.rb +0 -0
- data/test/data/pleac.rb.broken +0 -0
- data/test/data/pre.rb +0 -0
- data/test/data/pre.unix.rb +0 -0
- data/test/data/regtest.rb +0 -0
- data/test/data/rescue.rb +0 -0
- data/test/data/s.rb +0 -0
- data/test/data/simple.rb +0 -0
- data/test/data/simple_dos.rb +0 -0
- data/test/data/stanzas.rb +0 -0
- data/test/data/strdelim_crlf.rb +0 -0
- data/test/data/strinc.rb +0 -0
- data/test/data/stuff.rb +0 -0
- data/test/data/stuff2.rb +0 -0
- data/test/data/stuff3.rb +0 -0
- data/test/data/tkweird.rb +0 -0
- data/test/data/tokentest.assert.rb.can +0 -0
- data/test/data/unending_stuff.rb +0 -0
- data/test/data/untermed_here.rb.broken +0 -0
- data/test/data/untermed_string.rb.broken +0 -0
- data/test/data/untitled1.rb +0 -0
- data/test/data/w.rb +0 -0
- data/test/data/whatnot.rb +0 -0
- data/test/data/ws_strdelim.rb +0 -0
- data/test/data/wsdlDriver.rb +0 -0
- data/test/test.sh +0 -0
- data/testing.txt +0 -0
- metadata +64 -149
data/COPYING
CHANGED
|
File without changes
|
data/History.txt
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
1
|
-
=== 0.7.
|
|
1
|
+
=== 0.7.2/10-12-2008
|
|
2
|
+
* 12 Minor Enhancements:
|
|
3
|
+
* a new context for then kw expected
|
|
4
|
+
* disable all backtracking when scanning string interiors
|
|
5
|
+
* ternary flag distinguishes ternary : from other uses
|
|
6
|
+
* EndDefHeaderToken renamed to EndHeaderToken
|
|
7
|
+
* ^ now gets its own scanning method
|
|
8
|
+
* correct # of parens emitted after of kw used as (or like) method
|
|
9
|
+
* more special casing for break return and next
|
|
10
|
+
* abort_noparens! now better if When context on the stack
|
|
11
|
+
* semicolon may now be omitted after module header
|
|
12
|
+
* { and } in BEGIN/END expr masquerade as do and end
|
|
13
|
+
* trying to make 'rake test' work right
|
|
14
|
+
* certain other changes of no importance whatsoever
|
|
15
|
+
|
|
16
|
+
=== 0.7.1/8-29-2008
|
|
2
17
|
* 6 Major Enhancements:
|
|
3
18
|
* handling of empty string fragments now more closely mirrors ruby; this resolves many warnings
|
|
4
19
|
* yet more hacks in aid of string inclusions
|
data/Manifest.txt
CHANGED
|
File without changes
|
data/README.txt
CHANGED
|
File without changes
|
data/Rakefile
CHANGED
|
@@ -15,7 +15,7 @@ require 'lib/rubylexer/version.rb'
|
|
|
15
15
|
_.email = "rubylexer-owner @at@ inforadical .dot. net"
|
|
16
16
|
_.url = ["http://rubylexer.rubyforge.org/", "http://rubyforge.org/projects/rubylexer/"]
|
|
17
17
|
_.extra_deps << ['sequence', '>= 0.2.0']
|
|
18
|
-
_.test_globs=["test/
|
|
18
|
+
_.test_globs=["test/code/regression.rb"]
|
|
19
19
|
_.description=desc
|
|
20
20
|
_.summary=desc[/\A[^.]+\./]
|
|
21
21
|
_.spec_extras={:bindir=>''}
|
data/howtouse.txt
CHANGED
|
File without changes
|
data/lib/assert.rb
CHANGED
|
File without changes
|
data/lib/rubylexer.rb
CHANGED
|
@@ -83,7 +83,7 @@ class RubyLexer
|
|
|
83
83
|
?, => :comma,
|
|
84
84
|
?; => :semicolon,
|
|
85
85
|
|
|
86
|
-
?^ => :
|
|
86
|
+
?^ => :caret,
|
|
87
87
|
?~ => :tilde,
|
|
88
88
|
?= => :equals,
|
|
89
89
|
?! => :exclam,
|
|
@@ -130,6 +130,9 @@ class RubyLexer
|
|
|
130
130
|
@in_def_name=false
|
|
131
131
|
@last_operative_token=nil
|
|
132
132
|
@last_token_maybe_implicit=nil
|
|
133
|
+
@enable_macro=nil
|
|
134
|
+
@base_file=nil
|
|
135
|
+
@progress_thread=nil
|
|
133
136
|
|
|
134
137
|
@toptable=CharHandler.new(self, :illegal_char, CHARMAPPINGS)
|
|
135
138
|
|
|
@@ -442,12 +445,12 @@ private
|
|
|
442
445
|
end
|
|
443
446
|
|
|
444
447
|
#-----------------------------------
|
|
445
|
-
def in_lvar_define_state
|
|
448
|
+
def in_lvar_define_state lasttok=@last_operative_token
|
|
446
449
|
#@defining_lvar is a hack
|
|
447
450
|
@defining_lvar or case ctx=@parsestack.last
|
|
448
451
|
#when ForSMContext; ctx.state==:for
|
|
449
452
|
when RescueSMContext
|
|
450
|
-
|
|
453
|
+
lasttok.ident=="=>" and @file.match? /\A[\s\v]*([:;#\n]|then[^a-zA-Z0-9_])/m
|
|
451
454
|
#when BlockParamListLhsContext; true
|
|
452
455
|
end
|
|
453
456
|
end
|
|
@@ -472,7 +475,7 @@ private
|
|
|
472
475
|
|
|
473
476
|
assert String===name
|
|
474
477
|
|
|
475
|
-
was_in_lvar_define_state=in_lvar_define_state
|
|
478
|
+
was_in_lvar_define_state=in_lvar_define_state(lasttok)
|
|
476
479
|
#maybe_local really means 'maybe local or constant'
|
|
477
480
|
maybe_local=case name
|
|
478
481
|
when /[^a-z_0-9]$/i #do nothing
|
|
@@ -500,8 +503,6 @@ private
|
|
|
500
503
|
if /^[a-z_][a-zA-Z_0-9]*$/===name
|
|
501
504
|
assert !(lasttok===/^(\.|::)$/)
|
|
502
505
|
localvars[name]=true
|
|
503
|
-
else
|
|
504
|
-
lexerror tok,"not a valid variable name: #{name}"
|
|
505
506
|
end
|
|
506
507
|
return result.unshift(tok)
|
|
507
508
|
elsif maybe_local
|
|
@@ -534,7 +535,6 @@ private
|
|
|
534
535
|
if (assignment_coming && !(lasttok===/^(\.|::)$/) or was_in_lvar_define_state)
|
|
535
536
|
tok=assign_lvar_type! VarNameToken.new(name,pos)
|
|
536
537
|
if /[^a-z_0-9]$/i===name
|
|
537
|
-
lexerror tok,"not a valid variable name: #{name}"
|
|
538
538
|
elsif /^[a-z_]/===name and !(lasttok===/^(\.|::)$/)
|
|
539
539
|
localvars[name]=true
|
|
540
540
|
end
|
|
@@ -573,7 +573,7 @@ private
|
|
|
573
573
|
!(KeywordToken===oldlast and oldlast===/\A(\.|::)\Z/)
|
|
574
574
|
x
|
|
575
575
|
=end
|
|
576
|
-
when ?(
|
|
576
|
+
when ?(
|
|
577
577
|
maybe_local=false
|
|
578
578
|
lastid=lasttok&&lasttok.ident
|
|
579
579
|
case lastid
|
|
@@ -595,10 +595,12 @@ private
|
|
|
595
595
|
# ignored_tokens(true)
|
|
596
596
|
# want_parens=false if nextchar==?)
|
|
597
597
|
# @file.pos=afterparen
|
|
598
|
-
|
|
598
|
+
want_parens=true if /^(return|break|next)$/===@last_operative_token.ident and not(
|
|
599
|
+
KeywordToken===lasttok and /^(.|::)$/===lasttok.ident
|
|
600
|
+
)
|
|
599
601
|
want_parens ? 1 : 0
|
|
600
|
-
when ?},?],?)
|
|
601
|
-
when ?+, ?-, ?%,
|
|
602
|
+
when ?},?],?),?;,(?^ unless @enable_macro), ?|, ?>, ?,, ?., ?=; 2
|
|
603
|
+
when ?+, ?-, ?%, ?/, (?^ if @enable_macro)
|
|
602
604
|
if /^(return|break|next)$/===@last_operative_token.ident and not(
|
|
603
605
|
KeywordToken===lasttok and /^(.|::)$/===lasttok.ident
|
|
604
606
|
)
|
|
@@ -607,7 +609,7 @@ private
|
|
|
607
609
|
(ws_toks.empty? || readahead(2)[/^.[#{WHSPLF}]/o]) ? 2 : 3
|
|
608
610
|
end
|
|
609
611
|
when ?*, ?&
|
|
610
|
-
|
|
612
|
+
# lasttok=@last_operative_token
|
|
611
613
|
if /^(return|break|next)$/===@last_operative_token.ident and not(
|
|
612
614
|
KeywordToken===lasttok and /^(.|::)$/===lasttok.ident
|
|
613
615
|
)
|
|
@@ -626,7 +628,12 @@ private
|
|
|
626
628
|
/^\?([#{WHSPLF}]|[a-z_][a-z_0-9])/io===next3 ? 2 : 3
|
|
627
629
|
# when ?:,??; (readahead(2)[/^.[#{WHSPLF}]/o]) ? 2 : 3
|
|
628
630
|
when ?<; (!ws_toks.empty? && readahead(4)[/^<<-?["'`a-zA-Z_0-9]/]) ? 3 : 2
|
|
629
|
-
when ?[;
|
|
631
|
+
when ?[;
|
|
632
|
+
if ws_toks.empty?
|
|
633
|
+
(KeywordToken===oldlast and /^(return|break|next)$/===oldlast.ident) ? 3 : 2
|
|
634
|
+
else
|
|
635
|
+
3
|
|
636
|
+
end
|
|
630
637
|
when ?\\, ?\s, ?\t, ?\n, ?\r, ?\v, ?#; raise 'failure'
|
|
631
638
|
else raise "unknown char after ident: #{nc=nextchar ? nc.chr : "<<EOF>>"}"
|
|
632
639
|
end
|
|
@@ -704,8 +711,8 @@ private
|
|
|
704
711
|
CONTEXT2ENDTOK={
|
|
705
712
|
AssignmentRhsContext=>AssignmentRhsListEndToken,
|
|
706
713
|
ParamListContextNoParen=>ImplicitParamListEndToken,
|
|
707
|
-
KWParamListContextNoParen=>ImplicitParamListEndToken,
|
|
708
|
-
WhenParamListContext=>KwParamListEndToken,
|
|
714
|
+
KWParamListContextNoParen=>ImplicitParamListEndToken, #break,next,return
|
|
715
|
+
WhenParamListContext=>KwParamListEndToken,
|
|
709
716
|
RescueSMContext=>KwParamListEndToken
|
|
710
717
|
}
|
|
711
718
|
def abort_noparens!(str='')
|
|
@@ -713,7 +720,8 @@ private
|
|
|
713
720
|
result=[]
|
|
714
721
|
while klass=CONTEXT2ENDTOK[@parsestack.last.class]
|
|
715
722
|
result << klass.new(input_position-str.length)
|
|
716
|
-
break if RescueSMContext===@parsestack.last
|
|
723
|
+
break if RescueSMContext===@parsestack.last #and str==':'
|
|
724
|
+
break if WhenParamListContext===@parsestack.last and str==':'
|
|
717
725
|
@parsestack.pop
|
|
718
726
|
end
|
|
719
727
|
return result
|
|
@@ -724,7 +732,7 @@ private
|
|
|
724
732
|
AssignmentRhsContext=>AssignmentRhsListEndToken,
|
|
725
733
|
ParamListContextNoParen=>ImplicitParamListEndToken,
|
|
726
734
|
KWParamListContextNoParen=>ImplicitParamListEndToken,
|
|
727
|
-
WhenParamListContext=>KwParamListEndToken,
|
|
735
|
+
WhenParamListContext=>KwParamListEndToken, #I think this isn't needed...
|
|
728
736
|
RescueSMContext=>KwParamListEndToken
|
|
729
737
|
}
|
|
730
738
|
def abort_noparens_for_rescue!(str='')
|
|
@@ -791,6 +799,39 @@ private
|
|
|
791
799
|
return result
|
|
792
800
|
end
|
|
793
801
|
|
|
802
|
+
#-----------------------------------
|
|
803
|
+
def enable_macros!
|
|
804
|
+
@enable_macro="macro"
|
|
805
|
+
end
|
|
806
|
+
public :enable_macros!
|
|
807
|
+
|
|
808
|
+
|
|
809
|
+
#-----------------------------------
|
|
810
|
+
@@SPACES=/[\ \t\v\f\v]/
|
|
811
|
+
@@WSTOK=/\r?\n|\r*#@@SPACES+(?:#@@SPACES|\r(?!\n))*|\#[^\n]*\n|\\\r?\n|
|
|
812
|
+
^=begin[\s\n](?:(?!=end).*\n)*=end[\s\n].*\n/x
|
|
813
|
+
@@WSTOKS=/(?!=begin)#@@WSTOK+/o
|
|
814
|
+
def divide_ws(ws,offset)
|
|
815
|
+
result=[]
|
|
816
|
+
ws.scan(/\G#@@WSTOK/o){|ws|
|
|
817
|
+
incr= $~.begin(0)
|
|
818
|
+
klass=case ws
|
|
819
|
+
when /\A[\#=]/: CommentToken
|
|
820
|
+
when /\n\Z/: EscNlToken
|
|
821
|
+
else WsToken
|
|
822
|
+
end
|
|
823
|
+
result << klass.new(ws,offset+incr)
|
|
824
|
+
}
|
|
825
|
+
result.each_with_index{|ws,i|
|
|
826
|
+
if WsToken===ws
|
|
827
|
+
ws.ident << result.delete(i+1).ident while WsToken===result[i+1]
|
|
828
|
+
end
|
|
829
|
+
}
|
|
830
|
+
return result
|
|
831
|
+
end
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
|
|
794
835
|
#-----------------------------------
|
|
795
836
|
#parse keywords now, to prevent confusion over bare symbols
|
|
796
837
|
#and match end with corresponding preceding def or class or whatever.
|
|
@@ -823,7 +864,33 @@ private
|
|
|
823
864
|
result.first.has_end!
|
|
824
865
|
@parsestack.push WantsEndContext.new(str,@linenum)
|
|
825
866
|
@localvars_stack.push SymbolTable.new
|
|
826
|
-
|
|
867
|
+
offset=input_position
|
|
868
|
+
@file.scan(/\A(#@@WSTOKS)?(::)?/o)
|
|
869
|
+
md=@file.last_match
|
|
870
|
+
all,ws,dc=*md
|
|
871
|
+
fail if all.empty?
|
|
872
|
+
@moretokens.concat divide_ws(ws,offset) if ws
|
|
873
|
+
@moretokens.push KeywordToken.new('::',offset+md.end(0)-2) if dc
|
|
874
|
+
loop do
|
|
875
|
+
offset=input_position
|
|
876
|
+
@file.scan(/\A(#@@WSTOKS)?([A-Z][a-zA-Z_0-9]*)(::)?/o)
|
|
877
|
+
#this regexp---^ will need to change in order to support utf8 properly.
|
|
878
|
+
md=@file.last_match
|
|
879
|
+
all,ws,name,dc=*md
|
|
880
|
+
if ws
|
|
881
|
+
@moretokens.concat divide_ws(ws,offset)
|
|
882
|
+
incr=ws.size
|
|
883
|
+
else
|
|
884
|
+
incr=0
|
|
885
|
+
end
|
|
886
|
+
@moretokens.push VarNameToken.new(name,offset+incr)
|
|
887
|
+
break unless dc
|
|
888
|
+
@moretokens.push KeywordToken.new('::',offset+md.end(0)-2)
|
|
889
|
+
end
|
|
890
|
+
@moretokens.push EndHeaderToken.new(input_position)
|
|
891
|
+
|
|
892
|
+
|
|
893
|
+
|
|
827
894
|
when "class"
|
|
828
895
|
result.first.has_end!
|
|
829
896
|
@parsestack.push ClassContext.new(str,@linenum)
|
|
@@ -832,11 +899,12 @@ private
|
|
|
832
899
|
if after_nonid_op?{false} #prefix form
|
|
833
900
|
result.first.has_end!
|
|
834
901
|
@parsestack.push WantsEndContext.new(str,@linenum)
|
|
835
|
-
|
|
836
|
-
|
|
902
|
+
@parsestack.push ExpectThenOrNlContext.new(str,@linenum)
|
|
837
903
|
else #infix form
|
|
838
904
|
result.unshift(*abort_noparens!(str))
|
|
839
905
|
end
|
|
906
|
+
when "elsif"
|
|
907
|
+
@parsestack.push ExpectThenOrNlContext.new(str,@linenum)
|
|
840
908
|
when "begin","case"
|
|
841
909
|
result.first.has_end!
|
|
842
910
|
@parsestack.push WantsEndContext.new(str,@linenum)
|
|
@@ -868,12 +936,12 @@ private
|
|
|
868
936
|
localvars.start_block
|
|
869
937
|
block_param_list_lookahead
|
|
870
938
|
end
|
|
871
|
-
when "def"
|
|
939
|
+
when "def",@enable_macro
|
|
872
940
|
result.first.has_end!
|
|
873
941
|
@parsestack.push ctx=DefContext.new(@linenum)
|
|
874
942
|
ctx.state=:saw_def
|
|
875
943
|
safe_recurse { |aa|
|
|
876
|
-
set_last_token KeywordToken.new
|
|
944
|
+
set_last_token KeywordToken.new str #hack
|
|
877
945
|
result.concat ignored_tokens
|
|
878
946
|
|
|
879
947
|
#read an expr like a.b.c or a::b::c
|
|
@@ -957,7 +1025,7 @@ private
|
|
|
957
1025
|
else
|
|
958
1026
|
ofs+=listend.to_s.size
|
|
959
1027
|
end
|
|
960
|
-
result.insert end_index+1,
|
|
1028
|
+
result.insert end_index+1,EndHeaderToken.new(ofs)
|
|
961
1029
|
break
|
|
962
1030
|
end
|
|
963
1031
|
|
|
@@ -983,7 +1051,7 @@ private
|
|
|
983
1051
|
if endofs
|
|
984
1052
|
result.insert -2,ImplicitParamListEndToken.new(tok.offset)
|
|
985
1053
|
end
|
|
986
|
-
result.insert -2,
|
|
1054
|
+
result.insert -2, EndHeaderToken.new(tok.offset)
|
|
987
1055
|
break
|
|
988
1056
|
else
|
|
989
1057
|
lexerror(tok, "bizarre token in def name: " +
|
|
@@ -1060,6 +1128,11 @@ private
|
|
|
1060
1128
|
when "then"
|
|
1061
1129
|
result.unshift(*abort_noparens!(str))
|
|
1062
1130
|
@parsestack.last.see self,:then
|
|
1131
|
+
|
|
1132
|
+
if ExpectThenOrNlContext===@parsestack.last
|
|
1133
|
+
@parsestack.pop
|
|
1134
|
+
else #error... does anyone care?
|
|
1135
|
+
end
|
|
1063
1136
|
|
|
1064
1137
|
when "in"
|
|
1065
1138
|
result.unshift KwParamListEndToken.new( offset)
|
|
@@ -1083,7 +1156,7 @@ private
|
|
|
1083
1156
|
#END blocks are visible to subsequent code. (Why??)
|
|
1084
1157
|
#That difference forces a custom parsing.
|
|
1085
1158
|
if @last_operative_token===/^(\.|::)$/
|
|
1086
|
-
result=yield
|
|
1159
|
+
result=yield MethNameToken.new(str) #should pass a methname token here
|
|
1087
1160
|
else
|
|
1088
1161
|
safe_recurse{
|
|
1089
1162
|
old=result.first
|
|
@@ -1096,17 +1169,18 @@ private
|
|
|
1096
1169
|
getchar=='{' or lexerror(result.first,"expected { after #{str}")
|
|
1097
1170
|
result.push KeywordToken.new('{',input_position-1)
|
|
1098
1171
|
result.last.set_infix!
|
|
1172
|
+
result.last.as="do"
|
|
1099
1173
|
@parsestack.push BeginEndContext.new(str,offset)
|
|
1100
1174
|
}
|
|
1101
1175
|
end
|
|
1102
1176
|
|
|
1103
1177
|
when FUNCLIKE_KEYWORDS
|
|
1104
|
-
result=yield
|
|
1178
|
+
result=yield MethNameToken.new(str) #should be a keyword token?
|
|
1105
1179
|
|
|
1106
1180
|
when RUBYKEYWORDS
|
|
1107
1181
|
#do nothing
|
|
1108
1182
|
|
|
1109
|
-
else result=yield
|
|
1183
|
+
else result=yield MethNameToken.new(str)
|
|
1110
1184
|
|
|
1111
1185
|
end
|
|
1112
1186
|
|
|
@@ -1307,7 +1381,7 @@ end
|
|
|
1307
1381
|
# if !eof? and nextchar.chr[/[iuw\/<|>+\-*&%?:({]/] and
|
|
1308
1382
|
# !(NewlineToken===@last_operative_token) and
|
|
1309
1383
|
# !(/^(end|;)$/===@last_operative_token)
|
|
1310
|
-
#result<<
|
|
1384
|
+
#result<<EndHeaderToken.new(result.last.offset+result.last.to_s.size)
|
|
1311
1385
|
set_last_token KeywordToken.new ';'
|
|
1312
1386
|
result<< get1token
|
|
1313
1387
|
# end
|
|
@@ -1426,10 +1500,18 @@ end
|
|
|
1426
1500
|
#-----------------------------------
|
|
1427
1501
|
def symbol_or_op(ch)
|
|
1428
1502
|
startpos= input_position
|
|
1503
|
+
|
|
1504
|
+
|
|
1429
1505
|
qe= colon_quote_expected?(ch)
|
|
1430
1506
|
lastchar=prevchar
|
|
1431
1507
|
eat_next_if(ch[0]) or raise "needed: "+ch
|
|
1432
1508
|
|
|
1509
|
+
if nextchar==?( and @enable_macro
|
|
1510
|
+
result= OperatorToken.new(':', startpos)
|
|
1511
|
+
result.unary=true
|
|
1512
|
+
return result
|
|
1513
|
+
end
|
|
1514
|
+
|
|
1433
1515
|
#handle quoted symbols like :"foobar", :"[]"
|
|
1434
1516
|
qe and return symbol(':')
|
|
1435
1517
|
|
|
@@ -1437,17 +1519,23 @@ end
|
|
|
1437
1519
|
unless eat_next_if(?:)
|
|
1438
1520
|
#cancel implicit contexts...
|
|
1439
1521
|
@moretokens.push(*abort_noparens!(':'))
|
|
1440
|
-
@moretokens.push KeywordToken.new(':',startpos)
|
|
1522
|
+
@moretokens.push tok=KeywordToken.new(':',startpos)
|
|
1441
1523
|
|
|
1442
1524
|
case @parsestack.last
|
|
1443
|
-
when TernaryContext:
|
|
1525
|
+
when TernaryContext:
|
|
1526
|
+
tok.ternary=true
|
|
1527
|
+
@parsestack.pop #should be in the context's see handler
|
|
1444
1528
|
when ExpectDoOrNlContext: #should be in the context's see handler
|
|
1445
1529
|
@parsestack.pop
|
|
1446
1530
|
assert @parsestack.last.starter[/^(while|until|for)$/]
|
|
1447
|
-
|
|
1531
|
+
tok.as=";"
|
|
1532
|
+
when ExpectThenOrNlContext,WhenParamListContext:
|
|
1533
|
+
#should be in the context's see handler
|
|
1534
|
+
@parsestack.pop
|
|
1535
|
+
tok.as="then"
|
|
1448
1536
|
when RescueSMContext:
|
|
1449
|
-
|
|
1450
|
-
else @
|
|
1537
|
+
tok.as=";"
|
|
1538
|
+
else fail ": not expected in #{@parsestack.last.class}->#{@parsestack.last.starter}"
|
|
1451
1539
|
end
|
|
1452
1540
|
|
|
1453
1541
|
#end ternary context, if any
|
|
@@ -1503,7 +1591,9 @@ end
|
|
|
1503
1591
|
/[A-Z_0-9]$/i===result and klass=VarNameToken
|
|
1504
1592
|
end
|
|
1505
1593
|
result
|
|
1506
|
-
else
|
|
1594
|
+
else
|
|
1595
|
+
error= "unexpected char starting symbol: #{nc.chr}"
|
|
1596
|
+
'_'
|
|
1507
1597
|
end
|
|
1508
1598
|
result= lexerror(klass.new(result,start,notbare ? ':' : ''),error)
|
|
1509
1599
|
if open
|
|
@@ -1843,7 +1933,10 @@ end
|
|
|
1843
1933
|
then #hack-o-rama: probly cases left out above
|
|
1844
1934
|
@offset_adjust=@min_offset_adjust
|
|
1845
1935
|
a= abort_noparens!
|
|
1846
|
-
|
|
1936
|
+
case @parsestack.last #these should be in the see:semi handler
|
|
1937
|
+
when ExpectDoOrNlContext: @parsestack.pop
|
|
1938
|
+
when ExpectThenOrNlContext: @parsestack.pop
|
|
1939
|
+
end
|
|
1847
1940
|
assert !@parsestack.empty?
|
|
1848
1941
|
@parsestack.last.see self,:semi
|
|
1849
1942
|
|
|
@@ -2011,7 +2104,7 @@ end
|
|
|
2011
2104
|
when /^(#{RUBYOPERATORREX}|#{INNERBOUNDINGWORDS}|do)$/o.token_pat
|
|
2012
2105
|
#regexs above must match whole string
|
|
2013
2106
|
#assert(@last_operative_token==$&) #disabled 'cause $& is now always nil :(
|
|
2014
|
-
return true
|
|
2107
|
+
return true if OperatorToken===@last_operative_token || KeywordToken===@last_operative_token
|
|
2015
2108
|
when NewlineToken, nil, #nil means we're still at beginning of file
|
|
2016
2109
|
/^([({\[]|or|not|and|if|unless|then|elsif|else|class|module|def|
|
|
2017
2110
|
while|until|begin|for|in|case|when|ensure|defined\?)$
|
|
@@ -2065,15 +2158,31 @@ end
|
|
|
2065
2158
|
end
|
|
2066
2159
|
|
|
2067
2160
|
|
|
2068
|
-
|
|
2069
|
-
|
|
2161
|
+
#-----------------------------------
|
|
2162
|
+
def caret(ch) #match /^=?/ (^ or ^=) (maybe unary ^ too)
|
|
2163
|
+
if @enable_macro and (@last_token_maybe_implicit and
|
|
2164
|
+
@last_token_maybe_implicit.ident=='(') || unary_op_expected?(ch)
|
|
2165
|
+
result=OperatorToken.new(read(1),input_position)
|
|
2166
|
+
result.unary=true
|
|
2167
|
+
result
|
|
2168
|
+
else
|
|
2169
|
+
biop ch
|
|
2170
|
+
end
|
|
2171
|
+
end
|
|
2172
|
+
|
|
2173
|
+
#-----------------------------------
|
|
2174
|
+
def biop(ch) #match /%=?/ (% or %=)
|
|
2070
2175
|
assert(ch[/^[%^]$/])
|
|
2176
|
+
oldpos=input_position
|
|
2071
2177
|
result=getchar
|
|
2072
2178
|
if eat_next_if(?=)
|
|
2073
2179
|
result << ?=
|
|
2074
2180
|
end
|
|
2075
|
-
|
|
2181
|
+
result= operator_or_methname_token( result)
|
|
2182
|
+
result.offset=oldpos
|
|
2183
|
+
return result
|
|
2076
2184
|
end
|
|
2185
|
+
|
|
2077
2186
|
#-----------------------------------
|
|
2078
2187
|
def tilde(ch) #match ~
|
|
2079
2188
|
assert(ch=='~')
|
|
@@ -2322,10 +2431,8 @@ end
|
|
|
2322
2431
|
lexerror kw,"mismatched braces: #{origch}#{ch}\n" +
|
|
2323
2432
|
"matching brace location", @filename, line
|
|
2324
2433
|
end
|
|
2325
|
-
if BlockContext===ctx
|
|
2326
|
-
|
|
2327
|
-
@moretokens.last.as="end"
|
|
2328
|
-
end
|
|
2434
|
+
localvars.end_block if BlockContext===ctx
|
|
2435
|
+
@moretokens.last.as="end" if BlockContext===ctx or BeginEndContext===ctx
|
|
2329
2436
|
if ParamListContext==ctx.class
|
|
2330
2437
|
assert ch==')'
|
|
2331
2438
|
kw.set_callsite! #not needed?
|
|
@@ -2372,6 +2479,7 @@ end
|
|
|
2372
2479
|
ParamListContext===@parsestack[-2] ||
|
|
2373
2480
|
ParamListContextNoParen===@parsestack[-2] ||
|
|
2374
2481
|
WhenParamListContext===@parsestack[-2] ||
|
|
2482
|
+
ListImmedContext===@parsestack[-2] ||
|
|
2375
2483
|
(RescueSMContext===@parsestack[-2] && @parsestack[-2].state==:rescue) ||
|
|
2376
2484
|
(DefContext===@parsestack[-2] && !@parsestack[-2].in_body)
|
|
2377
2485
|
@parsestack.pop
|
|
@@ -2394,7 +2502,10 @@ end
|
|
|
2394
2502
|
assert @moretokens.empty?
|
|
2395
2503
|
@moretokens.push(*abort_noparens!)
|
|
2396
2504
|
@parsestack.last.see self,:semi
|
|
2397
|
-
|
|
2505
|
+
case @parsestack.last #should be in context's see:semi handler
|
|
2506
|
+
when ExpectThenOrNlContext
|
|
2507
|
+
@parsestack.pop
|
|
2508
|
+
when ExpectDoOrNlContext
|
|
2398
2509
|
@parsestack.pop
|
|
2399
2510
|
assert @parsestack.last.starter[/^(while|until|for)$/]
|
|
2400
2511
|
end
|
|
@@ -2417,7 +2528,7 @@ end
|
|
|
2417
2528
|
#-----------------------------------
|
|
2418
2529
|
#tokenify_results_of :identifier
|
|
2419
2530
|
save_offsets_in(*CHARMAPPINGS.values.uniq-[
|
|
2420
|
-
:symbol_or_op,:open_brace,:whitespace,:exclam,:backquote
|
|
2531
|
+
:symbol_or_op,:open_brace,:whitespace,:exclam,:backquote,:caret
|
|
2421
2532
|
])
|
|
2422
2533
|
#save_offsets_in :symbol
|
|
2423
2534
|
|