/* * * Copyright 2012 lexergen. * This file is part of lexergen. * * lexergen is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * lexergen is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with lexergen. If not, see <http://www.gnu.org/licenses/>. * * lexergen: * A tool to chunk source code into tokens for further processing in a compiler chain. * * Projectgroup: bi, bii * * Authors: Alexander Niemeier, Benjamin Weißenfels, Daniel Rotar, Johannes Dahlke, Maximilian Schröder, Philipp Schröter, Wojciech Lukasiewicz, Yanlei Li * * Module: Softwareprojekt Übersetzerbau 2012 * * Created: Apr. 2012 * Version: 1.0 * */ package de.fuberlin.bii; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.NoSuchElementException; import javax.sound.midi.SysexMessage; import de.fuberlin.bii.lexergen.BuilderType; import de.fuberlin.bii.lexergen.Lexergen; import de.fuberlin.bii.parser.IToken; import de.fuberlin.bii.tokenmatcher.Token; import de.fuberlin.bii.tokenmatcher.errorhandler.ErrorCorrector.CorrectionMode; import de.fuberlin.bii.utils.ApplicationArgument; import de.fuberlin.bii.utils.ApplicationArgumentProcessor; import de.fuberlin.bii.utils.InvalidArgumentException; import de.fuberlin.bii.utils.Notification; import de.fuberlin.bii.utils.StrUtils; import de.fuberlin.bii.utils.Test; import de.fuberlin.commons.lexer.ILexer; import de.fuberlin.commons.lexer.TokenType; /** * * @author Alexander Niemeier * @author Benjamin Weißenfels * @author Daniel Rotar * @author Johannes Dahlke * @author Maximilian Schröder * @author Philipp Schröter * @author Wojciech Lukasiewicz * @author Yanlei Li * */ public class Lexer { private static ApplicationArgumentProcessor argumentProcessor; private static ILexer lexer; private static File definitionFile; private static File sourceFile; private static BuilderType builderType = BuilderType.directBuilder; private static boolean rebuildDfa = false; private static CorrectionMode correctionMode = CorrectionMode.PANIC_MODE; private static boolean lineBreak = false; private static boolean noHeader = false; /** * Liest die übergebenen Argumente ein. Analysiert sie auf Syntax und filtert * die akzeptierten Parameter heraus * * @param args * @throws InvalidArgumentException */ private static void initArgumentProcessor() throws InvalidArgumentException { // param verbose final ApplicationArgument beVerboseArgument = new ApplicationArgument( "v", "verbose") { protected void execute() { Notification.enableInfoPrinting(); }; @Override protected boolean acceptParam( String param) { return false; } }; // param errors final ApplicationArgument notifyErrorsArgument = new ApplicationArgument( "e", "errors") { protected void execute() { if ( getParamList().contains( "suppress")) Notification.disableErrorPrinting(); else Notification.enableErrorPrinting(); }; @Override protected boolean acceptParam( String param) { return param.equals( "suppress"); } }; // param debug final ApplicationArgument debugArgument = new ApplicationArgument( "db", "debug") { protected void execute() { Notification.enableDebugPrinting(); }; @Override protected boolean acceptParam( String param) { return false; } }; // param tokendefinition file final ApplicationArgument tokendefFileArgument = new ApplicationArgument( "d", "token-definition") { protected void execute() { if ( getParamList().size() < 1) { System.err.println( "No definition file specified."); System.exit( 1); } else definitionFile = new File( getParamList().get( 0)); }; @Override protected boolean acceptParam( String param) { return getParamList().size() == 0; } }; // param rebuild dfa final ApplicationArgument rebuildDfaArgument = new ApplicationArgument( "rb", "rebuild-dfa") { protected void execute() { rebuildDfa = true; builderType = ( getParamList().contains( "bi")) ? BuilderType.indirectBuilder : BuilderType.directBuilder; }; @Override protected boolean acceptParam( String param) { return param.equals( "bi") || // indirect param.equals( "bii"); // direct } }; // param source file final ApplicationArgument sourceFileArgument = new ApplicationArgument( "f", "source-file") { protected void execute() { if ( getParamList().size() < 1) { System.err.println( "No source file specified."); System.exit( 1); } else sourceFile = new File( getParamList().get( 0)); }; @Override protected boolean acceptParam( String param) { return getParamList().size() == 0; } }; // param linebreak final ApplicationArgument lineBreakArgument = new ApplicationArgument( "lb", "line-break") { protected void execute() { lineBreak = true; }; @Override protected boolean acceptParam( String param) { return false; } }; // param usage final ApplicationArgument helpArgument = new ApplicationArgument( "h", "help") { protected void execute() { printUsage(); System.exit( 0); }; @Override protected boolean acceptParam( String param) { return false; } }; // param usage final ApplicationArgument bareArgument = new ApplicationArgument( "b", "bare") { protected void execute() { noHeader = true; }; @Override protected boolean acceptParam( String param) { return false; } }; argumentProcessor = new ApplicationArgumentProcessor( beVerboseArgument, notifyErrorsArgument, debugArgument, tokendefFileArgument, rebuildDfaArgument, sourceFileArgument, lineBreakArgument, helpArgument, bareArgument ); } /** * Untersucht die Argumente, welche der ArgumentProcessor eingelesen hat. * * @param args * @throws NoSuchElementException * @throws IllegalArgumentException * */ private static void processArguments(String[] args) throws NoSuchElementException { argumentProcessor.processArguments( args); } //force-rebuild /** * Erstellt ein neues Lexergen Objekt. * * @param regularDefinitionFile * Die Datei, die die regulären Definitionen enthält. * @param sourceProgramFile * Die Datei, die das Quellprogramm enthält. * @param builderType * Der Typ der DFA-Erstellung. * @param errorCorrectionMode * Der Modus der Fehlerbehandlung. * @param forceRebuild * Erzwingt die Neuerstellung des DFAs. */ private static void runApplication() throws Exception { if ( !noHeader) printEnvInfo(); if ( Test.isUnassigned( definitionFile) || Test.isUnassigned( sourceFile)) { System.err.println( "Insufficient parameterization"); System.exit( 1); } lexer = new Lexergen( definitionFile, sourceFile, builderType, correctionMode, rebuildDfa); Token token; String postFix = lineBreak ? "\n" : ""; do { token = (Token) lexer.getNextToken(); System.out.print( token.toString()+postFix); } while ( !token.isEofToken()); } private static void printEnvInfo() { System.out.println( "-------------------------------------------------------------------------------"); System.out.println( "token definition file: \t" + definitionFile); System.out.println( "source file: \t\t" + sourceFile); System.out.println( "dfa builder type: \t" + builderType.toString()); System.out.println( "force dfa rebuild: \t"+ rebuildDfa); System.out.println( "correction mode: \t" + correctionMode.toString()); System.out.println( "insert line breaks: \t" + lineBreak); System.out.println( "-------------------------------------------------------------------------------"); System.out.println(); } private static void printUsage() { System.out.println( "Usage: java -jar lexer.jar -d <path> -f <path>"); System.out.println(); System.out.println( "Expected parameters:"); System.out.println( "-d, --token-definition <path> \t Specifies the token definition file."); System.out.println( "-f, --source-file <path> \t Specifies the source file to lex."); System.out.println(); System.out.println( "Optional parameters:"); System.out.println( "-b, --bare \t\t\t Suppress information header."); System.out.println( "-db, --debug \t\t\t Enables output of debug informations."); System.out.println( "-e, --errors [suppress] \t Enables or suppress error printing."); System.out.println( "-h, --help \t\t\t Shows this help."); System.out.println( "-lb, --line-break \t\t Appends a line break after each token."); System.out.println( "-rb, --rebuild-dfa [bi|bii] \t Forces the rebuild of the normally persitent DFA."); System.out.println( "-v, --verbose \t\t\t Prints additional information while lex."); System.out.println(); System.out.println( "Authors: Alexander Niemeier, Benjamin Weißenfels, Daniel Rotar, Johannes Dahlke, " + "Maximilian Schröder, Philipp Schröter, Wojciech Lukasiewicz, Yanlei Li"); } public static void main( String[] args) { Notification.enableErrorPrinting(); try { initArgumentProcessor(); processArguments( args); } catch ( InvalidArgumentException e) { // Notification Service ist hier möglicherweise noch nicht aufgesetzt. System.err.println( e); } try { runApplication(); } catch ( Exception e) { Notification.printDebugException( e); Notification.printErrorMessage( e.getMessage()); } } }