package fr.umlv.tatoo.tutorial.evaluation;

import java.io.InputStreamReader;
import java.io.Reader;

import fr.umlv.tatoo.runtime.buffer.impl.ReaderWrapper;
import fr.umlv.tatoo.runtime.lexer.Lexer;
import fr.umlv.tatoo.runtime.lexer.LexerWarningReporter;
import fr.umlv.tatoo.runtime.lexer.SimpleLexer;
import fr.umlv.tatoo.runtime.tools.AnalyzerListener;
import fr.umlv.tatoo.runtime.tools.DataViewer;
import fr.umlv.tatoo.runtime.tools.SemanticStack;
import fr.umlv.tatoo.runtime.tools.builder.Builder;
import fr.umlv.tatoo.tutorial.evaluation.lexer.LexerDataTable;
import fr.umlv.tatoo.tutorial.evaluation.lexer.RuleEnum;
import fr.umlv.tatoo.tutorial.evaluation.parser.NonTerminalEnum;
import fr.umlv.tatoo.tutorial.evaluation.parser.ParserDataTable;
import fr.umlv.tatoo.tutorial.evaluation.parser.ProductionEnum;
import fr.umlv.tatoo.tutorial.evaluation.parser.TerminalEnum;
import fr.umlv.tatoo.tutorial.evaluation.tools.AnalyzerProcessor;
import fr.umlv.tatoo.tutorial.evaluation.tools.GrammarEvaluator;
import fr.umlv.tatoo.tutorial.evaluation.tools.TerminalEvaluator;
import fr.umlv.tatoo.tutorial.evaluation.tools.ToolsDataTable;

public class EvaluationAnalyzer {

	public static void main(String[] args) {
		Reader reader = new InputStreamReader(System.in);
	    TerminalEvaluator<CharSequence> terminalEvaluator = new TerminalEvaluator<CharSequence>(){

			public int value(CharSequence data) {
				return Integer.parseInt(data.toString());
			}
	    	
	    };
	    GrammarEvaluator grammarEvaluator = new GrammarEvaluator(){
			public void acceptStart() {				
			}

			public int expr_minus(int expr, int expr2) {
				return expr - expr2;
			}

			public int expr_parens(int expr) {
				return expr;
			}

			public int expr_plus(int expr, int expr2) {
				return expr + expr2;
			}

			public int expr_star(int expr, int expr2) {
				return expr * expr2;
			}

			public int expr_value(int value) {
				return value;
			}

			public void start(int expr) {
				System.out.println("Result is: "+expr);
			}
	    	
	    };
	    AnalyzerListener<RuleEnum, ReaderWrapper, TerminalEnum, NonTerminalEnum, ProductionEnum> listener = AnalyzerProcessor.createAnalyzerProcessor(terminalEvaluator, grammarEvaluator,DataViewer.<CharSequence>getTokenBufferViewer() , new SemanticStack());
	    SimpleLexer lexer = Builder.analyzer(
	    	      LexerDataTable.createTable(),
	    	      ParserDataTable.createTable(),
	    	      ToolsDataTable.createToolsTable()).reader(reader)
	    	      .listener(listener).expert()
	    			.defaultLexerErrorPolicy(
	        				new LexerWarningReporter<ReaderWrapper>(){

	        					public void handleWarning(Lexer<? extends ReaderWrapper> arg0, String arg1) {
	        						System.err.println("Warning: "+args1);
	        					}
	        				}).createLexer();
	    	     
	    
           lexer.run();
	}

}
