package fr.umlv.tatoo.tutorial.translation;

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.translation.lexer.LexerDataTable;
import fr.umlv.tatoo.tutorial.translation.lexer.RuleEnum;
import fr.umlv.tatoo.tutorial.translation.parser.NonTerminalEnum;
import fr.umlv.tatoo.tutorial.translation.parser.ParserDataTable;
import fr.umlv.tatoo.tutorial.translation.parser.ProductionEnum;
import fr.umlv.tatoo.tutorial.translation.parser.TerminalEnum;
import fr.umlv.tatoo.tutorial.translation.tools.AnalyzerProcessor;
import fr.umlv.tatoo.tutorial.translation.tools.GrammarEvaluator;
import fr.umlv.tatoo.tutorial.translation.tools.TerminalEvaluator;
import fr.umlv.tatoo.tutorial.translation.tools.ToolsDataTable;

public class TranslationAnalyzer {

	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 ExprContent expr_minus(ExprContent expr, ExprContent expr2) {
				String s = "- "+ expr.getTranslation()+" "+expr2.getTranslation();
				int value = expr.getValue() - expr2.getValue();
				return new ExprContent(s,value);
			}

			public ExprContent expr_parens(ExprContent expr) {				
				return new ExprContent(expr.getTranslation(),expr.getValue());
			}

			public ExprContent expr_plus(ExprContent expr, ExprContent expr2) {
				String s = "+ "+ expr.getTranslation()+" "+expr2.getTranslation();
				int value = expr.getValue() + expr2.getValue();
				return new ExprContent(s,value);
			}

			public ExprContent expr_star(ExprContent expr, ExprContent expr2) {
				String s = "* "+ expr.getTranslation()+" "+expr2.getTranslation();
				int value = expr.getValue() * expr2.getValue();
				return new ExprContent(s,value);
			}

			public ExprContent expr_value(int value) {
				return new ExprContent(""+value,value);
			}

			public void start(ExprContent expr) {
				System.out.println("Translation is: " + expr.getTranslation());
				System.out.println("Result is: " +expr.getValue());
			}
			
		};
		
		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();
	}

	
	
}
