package ca.uwaterloo.joos;

import java.util.*;
import java.util.logging.*;

import ca.uwaterloo.joos.LR1.*;

/**
 *
 * @author Wenzhu Man
 *
 *
 */

public class LR1Parser {
	private static final Logger logger = Main.getLogger();
	private final LR1 lr1;

	private class TransitionState {
		private Token token;
		private int state;

		public TransitionState(Token token, int state) {
			this.state = state;
			this.token = token;
		}

		public int getState() {
			return state;
		}

		public String toString() {
			return "<TransitionState> " + String.valueOf(this.state) + " | " + this.token;
		}
	}

	public LR1Parser(LR1 lr1) {
		this.lr1 = lr1;
	}

	public boolean checkGrammer(List<Token> tokens) {
		String startSymbol = lr1.getStartSymbol();
		ListIterator<Token> tokensIterator = tokens.listIterator();
		Stack<TransitionState> parseStack = new Stack<TransitionState>();
		parseStack.push(new TransitionState(null, 0));

		int currentState = 0;
		Token nextToken = tokensIterator.next();
		Action nextAction = null;
		while (!nextToken.getKind().equals(startSymbol)) {
			currentState = parseStack.peek().getState();
			nextAction = lr1.actionFor(currentState, nextToken.getKind());
			LR1Parser.logger.fine("Next:\tState " + currentState + " + " + nextToken + " => " + nextAction);

			if (nextAction instanceof LR1.ActionShift) {
				ActionShift shift = (ActionShift) nextAction;
				LR1Parser.logger.info("Shift:\t" + shift);

				TransitionState transitionState = new TransitionState(nextToken, shift.getToState());
				parseStack.push(transitionState);
				LR1Parser.logger.info("├─ Push:\t" + transitionState);

				if(!tokensIterator.hasNext()) tokensIterator = tokens.listIterator();
				nextToken = tokensIterator.next();
			}
			else if (nextAction instanceof LR1.ActionReduce){
				ActionReduce reduce = (ActionReduce) nextAction;
				LR1Parser.logger.info("Redue:\t" + reduce);

				for (int i = 0; i < reduce.getInt(); i++) {
					TransitionState poppedState = parseStack.pop();
					LR1Parser.logger.info("├─ Pop:\t" + poppedState);
				}
				tokensIterator.previous();
				nextToken = new Token(reduce.getProductionRule().getLefthand(), Arrays.toString(reduce.getProductionRule().getRighthand()));
			}
			else {
				LR1Parser.logger.severe("ERROR: No valid action for State " + currentState + " + " + nextToken);
				return false;
			}
		}

		LR1Parser.logger.info("Tokens has been validated against LR1");
		return true;
	}
}

@@ -698,16 +698,79 @@
 kens) %7B%0A
+%09%09// Initialize startSymbol, tokens iterator and parsing stack%0A
 %09%09String
@@ -992,29 +992,45 @@
 %0A%0A%09%09
-int currentState = 0;
+// Initialize parsing state variables
 %0A%09%09T
@@ -1103,106 +1103,225 @@
 ;%0A%09%09
-while (!nextToken.getKind().equals(startSymbol)) %7B%0A%09%09%09currentState = parseStack.peek().getState();
+%0A%09%09// Execute lr1 parsing until the tokens has been reduced to the startSymbol%0A%09%09while (!nextToken.getKind().equals(startSymbol)) %7B%0A%09%09%09%0A%09%09%09// Acquire next action, according to the current state and the next token kind
 %0A%09%09%09
@@ -1347,28 +1347,44 @@
 tionFor(
-curren
+parseStack.peek().ge
 tState
+()
 , nextTo
@@ -1438,36 +1438,52 @@
 %5CtState %22 + 
-curren
+parseStack.peek().ge
 tState
+()
  + %22 + %22 + n
@@ -1516,16 +1516,36 @@
 tion);%0A%0A
+%09%09%09// If is a shift%0A
 %09%09%09if (n
@@ -1678,24 +1678,69 @@
  + shift);%0A%0A
+%09%09%09%09// Push the transitionState to the stack%0A
 %09%09%09%09Transiti
@@ -1911,24 +1911,119 @@
 ionState);%0A%0A
+%09%09%09%09// Iterate to next token%0A%09%09%09%09// Note: if there is no next, move cursor back to front first%0A
 %09%09%09%09if(!toke
@@ -2120,32 +2120,56 @@
 or.next();%0A%09%09%09%7D%0A
+%09%09%09// If is a reduction%0A
 %09%09%09else if (next
@@ -2303,24 +2303,98 @@
 + reduce);%0A%0A
+%09%09%09%09// Pop the stack according to the length of the production rule's RHS%0A
 %09%09%09%09for (int
@@ -2551,34 +2551,164 @@
 %09%09%09%09
-tokensIterator.previous();
+%0A%09%09%09%09// Iterate back one token, since it has not been pushed to the stack%0A%09%09%09%09tokensIterator.previous();%0A%09%09%09%09%0A%09%09%09%09// Next token is the production rule's LHS
 %0A%09%09%09
@@ -2838,16 +2838,57 @@
 );%0A%09%09%09%7D%0A
+%09%09%09// No action found, validation failed%0A
 %09%09%09else 
@@ -2959,20 +2959,36 @@
 %22 + 
-curren
+parseStack.peek().ge
 tState
+()
  + %22
@@ -3034,16 +3034,84 @@
 %09%7D%0A%09%09%7D%0A%0A
+%09%09// The tokens has been reduced to startSymbol, validation succeed%0A
 %09%09LR1Par

Add comments for LR1Parser