Class: RedParse::ParserState
- Inherits:
-
Object
- Object
- RedParse::ParserState
- Defined in:
- lib/redparse/compile.rb,
lib/redparse/compile.rb
Overview
a union of dotted rules
Instance Attribute Summary collapse
-
#actions ⇒ Object
readonly
Returns the value of attribute actions.
-
#dotteds ⇒ Object
readonly
Returns the value of attribute dotteds.
- #name ⇒ Object
Instance Method Summary collapse
- #==(other) ⇒ Object (also: #eql?)
- #[](k) ⇒ Object
- #[]=(k, v) ⇒ Object
- #dup ⇒ Object
-
#evolve(input, parser, seenlist) ⇒ Object
returns ParserState|MultiShift|MultiReduce|Rule|:accept|:error.
- #hash ⇒ Object
-
#initialize(dotteds, index) ⇒ ParserState
constructor
A new instance of ParserState.
- #looping? ⇒ Boolean
- #make_sr_goto_tables(inputs) ⇒ Object
- #most_prominent_members ⇒ Object
- #old_perhaps_also_allow(morerules, parser) ⇒ Object (also: #perhaps_also_allow)
- #rename(name2count) ⇒ Object
- #shiftlist2multishift?(shiftlist, parser) ⇒ Boolean
- #sort_substates! ⇒ Object
- #substates ⇒ Object
-
#transition_to_loop?(input) ⇒ Boolean
not used.
Constructor Details
#initialize(dotteds, index) ⇒ ParserState
Returns a new instance of ParserState.
770 771 772 773 774 775 776 777 |
# File 'lib/redparse/compile.rb', line 770 def initialize(dotteds,index) fail if dotteds.empty? #error state fail unless dotteds.grep(nil).empty? @dotteds=dotteds @index=index sort_substates! @actions={} #key is an input, value is ParserState|Rule|MultiShift|MultiReduce|:accept|:error end |
Instance Attribute Details
#actions ⇒ Object (readonly)
Returns the value of attribute actions.
779 780 781 |
# File 'lib/redparse/compile.rb', line 779 def actions @actions end |
#dotteds ⇒ Object (readonly)
Returns the value of attribute dotteds.
794 795 796 |
# File 'lib/redparse/compile.rb', line 794 def dotteds @dotteds end |
#name ⇒ Object
933 934 935 |
# File 'lib/redparse/compile.rb', line 933 def name @name||@dotteds.map{|dotted| dotted.name}.join(",") end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
963 964 965 966 |
# File 'lib/redparse/compile.rb', line 963 def == other ParserState===other and @dotteds==other.dotteds end |
#[](k) ⇒ Object
781 782 783 784 785 |
# File 'lib/redparse/compile.rb', line 781 def [](k) result=@actions[k] assert ACTION_PATTERN===result result end |
#[]=(k, v) ⇒ Object
786 787 788 789 |
# File 'lib/redparse/compile.rb', line 786 def []=(k,v) assert ACTION_PATTERN===v @actions[k]=v end |
#dup ⇒ Object
796 797 798 799 800 |
# File 'lib/redparse/compile.rb', line 796 def dup result=super result.instance_variable_set(:@dotteds,@dotteds.dup) return result end |
#evolve(input, parser, seenlist) ⇒ Object
returns ParserState|MultiShift|MultiReduce|Rule|:accept|:error
859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 |
# File 'lib/redparse/compile.rb', line 859 def evolve input,parser,seenlist result2=[] @dotteds.each{|dotted| dotted.evolve input,parser,seenlist,result2 } result= #seenlist.values.flatten.compact.uniq.sort_by{|x| x.name} result2=result2.uniq.compact.sort_by{|x| x.name} #pp [result,result2].map{|x| x.map{|res| DottedRule===res ? res.name : res }} #pp result2.map{|res| DottedRule===res ? res.name : res } # result==result2 or fail return result=:error if result.empty? #ok, who wants to shift and who wants to reduce? shiftlist,reducelist=result.partition{|res| DottedRule===res or Conditional===res && DottedRule===res.action } #if no reducers at all, just try (multi?)shift return result=shiftlist2multishift?( shiftlist,parser )if reducelist.empty? #line up reducers by priority actions=reducelist \ .sort_by{|rule| -rule.priority } # .map{|rule| rule.action } #actions is +[(Rule|Conditional[Rule]).*] action=actions.shift #this first (unless conditional) #action is Rule|Conditional[Rule] result= case action.action when :error; return :error when Class, StackMonkey action when :accept :accept when :shift #this counts as a reduce at this point, but it writes shift instructions shiftlist2multishift? shiftlist,parser when Rule #oy, vey, was a Conditional shiftaction=shiftlist2multishift?(shiftlist,parser) fail unless Rule===action.action case action.action.action when :error; huh when :shift, StackMonkey, :accept, Class #MultiReduce first_fixed_index=actions.size #actions is +[(Rule|Conditional[Rule]).*] actions.each_with_index{|act,i| break first_fixed_index=i unless Conditional===act } condactions=actions[0...first_fixed_index].unshift(action) condactions=condactions.inject([]){|sum,cond| act=cond.action act=shiftaction if act==:shift #=>shiftlist? sum.push cond.condition, act } #possible optimization: one or more :shift right at end could be ignored if actions[first_fixed_index] action=actions[first_fixed_index].action else action=shiftaction end MultiReduce.new condactions,action #=>shiftlist? else fail end else fail "#{action} not expected here" end #stack monkeys/:accept are treated like reduce here ensure assert ACTION_PATTERN===result end |
#hash ⇒ Object
960 961 962 |
# File 'lib/redparse/compile.rb', line 960 def hash -@dotteds.hash end |
#looping? ⇒ Boolean
969 970 971 |
# File 'lib/redparse/compile.rb', line 969 def looping? @dotteds.any?{|dotted| dotted.looping? } end |
#make_sr_goto_tables(inputs) ⇒ Object
984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 |
# File 'lib/redparse/compile.rb', line 984 def make_sr_goto_tables inputs name2exemplar={} inputs.each{|i| name2exemplar[i.name]=i } @goto={}; @sr={} goto_counts=Hash.new(0); sr_counts=Hash.new(0) actions.each_pair{|k,v| if Node===name2exemplar[k] @goto[k]=v goto_counts[v]+=1 else assert(Token===name2exemplar[k]) @sr[k]=v sr_counts[v]+=1 end } dflt=goto_counts.sort_by{|v,c| c}.last[0] @goto.delete_if{|k,v| v==dflt } @goto.default=dflt dflt=sr_counts.sort_by{|v,c| c}.last[0] @sr.delete_if{|k,v| v==dflt } @sr.default=dflt @actions=nil end |
#most_prominent_members ⇒ Object
951 952 953 954 955 956 957 958 |
# File 'lib/redparse/compile.rb', line 951 def most_prominent_members result=@dotteds.select{|dr| dr.pos==@dotteds.first.pos } close2end=@dotteds.map{|dr| [dr,dr.rule.patterns.size-dr.pos]}.sort_by{|(o,k)| -k} result+=close2end.select{|(dr,k)| k==close2end.first.last}.map{|(dr,k)| dr} result2=result.reject{|dr| dr.pos==0 or dr.pos==1&&dr.rule.lookback?} result=result2 unless result2.empty? return result end |
#old_perhaps_also_allow(morerules, parser) ⇒ Object Also known as: perhaps_also_allow
829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 |
# File 'lib/redparse/compile.rb', line 829 def old_perhaps_also_allow(morerules,parser) morerules=morerules.dup need_sort=false scan_rules=@dotteds added={} while true adding=[] morerules.each{|morerule| next if added[morerule] fake_rule=morerule.final_promised_rule final_more_dr=DottedRule.create(fake_rule,0,parser) scan_rules.each{|dotted| if dotted.optionally_combine final_more_dr,parser adding<<DottedRule.create(morerule,0,parser) added[morerule]=1 break end } } break if adding.empty? @dotteds.concat adding need_sort=true scan_rules=adding end sort_substates! if need_sort end |
#rename(name2count) ⇒ Object
938 939 940 941 942 943 944 945 946 947 948 949 |
# File 'lib/redparse/compile.rb', line 938 def rename(name2count) return @name if defined? @name name=most_prominent_members.map{|dotted| dotted.name}.join(",") if name2count[name] name2count[name]+=1 name+="___"+name2count[name].to_s else name2count[name]=1 end @name=name end |
#shiftlist2multishift?(shiftlist, parser) ⇒ Boolean
804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 |
# File 'lib/redparse/compile.rb', line 804 def shiftlist2multishift? shiftlist,parser return :error if shiftlist.empty? parser.sl2ms_cache||={} cache=parser.sl2ms_cache[shiftlist] return cache if cache fixed,=shiftlist.partition{|res| DottedRule===res} result=ParserState.new(fixed,nil) result.perhaps_also_allow parser.all_rules,parser unless .empty? #MultiShift .map!{|v| [v.condition,v.action]}.flatten result=MultiShift.new(result,) end parser.sl2ms_cache[shiftlist]=result return result end |
#sort_substates! ⇒ Object
791 792 793 |
# File 'lib/redparse/compile.rb', line 791 def sort_substates! @dotteds=@dotteds.sort_by{|dotted| -dotted.pos}.uniq end |
#substates ⇒ Object
802 |
# File 'lib/redparse/compile.rb', line 802 def substates; [self] end |
#transition_to_loop?(input) ⇒ Boolean
not used
973 974 975 976 977 978 979 980 981 982 |
# File 'lib/redparse/compile.rb', line 973 def transition_to_loop? input #not used action=@actions.input case action when :error; false when ParserState; action.looping? and action!=self when MultiShift,MultiReduce; action.transition_to_loop? input else fail end end |