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.
678 679 680 681 682 683 684 685 |
# File 'lib/redparse/compile.rb', line 678 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.
687 688 689 |
# File 'lib/redparse/compile.rb', line 687 def actions @actions end |
#dotteds ⇒ Object (readonly)
Returns the value of attribute dotteds.
702 703 704 |
# File 'lib/redparse/compile.rb', line 702 def dotteds @dotteds end |
#name ⇒ Object
841 842 843 |
# File 'lib/redparse/compile.rb', line 841 def name @name||@dotteds.map{|dotted| dotted.name}.join(",") end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
871 872 873 874 |
# File 'lib/redparse/compile.rb', line 871 def == other ParserState===other and @dotteds==other.dotteds end |
#[](k) ⇒ Object
689 690 691 692 693 |
# File 'lib/redparse/compile.rb', line 689 def [](k) result=@actions[k] assert ACTION_PATTERN===result result end |
#[]=(k, v) ⇒ Object
694 695 696 697 |
# File 'lib/redparse/compile.rb', line 694 def []=(k,v) assert ACTION_PATTERN===v @actions[k]=v end |
#dup ⇒ Object
704 705 706 707 708 |
# File 'lib/redparse/compile.rb', line 704 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
767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 |
# File 'lib/redparse/compile.rb', line 767 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
868 869 870 |
# File 'lib/redparse/compile.rb', line 868 def hash -@dotteds.hash end |
#looping? ⇒ Boolean
877 878 879 |
# File 'lib/redparse/compile.rb', line 877 def looping? @dotteds.any?{|dotted| dotted.looping? } end |
#make_sr_goto_tables(inputs) ⇒ Object
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 |
# File 'lib/redparse/compile.rb', line 892 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
859 860 861 862 863 864 865 866 |
# File 'lib/redparse/compile.rb', line 859 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
737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 |
# File 'lib/redparse/compile.rb', line 737 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
846 847 848 849 850 851 852 853 854 855 856 857 |
# File 'lib/redparse/compile.rb', line 846 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
712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 |
# File 'lib/redparse/compile.rb', line 712 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
699 700 701 |
# File 'lib/redparse/compile.rb', line 699 def sort_substates! @dotteds=@dotteds.sort_by{|dotted| -dotted.pos}.uniq end |
#substates ⇒ Object
710 |
# File 'lib/redparse/compile.rb', line 710 def substates; [self] end |
#transition_to_loop?(input) ⇒ Boolean
not used
881 882 883 884 885 886 887 888 889 890 |
# File 'lib/redparse/compile.rb', line 881 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 |