package machine;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class Generated2 {
    
    //// Symbols ////
    // <BOF>
    // %action%
    // %base%
    // %bracket_comment%
    // %bracketed_state_list%
    // %component_option_section%
    // %component_rule_section%
    // %decl_region%
    // %delete_directive%
    // %identifier_directive%
    // %init_region%
    // %macro_invoc%
    // %metatoken_decl%
    // %open_rule_group%
    // %repetition_spec%
    // %string_directive%
    // %string%
    // END_ACTION
    // START_BRACKET_COMMENT
    // END_BRACKET_COMMENT
    // END_BRACKETED_STATE_LIST
    // START_DECL_REGION
    // START_INIT_REGION
    // START_MACRO_INVOC
    // START_REPETITION_SPEC
    // END_OPTION_SECTION
    // START_STRING
    // START_IDENTIFIER_DIRECTIVE
    // START_STRING_DIRECTIVE
    // START_BRACKETED_STATE_LIST
    // START_ACTION
    // START_DELETE_DIRECTIVE
    // END_RULE_SECTION
    // END_DECL_REGION
    // END_DELETE_DIRECTIVE
    // END_IDENTIFIER_DIRECTIVE
    // END_INIT_REGION
    // END_MACRO_INVOC
    // END_METATOKEN_DECL
    // END_OPEN_RULE_GROUP
    // END_REPETITION_SPEC
    // END_STRING_DIRECTIVE
    // END_STRING
    
    private static final Integer[][] trans_BASE = new Integer[][] {
        {0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
    };
    private static final Integer[] act_BASE = new Integer[] {null,4,};
    
    private static final Integer[][] trans_rule_delete_directive = new Integer[][] {
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,2,3,0,4,0,0,5,0,0,0,0,6,0,0,0,0,0,0,0,0,},
    };
    private static final Integer[] act_rule_delete_directive = new Integer[] {null,9,12,13,10,14,-1,};
    
    private static final Integer[][] trans_option_string_directive = new Integer[][] {
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,},
    };
    private static final Integer[] act_option_string_directive = new Integer[] {null,9,10,-1,};
    
    private static final Integer[][] trans_option_init = new Integer[][] {
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,},
    };
    private static final Integer[] act_option_init = new Integer[] {null,-1,};
    
    private static final Integer[][] trans_rule_section = new Integer[][] {
        {0,1,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,4,5,0,6,7,0,8,9,10,11,0,0,0,0,0,0,0,0,0,0,},
    };
    private static final Integer[] act_rule_section = new Integer[] {null,7,8,9,12,13,10,11,14,6,5,-1,};
    
    private static final Integer[][] trans_open_rule_group = new Integer[][] {
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,},
    };
    private static final Integer[] act_open_rule_group = new Integer[] {null,-1,};
    
    private static final Integer[][] trans_bracketed_state_list = new Integer[][] {
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
    };
    private static final Integer[] act_bracketed_state_list = new Integer[] {null,9,-1,};
    
    private static final Integer[][] trans_comments = new Integer[][] {
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
    };
    private static final Integer[] act_comments = new Integer[] {null,9,-1,};
    
    private static final Integer[][] trans_rule_metatoken = new Integer[][] {
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,},
    };
    private static final Integer[] act_rule_metatoken = new Integer[] {null,9,-1,};
    
    private static final Integer[][] trans_option_decl = new Integer[][] {
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,},
    };
    private static final Integer[] act_option_decl = new Integer[] {null,-1,};
    
    private static final Integer[][] trans_option_section = new Integer[][] {
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
    };
    private static final Integer[] act_option_section = new Integer[] {null,9,1,2,12,13,-1,10,11,3,};
    
    private static final Integer[][] trans_identifier_directive = new Integer[][] {
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,},
    };
    private static final Integer[] act_identifier_directive = new Integer[] {null,9,-1,};
    
    private static final Integer[][] trans_repetition_spec = new Integer[][] {
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,},
    };
    private static final Integer[] act_repetition_spec = new Integer[] {null,-1,};
    
    private static final Integer[][] trans_rule_action = new Integer[][] {
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
    };
    private static final Integer[] act_rule_action = new Integer[] {null,-1,};
    
    private static final Integer[][] trans_string = new Integer[][] {
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
    };
    private static final Integer[] act_string = new Integer[] {null,-1,};
    
    private static final Integer[][] trans_macro_invoc = new Integer[][] {
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,},
    };
    private static final Integer[] act_macro_invoc = new Integer[] {null,-1,};
    
    
    private static final Integer[][][] transitionTables = new Integer[][][] {
        trans_option_section,
        trans_option_decl,
        trans_option_init,
        trans_option_string_directive,
        trans_rule_section,
        trans_rule_delete_directive,
        trans_rule_action,
        trans_rule_metatoken,
        trans_open_rule_group,
        trans_comments,
        trans_string,
        trans_identifier_directive,
        trans_macro_invoc,
        trans_repetition_spec,
        trans_bracketed_state_list,
    };
    
    private static final Integer[][] actionTables = new Integer[][] {
        act_option_section,
        act_option_decl,
        act_option_init,
        act_option_string_directive,
        act_rule_section,
        act_rule_delete_directive,
        act_rule_action,
        act_rule_metatoken,
        act_open_rule_group,
        act_comments,
        act_string,
        act_identifier_directive,
        act_macro_invoc,
        act_repetition_spec,
        act_bracketed_state_list,
    };
    
    private final Stack<Integer> stateStack = new Stack<Integer>();
    
    private List<Integer> currentMatch = new ArrayList<Integer>();
    private int currentState = 0;
    private Integer[][] currentTransitionTable = trans_BASE;
    private Integer[] currentActionTable = act_BASE;
    
    public Generated2() {
        //Transition through states reachable by pure BOF patterns
        switchDFAs(/*option_section*/ 0); 
    }
    
    public Transition processSymbol(int sym) {
        currentMatch.add(sym);
        currentState = currentTransitionTable[currentState][sym];
        Integer action = currentActionTable[currentState];
        if(action == null) {
            return null;
        }
        Transition transition = new Transition(action, currentMatch);
        switchDFAs(action);
        return transition;
    }
    
    private void switchDFAs(int action) {
        currentState = 0;
        currentMatch.clear();
        
        int nextEmbedding;
        if(action < 0) {
            nextEmbedding = stateStack.pop();
        } else {
            stateStack.push(action);
            nextEmbedding = action;
        }
        currentTransitionTable = transitionTables[nextEmbedding];
        currentActionTable = actionTables[nextEmbedding];
    }
    
    public static class Transition {
        private final int embeddingNum;
        private final List<Integer> match;
        
        public Transition(int embeddingNum, List<Integer> match) {
            this.embeddingNum = embeddingNum;
            this.match = new ArrayList<Integer>(match);
        }
        
        public int getEmbeddingNum() { return embeddingNum; }
        
        public List<Integer> getMatch() { return match; }
    }
    
}

