rubylexer 0.7.5 → 0.7.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 +13 -0
- data/Rakefile +1 -1
- data/lib/rubylexer.rb +114 -59
- data/lib/rubylexer/context.rb +11 -0
- data/lib/rubylexer/version.rb +1 -1
- metadata +3 -3
data/History.txt
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
=== 0.7.6/7-01-2009
|
2
|
+
* 5 Bugfixes:
|
3
|
+
* don't treat <, <=, <=> as starting variables (only << for here header)
|
4
|
+
* space between break/return/next and following open paren is ignored
|
5
|
+
* fixed unusual whitespace is unlikely places (module header)
|
6
|
+
* some parentheses weren't being decorated right
|
7
|
+
* rescue should not end implicit parameter lists... unless its an op
|
8
|
+
|
9
|
+
* 3 new ruby 1.9 features:
|
10
|
+
* stabby blocks
|
11
|
+
* dot at beginning of line
|
12
|
+
* !, !=, !~ are now valid method/symbol names
|
13
|
+
|
1
14
|
=== 0.7.5/5-23-2009
|
2
15
|
* 1 Bugfix:
|
3
16
|
* fixed problem with parsing shebang lines
|
data/Rakefile
CHANGED
@@ -30,7 +30,7 @@ require 'lib/rubylexer/version.rb'
|
|
30
30
|
_.test_globs=["test/code/regression.rb"]
|
31
31
|
_.description=desc
|
32
32
|
_.summary=desc[/\A[^.]+\./]
|
33
|
-
_.spec_extras={:bindir=>'',:rdoc_options=>'-x lib/rubylexer/test'}
|
33
|
+
_.spec_extras={:bindir=>'',:rdoc_options=>'-x lib/rubylexer/test/oneliners.rb'}
|
34
34
|
#_.rdoc_pattern=/\A(howtouse\.txt|testing\.txt|README\.txt|lib\/[^\/]*\.rb|lib\/rubylexer\/[^\d][^\/]*\.rb)\Z/
|
35
35
|
end
|
36
36
|
|
data/lib/rubylexer.rb
CHANGED
@@ -170,6 +170,11 @@ class RubyLexer
|
|
170
170
|
@progress_thread=nil
|
171
171
|
@rubyversion=options[:rubyversion]
|
172
172
|
@encoding=options[:encoding]||:detect
|
173
|
+
@method_operators=if @rubyversion>=1.9
|
174
|
+
/#{RUBYSYMOPERATORREX}|\A![=~]?\Z/o
|
175
|
+
else
|
176
|
+
RUBYSYMOPERATORREX
|
177
|
+
end
|
173
178
|
|
174
179
|
@toptable=CharHandler.new(self, :illegal_char, CHARMAPPINGS)
|
175
180
|
|
@@ -670,9 +675,9 @@ private
|
|
670
675
|
maybe_local=false
|
671
676
|
lastid=lasttok&&lasttok.ident
|
672
677
|
case lastid
|
673
|
-
when /\A[;(]|do\Z
|
674
|
-
when '|'
|
675
|
-
when '{'
|
678
|
+
when /\A[;(]|do\Z/; was_after_nonid_op=false
|
679
|
+
when '|'; was_after_nonid_op=false unless BlockParamListLhsContext===@parsestack.last
|
680
|
+
when '{'; was_after_nonid_op=false if BlockContext===@parsestack.last or BeginEndContext===@parsestack.last
|
676
681
|
end if KeywordToken===lasttok
|
677
682
|
was_after_nonid_op=false if NewlineToken===lasttok or lasttok.nil?
|
678
683
|
want_parens=!(ws_toks.empty? or was_after_nonid_op) #or
|
@@ -752,20 +757,21 @@ private
|
|
752
757
|
result.unshift ImplicitParamListStartToken.new(oldpos),
|
753
758
|
ImplicitParamListEndToken.new(oldpos)
|
754
759
|
when 1,3;
|
755
|
-
|
756
|
-
|
757
|
-
unless pass
|
760
|
+
if /^(break|next|return)$/===name and
|
761
|
+
!(KeywordToken===lasttok and /^(\.|::)$/===lasttok.ident)
|
758
762
|
#only 1 param in list
|
759
763
|
result.unshift ImplicitParamListStartToken.new(oldpos)
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
764
|
+
@parsestack.push ParamListContextNoParen.new(@linenum)
|
765
|
+
else
|
766
|
+
arr,pass=*param_list_coming_with_2_or_more_params?
|
767
|
+
result.push( *arr )
|
768
|
+
unless pass
|
769
|
+
#only 1 param in list
|
770
|
+
result.unshift ImplicitParamListStartToken.new(oldpos)
|
771
|
+
last=result.last
|
772
|
+
last.set_callsite! false if last.respond_to? :callsite? and last.callsite?
|
773
|
+
@parsestack.push ParamListContextNoParen.new(@linenum)
|
767
774
|
end
|
768
|
-
@parsestack.push ty.new(@linenum)
|
769
775
|
end
|
770
776
|
when 0; #do nothing
|
771
777
|
else raise 'invalid value of implicit_parens_to_emit'
|
@@ -782,8 +788,11 @@ private
|
|
782
788
|
end
|
783
789
|
|
784
790
|
#-----------------------------------
|
791
|
+
#read ahead to see if there's method param list (with real parentheses)
|
792
|
+
#and 2 or more parameters (and hence a comma to separate them)
|
793
|
+
#ugly, lexer recursion
|
785
794
|
def param_list_coming_with_2_or_more_params?
|
786
|
-
|
795
|
+
return [[],false] unless WHSPCHARS[prevchar] && (?(==nextchar)
|
787
796
|
basesize=@parsestack.size
|
788
797
|
result=[get1token]
|
789
798
|
pass=loop{
|
@@ -799,6 +808,8 @@ private
|
|
799
808
|
lexerror tok, "unexpected eof in parameter list"
|
800
809
|
end
|
801
810
|
}
|
811
|
+
result.concat @moretokens
|
812
|
+
@moretokens.replace []
|
802
813
|
return [result,pass]
|
803
814
|
end
|
804
815
|
|
@@ -907,22 +918,22 @@ private
|
|
907
918
|
#-----------------------------------
|
908
919
|
@@SPACES=/[\ \t\v\f\v]/
|
909
920
|
@@WSTOK=/\r?\n|\r*#@@SPACES+(?:#@@SPACES|\r(?!\n))*|\#[^\n]*\n|\\\r?\n|
|
910
|
-
^=begin[\s
|
921
|
+
^=begin(?:[\s].*)?\n(?:(?!=end).*\n)*=end[\s\n].*\n/x
|
911
922
|
@@WSTOKS=/(?!=begin)#@@WSTOK+/o
|
912
923
|
def divide_ws(ws,offset)
|
913
924
|
result=[]
|
914
925
|
ws.scan(/\G#@@WSTOK/o){|ws|
|
915
926
|
incr= $~.begin(0)
|
916
927
|
klass=case ws
|
917
|
-
when /\A[\#=]
|
918
|
-
when /\n\Z
|
928
|
+
when /\A[\#=]/; CommentToken
|
929
|
+
when /\n\Z/; EscNlToken
|
919
930
|
else WsToken
|
920
931
|
end
|
921
932
|
result << klass.new(ws,offset+incr)
|
922
933
|
}
|
923
934
|
result.each_with_index{|ws,i|
|
924
935
|
if WsToken===ws
|
925
|
-
ws.ident << result.
|
936
|
+
ws.ident << result.delete_at(i+1).ident while WsToken===result[i+1]
|
926
937
|
end
|
927
938
|
}
|
928
939
|
return result
|
@@ -1052,15 +1063,21 @@ private
|
|
1052
1063
|
|
1053
1064
|
def keyword_do(str,offset,result)
|
1054
1065
|
result.unshift(*abort_noparens_for_do!(str))
|
1055
|
-
|
1066
|
+
ctx=@parsestack.last
|
1067
|
+
if ExpectDoOrNlContext===ctx
|
1056
1068
|
@parsestack.pop
|
1057
1069
|
assert WantsEndContext===@parsestack.last
|
1058
1070
|
result.last.as=";"
|
1059
1071
|
else
|
1060
1072
|
result.last.has_end!
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1073
|
+
if BlockContext===ctx and ctx.wanting_stabby_block_body
|
1074
|
+
ctx.wanting_stabby_block_body=false
|
1075
|
+
ctx.starter,ctx.ender="do","end"
|
1076
|
+
else
|
1077
|
+
@parsestack.push WantsEndContext.new(str,@linenum)
|
1078
|
+
localvars.start_block
|
1079
|
+
block_param_list_lookahead
|
1080
|
+
end
|
1064
1081
|
end
|
1065
1082
|
return result
|
1066
1083
|
end
|
@@ -1262,7 +1279,7 @@ private
|
|
1262
1279
|
result.push KwParamListStartToken.new(offset+str.length)
|
1263
1280
|
#corresponding EndToken emitted by abort_noparens! on leaving rescue context
|
1264
1281
|
@parsestack.push RescueSMContext.new(@linenum)
|
1265
|
-
result.unshift(*abort_noparens!(str))
|
1282
|
+
# result.unshift(*abort_noparens!(str))
|
1266
1283
|
end
|
1267
1284
|
return result
|
1268
1285
|
end
|
@@ -1386,16 +1403,17 @@ private
|
|
1386
1403
|
|
1387
1404
|
|
1388
1405
|
#-----------------------------------
|
1389
|
-
def block_param_list_lookahead
|
1406
|
+
def block_param_list_lookahead starter=?|, ctx_type=BlockParamListLhsContext
|
1390
1407
|
safe_recurse{ |la|
|
1391
1408
|
set_last_token KeywordToken.new( ';' )
|
1392
1409
|
a=ignored_tokens
|
1393
1410
|
|
1394
|
-
if eat_next_if(
|
1395
|
-
|
1411
|
+
if eat_next_if(starter)
|
1412
|
+
mycontext=ctx_type.new(@linenum)
|
1413
|
+
a<< KeywordToken.new(mycontext.starter, input_position-1)
|
1396
1414
|
if true
|
1397
|
-
@parsestack.push mycontext
|
1398
|
-
nextchar
|
1415
|
+
@parsestack.push mycontext
|
1416
|
+
nextchar==mycontext.ender[0] and a.push NoWsToken.new(input_position)
|
1399
1417
|
else
|
1400
1418
|
if eat_next_if(?|)
|
1401
1419
|
a.concat [NoWsToken.new(input_position-1),
|
@@ -1430,8 +1448,11 @@ else
|
|
1430
1448
|
a<< KeywordToken.new('|',tok.offset)
|
1431
1449
|
@moretokens.empty? or
|
1432
1450
|
fixme %#moretokens might be set from get1token call above...might be bad#
|
1433
|
-
end
|
1434
1451
|
end
|
1452
|
+
end
|
1453
|
+
elsif starter==?(
|
1454
|
+
ctx_type=UnparenedParamListLhsContext #hacky... should be a param?
|
1455
|
+
@parsestack.push ctx_type.new(@linenum)
|
1435
1456
|
end
|
1436
1457
|
|
1437
1458
|
set_last_token KeywordToken.new( ';' )
|
@@ -1594,7 +1615,8 @@ end
|
|
1594
1615
|
when AssignmentRhsContext; result.tag= :rhs
|
1595
1616
|
when ParamListContext,ParamListContextNoParen; #:call
|
1596
1617
|
when ListImmedContext; #:array
|
1597
|
-
when BlockParamListLhsContext; #:block
|
1618
|
+
when BlockParamListLhsContext,UnparenedParamListLhsContext; #:block or stabby proc
|
1619
|
+
when ParenedParamListLhsContext; #:stabby proc or method def'n?
|
1598
1620
|
when KnownNestedLhsParenContext; #:nested
|
1599
1621
|
else result.tag= :lhs if cill
|
1600
1622
|
end
|
@@ -1647,7 +1669,8 @@ end
|
|
1647
1669
|
|
1648
1670
|
s=tok.to_s
|
1649
1671
|
case s
|
1650
|
-
when /^[
|
1672
|
+
when /^[@$]/; true
|
1673
|
+
when /^<</; HerePlaceholderToken===tok
|
1651
1674
|
when /(?!#@@LETTER_DIGIT).$/o; false
|
1652
1675
|
# when /^#@@LCLETTER/o; localvars===s or VARLIKE_KEYWORDS===s
|
1653
1676
|
when /^#@@LETTER/o; VarNameToken===tok
|
@@ -1714,8 +1737,9 @@ end
|
|
1714
1737
|
end
|
1715
1738
|
when RescueSMContext
|
1716
1739
|
tok.as=";"
|
1717
|
-
end or
|
1740
|
+
end or
|
1718
1741
|
fail ": not expected in #{@parsestack.last.class}->#{@parsestack.last.starter}"
|
1742
|
+
|
1719
1743
|
|
1720
1744
|
#end ternary context, if any
|
1721
1745
|
@parsestack.last.see self,:colon
|
@@ -1748,7 +1772,7 @@ end
|
|
1748
1772
|
klass=(notbare ? SymbolToken : MethNameToken)
|
1749
1773
|
|
1750
1774
|
#look for operators
|
1751
|
-
opmatches=readahead(3)[
|
1775
|
+
opmatches=readahead(3)[@method_operators]
|
1752
1776
|
result= opmatches ? read(opmatches.size) :
|
1753
1777
|
case nc=nextchar
|
1754
1778
|
when ?" #"
|
@@ -1782,27 +1806,31 @@ end
|
|
1782
1806
|
return result
|
1783
1807
|
end
|
1784
1808
|
|
1809
|
+
#-----------------------------------
|
1785
1810
|
def merge_assignment_op_in_setter_callsites?
|
1786
1811
|
false
|
1787
1812
|
end
|
1813
|
+
|
1788
1814
|
#-----------------------------------
|
1789
1815
|
def callsite_symbol(tok_to_errify)
|
1790
1816
|
start= input_position
|
1791
1817
|
|
1792
1818
|
#look for operators
|
1793
|
-
opmatches=readahead(3)[
|
1794
|
-
return [
|
1795
|
-
|
1796
|
-
when ?`
|
1797
|
-
|
1819
|
+
opmatches=readahead(3)[@method_operators]
|
1820
|
+
return [read(opmatches.size), start] if opmatches
|
1821
|
+
case nc=nextchar
|
1822
|
+
when ?` #`
|
1823
|
+
return [read(1),start]
|
1824
|
+
when ?_,?a..?z,?A..?Z,NONASCII
|
1798
1825
|
context=merge_assignment_op_in_setter_callsites? ? ?: : nc
|
1799
|
-
identifier_as_string(context)
|
1800
|
-
|
1801
|
-
|
1802
|
-
|
1803
|
-
|
1804
|
-
|
1805
|
-
|
1826
|
+
return [identifier_as_string(context), start]
|
1827
|
+
when ?(
|
1828
|
+
return [nil,start] if @enable_macro
|
1829
|
+
end
|
1830
|
+
|
1831
|
+
set_last_token KeywordToken.new(';')
|
1832
|
+
lexerror(tok_to_errify,"unexpected char starting callsite symbol: #{nc.chr}, tok=#{tok_to_errify.inspect}")
|
1833
|
+
return [nil, start]
|
1806
1834
|
end
|
1807
1835
|
|
1808
1836
|
#-----------------------------------
|
@@ -2112,13 +2140,15 @@ end
|
|
2112
2140
|
pre=FileAndLineToken.new(@filename,@linenum+1,input_position)
|
2113
2141
|
pre.allow_ooo_offset=true
|
2114
2142
|
|
2115
|
-
|
2116
|
-
|
2117
|
-
|
2118
|
-
|
2119
|
-
|
2120
|
-
|
2121
|
-
|
2143
|
+
hard=NewlineToken===@last_operative_token || #hack
|
2144
|
+
(KeywordToken===@last_operative_token and
|
2145
|
+
@last_operative_token.ident=="rescue" and
|
2146
|
+
!@last_operative_token.infix?) ||
|
2147
|
+
!after_nonid_op?{false}
|
2148
|
+
|
2149
|
+
hard=false if @rubyversion>=1.9 and @file.check /\A\n(?:#@@WSTOKS)?\.[^.]/o
|
2150
|
+
|
2151
|
+
if hard
|
2122
2152
|
@offset_adjust=@min_offset_adjust
|
2123
2153
|
a= abort_noparens!
|
2124
2154
|
case @parsestack.last #these should be in the see:semi handler
|
@@ -2402,6 +2432,15 @@ end
|
|
2402
2432
|
/^(return|break|next)$/===@last_operative_token.ident
|
2403
2433
|
if (?0..?9)===readahead(2)[1]
|
2404
2434
|
return number(ch)
|
2435
|
+
elsif @rubyversion>=1.9 and '->' == readahead(2) #stabby proc
|
2436
|
+
#push down block context
|
2437
|
+
localvars.start_block
|
2438
|
+
@parsestack.push ctx=BlockContext.new(@linenum)
|
2439
|
+
ctx.wanting_stabby_block_body=true
|
2440
|
+
#read optional proc params
|
2441
|
+
block_param_list_lookahead ?(, ParenedParamListLhsContext
|
2442
|
+
|
2443
|
+
|
2405
2444
|
else #unary operator
|
2406
2445
|
result=getchar
|
2407
2446
|
WHSPLF[nextchar.chr] or
|
@@ -2575,8 +2614,13 @@ end
|
|
2575
2614
|
when '('
|
2576
2615
|
lasttok=last_token_maybe_implicit #last_operative_token
|
2577
2616
|
#could be: lasttok===/^#@@LETTER/o
|
2578
|
-
|
2579
|
-
|
2617
|
+
method_params= (
|
2618
|
+
VarNameToken===lasttok or
|
2619
|
+
MethNameToken===lasttok or
|
2620
|
+
lasttok===FUNCLIKE_KEYWORDS or
|
2621
|
+
(@enable_macro and lasttok and lasttok.ident==')')
|
2622
|
+
)
|
2623
|
+
if method_params
|
2580
2624
|
unless WHSPCHARS[lastchar]
|
2581
2625
|
@moretokens << tokch
|
2582
2626
|
tokch= NoWsToken.new(input_position-1)
|
@@ -2589,6 +2633,8 @@ end
|
|
2589
2633
|
!(KeywordToken===lasttok && lasttok.ident=="def")
|
2590
2634
|
if maybe_def or
|
2591
2635
|
BlockParamListLhsContext===ctx or
|
2636
|
+
ParenedParamListLhsContext===ctx or
|
2637
|
+
UnparenedParamListLhsContext===ctx or
|
2592
2638
|
ParenContext===ctx && ctx.lhs
|
2593
2639
|
@parsestack.push KnownNestedLhsParenContext.new(@linenum)
|
2594
2640
|
else
|
@@ -2614,9 +2660,13 @@ end
|
|
2614
2660
|
end
|
2615
2661
|
#=end
|
2616
2662
|
|
2617
|
-
|
2618
|
-
|
2619
|
-
|
2663
|
+
if BlockContext===@parsestack.last and @parsestack.last.wanting_stabby_block_body
|
2664
|
+
@parsestack.last.wanting_stabby_block_body=false
|
2665
|
+
else
|
2666
|
+
localvars.start_block
|
2667
|
+
@parsestack.push BlockContext.new(@linenum)
|
2668
|
+
block_param_list_lookahead
|
2669
|
+
end
|
2620
2670
|
end
|
2621
2671
|
end
|
2622
2672
|
return (tokch)
|
@@ -2645,6 +2695,10 @@ end
|
|
2645
2695
|
assert ch==')'
|
2646
2696
|
kw.set_callsite! #not needed?
|
2647
2697
|
end
|
2698
|
+
if ParenedParamListLhsContext===ctx
|
2699
|
+
assert @parsestack.last.wanting_stabby_block_body
|
2700
|
+
assert ch==')'
|
2701
|
+
end
|
2648
2702
|
return @moretokens.shift
|
2649
2703
|
end
|
2650
2704
|
|
@@ -2705,7 +2759,8 @@ end
|
|
2705
2759
|
when AssignmentRhsContext; token.tag=:rhs
|
2706
2760
|
when ParamListContext,ParamListContextNoParen; #:call
|
2707
2761
|
when ListImmedContext; #:array
|
2708
|
-
when BlockParamListLhsContext; #:block
|
2762
|
+
when BlockParamListLhsContext,UnparenedParamListLhsContext; #:block or stabby proc
|
2763
|
+
when ParenedParamListLhsContext; #stabby proc or method def'n?
|
2709
2764
|
when KnownNestedLhsParenContext; #:nested
|
2710
2765
|
else
|
2711
2766
|
token.tag=:lhs if comma_in_lvalue_list?
|
data/lib/rubylexer/context.rb
CHANGED
@@ -73,6 +73,7 @@ module NestedContexts
|
|
73
73
|
def initialize(linenum)
|
74
74
|
super('{','}',linenum)
|
75
75
|
end
|
76
|
+
attr_accessor :wanting_stabby_block_body
|
76
77
|
end
|
77
78
|
|
78
79
|
class BeginEndContext < NestedContext
|
@@ -109,6 +110,16 @@ module NestedContexts
|
|
109
110
|
def ender; '|' end
|
110
111
|
end
|
111
112
|
|
113
|
+
class ParenedParamListLhsContext < ImplicitLhsContext
|
114
|
+
def starter; '(' end
|
115
|
+
def ender; ')' end
|
116
|
+
end
|
117
|
+
|
118
|
+
class UnparenedParamListLhsContext < ImplicitLhsContext
|
119
|
+
def starter; huh end #" " ???
|
120
|
+
def ender; huh end #; or \n when from method def, { or do when from stabby block
|
121
|
+
end
|
122
|
+
|
112
123
|
class ImplicitContext < ListContext
|
113
124
|
end
|
114
125
|
|
data/lib/rubylexer/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubylexer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Caleb Clausen
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: ""
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-07-06 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -166,7 +166,7 @@ has_rdoc: true
|
|
166
166
|
homepage: http://github.com/coatl/rubylexer/
|
167
167
|
post_install_message:
|
168
168
|
rdoc_options:
|
169
|
-
- -x lib/rubylexer/test
|
169
|
+
- -x lib/rubylexer/test/oneliners.rb
|
170
170
|
require_paths:
|
171
171
|
- lib
|
172
172
|
required_ruby_version: !ruby/object:Gem::Requirement
|