public Boolean InputLine(String line){
		int symbolIndex;
		if (line != null) {
			String symbol = line.substring(0, line.indexOf(' '));
			String temp = line.substring(line.indexOf(' ') + 1);
			mCurrentLineOfCode = Integer.parseInt(temp.substring(0, temp.indexOf(' ')));
			symbolIndex = mSymbolsHashMap.get(symbol);
		}
		else symbolIndex = Utilities.EOFTerminalSymbolCode;
		
		if (mErrorRecoveryMode){
			// discard everything up until we get a synchronization symbol.
			if (!mSyncronizationSymbols.contains(symbolIndex)) return true;
			else{
				Cell_Action tempCA = mCellsA.get(new TableKey(symbolIndex, mStack.peek()));
				while (tempCA == null) {
					mStack.pop();
					mStack.pop();
					mSTN_Stack.pop();
					tempCA = mCellsA.get(new TableKey(symbolIndex, mStack.peek()));
				}
				mErrorRecoveryMode = false;
			}
		}
		
		Cell_Action tempCA = mCellsA.get(new TableKey(symbolIndex, mStack.peek()));
		if (tempCA == null) {
			mErrorRecoveryMode = true;
			System.err.println("Syntax error in line: " + mCurrentLineOfCode);
			return false;
		}
		
		SyntaxTreeNode newNode;
		switch (tempCA.mActionType){
		case Move:
			mStack.push(symbolIndex);
			mStack.push(tempCA.mActionSpecificValue_a); // index of a new state
			// syntax tree generation
			newNode = new SyntaxTreeNode();
			newNode.mName = line;
			mSTN_Stack.push(newNode);
			return true;
			
		case Reduce:
			// how many to pop (* 2 because state indexes need to be removed too)
			int popC1 = tempCA.mActionSpecificValue_a * 2;
			while (popC1-- > 0) mStack.pop();
			
			int currentStateIndex = mStack.peek();
			int nonTerminalSymbolIndex = tempCA.mActionSpecificValue_b;
			Cell_NewState tempNS = mCellsNS.get(new TableKey(nonTerminalSymbolIndex, currentStateIndex));
			int newStateIndex = tempNS.mActionSpecificValue;
			mStack.push(nonTerminalSymbolIndex); // <-- reduce to this
			mStack.push(newStateIndex);	
			
			// syntax tree generation
			newNode = new SyntaxTreeNode();
			newNode.mName = mSymbols.get(nonTerminalSymbolIndex);
			int popC2 = tempCA.mActionSpecificValue_a;
			if (popC2 == 0) { // was this epsilon production?
				SyntaxTreeNode epsilon = new SyntaxTreeNode();
				epsilon.mName = "$";
				newNode.mChildren.add(epsilon);
			}else{
				while (popC2-- > 0){
					newNode.mChildren.add(0, mSTN_Stack.pop());
				}
			}
			
			mSTN_Stack.push(newNode);
			return false;
			
		case Accept:
			// syntax tree generation
			newNode = new SyntaxTreeNode();
			newNode.mName = mSymbols.get(0); // index = 0 because the first defined symbol is always the initial one.
			int popC = mSTN_Stack.size();
			while (popC-- > 0){ // empty the stack
				newNode.mChildren.add(0, mSTN_Stack.pop());
			}
			mSTN_Stack.push(newNode); // at the end there must be just one node on the stack
			return true;
			
		default:
			return false;
		}
	}