All Downloads are FREE. Search and download functionalities are using the official Maven repository.

lt.compiler.ErrorManager Maven / Gradle / Ivy

Go to download

The latte-lang compiler project, which contains compiler and runtime required library.

The newest version!
/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2016 KuiGang Wang
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package lt.compiler;

import lt.compiler.lexical.IllegalIndentationException;
import lt.compiler.syntactic.DuplicateVariableNameException;
import lt.compiler.syntactic.UnexpectedNewLayerException;
import lt.compiler.syntactic.UnknownTokenException;

import java.io.PrintStream;
import java.text.DateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * controls compiling errors/info/warnings display and exception throwing.
 */
public class ErrorManager {
        public static class Out {
                public PrintStream debug = null;
                public PrintStream info = System.out;
                public PrintStream warn = System.err;
                public PrintStream err = System.err;

                public static Out allNull() {
                        Out out = new Out();
                        out.debug = null;
                        out.info = null;
                        out.warn = null;
                        out.err = null;
                        return out;
                }
        }

        private boolean fastFail;
        public Out out = new Out();
        public final List errorList = new ArrayList();

        public final StringBuilder sb = new StringBuilder();

        /**
         * records {fileName =>{LineNumber=>LineContent}}
         */
        public final Map> lineRecord = new ConcurrentHashMap>();

        public static class CompilingError {
                public final String msg;
                public final LineCol lineCol;
                public final int type;

                public static final int Syntax = 1;
                public static final int UnknownToken = 2;
                public static final int UnexpectedToken = 3;
                public static final int Indentation = 4;
                public static final int UnexpectedEnd = 5;
                public static final int UnexpectedNewLayer = 6;
                public static final int DuplicateVariableName = 7;

                private CompilingError(String msg, LineCol lineCol, int type) {
                        this.msg = msg;
                        this.lineCol = lineCol;
                        this.type = type;
                }
        }

        private static final DateFormat df = DateFormat.getDateTimeInstance();

        /**
         * construct an ErrorManager
         *
         * @param fastFail throw exception when meets an exception
         */
        public ErrorManager(boolean fastFail) {
                this.fastFail = fastFail;
        }

        /**
         * set fast fail. It's called in {@link SemanticProcessor}
         *
         * @param fastFail fast fail
         */
        public void setFastFail(boolean fastFail) {
                this.fastFail = fastFail;
        }

        /**
         * put the line record
         *
         * @param file    file name
         * @param line    the line number
         * @param content the content of the line
         */
        public void putLineRecord(String file, int line, String content) {
                Map map;
                if (lineRecord.containsKey(file)) {
                        map = lineRecord.get(file);
                } else {
                        map = new HashMap();
                        lineRecord.put(file, map);
                }

                map.put(line, content);
        }

        /**
         * build error info. The error info looks like :
*
         * the statement
         *     ^
         * 

* detailed info can directly concat to this string * * @param file the file * @param line line * @param col column * @return the error info */ public String buildErrInfo(String file, int line, int col) { if (!lineRecord.containsKey(file)) return ""; String content = lineRecord.get(file).get(line); if (content == null) return ""; StringBuilder sb = new StringBuilder("\n"); sb.append(content).append("\n"); for (int i = 1; i < col; ++i) { sb.append(" "); } sb.append("^ "); return sb.toString(); } /** * invoke {@link #buildErrInfo(String, int, int)} * * @param lineCol line col * @return the error info */ public String buildErrInfo(LineCol lineCol) { if (lineCol == null || lineCol.fileName == null || lineCol.line <= 0 || lineCol.column <= 0) return ""; return buildErrInfo(lineCol.fileName, lineCol.line, lineCol.column); } private void print(String msg, PrintStream out) { if (out != null) { msg = "[" + df.format(new Date()) + "]" + msg; out.println(msg); sb.append(msg).append("\n"); } } /** * print an error to printStream * * @param msg the message to print */ public void error(String msg) { print("[ERROR] " + msg, out.err); } /** * print a warning to printStream * * @param msg the message to print */ public void warning(String msg) { print("[WARNING] " + msg, out.warn); } /** * print a info to printStream * * @param msg the message to print */ public void info(String msg) { print("[INFO] " + msg, out.info); } /** * print a debug info to printStream * * @param msg the message to print */ public void debug(String msg) { print("[DEBUG] " + msg, out.debug); } /** * got a syntax exception * * @param msg message * @param lineCol file,line,column info * @throws SyntaxException compiling error */ public void SyntaxException(String msg, LineCol lineCol) throws SyntaxException { if (fastFail) throw new SyntaxException(buildErrInfo(lineCol), msg, lineCol); error(msg + " at " + lineCol); errorList.add(new CompilingError(msg, lineCol, CompilingError.Syntax)); } /** * directly throw the exception if fastFail is true. otherwise call {@link #SyntaxException(String, LineCol)} * * @param msg message * @param lineCol lineCol * @param e exception to throw * @throws SyntaxException compiling error */ public void SyntaxException(String msg, LineCol lineCol, SyntaxException e) throws SyntaxException { if (fastFail) throw e; SyntaxException(msg, lineCol); } /** * got an unexpected end * * @param lineCol file,line,column info * @throws UnexpectedEndException compiling error */ public void UnexpectedEndException(LineCol lineCol) throws UnexpectedEndException { if (fastFail) throw new UnexpectedEndException(buildErrInfo(lineCol), lineCol); final String msg = "unexpected end"; error(msg + " at " + lineCol); errorList.add(new CompilingError(msg, lineCol, CompilingError.UnexpectedEnd)); } /** * occurred an unexpected token * * @param expected expected token structure * @param got got token * @param lineCol file,line,column info * @throws UnexpectedTokenException compiling error */ public void UnexpectedTokenException(String expected, String got, LineCol lineCol) throws UnexpectedTokenException { if (fastFail) throw new UnexpectedTokenException(buildErrInfo(lineCol), expected, got, lineCol); String msg = "expecting " + expected + ", but got " + got; msg = buildErrInfo(lineCol) + msg; error(msg + " at " + lineCol); errorList.add(new CompilingError(msg, lineCol, CompilingError.UnexpectedToken)); } /** * occurred an unexpected token * * @param token unexpected token * @param lineCol file,line,column info * @throws UnexpectedTokenException compiling error */ public void UnexpectedTokenException(String token, LineCol lineCol) throws UnexpectedTokenException { if (fastFail) throw new UnexpectedTokenException(buildErrInfo(lineCol), token, lineCol); String msg = "unexpected token " + token; msg = buildErrInfo(lineCol) + msg; error(msg + " at " + lineCol); errorList.add(new CompilingError(msg, lineCol, CompilingError.UnexpectedToken)); } /** * occurred illegal indentation * * @param expectedIndent the expected indent * @param lineCol file,line,column info * @throws IllegalIndentationException compiling error */ public void IllegalIndentationException(int expectedIndent, LineCol lineCol) throws IllegalIndentationException { if (fastFail) throw new IllegalIndentationException(buildErrInfo(lineCol), expectedIndent, lineCol); String msg = "the indentation should be " + expectedIndent + " spaces"; msg = buildErrInfo(lineCol) + msg; error(msg + " at " + lineCol); errorList.add(new CompilingError(msg, lineCol, CompilingError.Indentation)); } /** * occurred an unexpected new Layer * * @param lineCol file,line,column info * @throws UnexpectedNewLayerException compiling error */ public void UnexpectedNewLayerException(LineCol lineCol) throws UnexpectedNewLayerException { if (fastFail) throw new UnexpectedNewLayerException(buildErrInfo(lineCol), lineCol); String msg = "unexpected new layer"; msg = buildErrInfo(lineCol) + msg; error(msg + " at " + lineCol); errorList.add(new CompilingError(msg, lineCol, CompilingError.UnexpectedNewLayer)); } /** * occurred an unknown token * * @param token the unknown token * @param lineCol file,line,column info * @throws UnknownTokenException compiling error */ public void UnknownTokenException(String token, LineCol lineCol) throws UnknownTokenException { if (fastFail) throw new UnknownTokenException(buildErrInfo(lineCol), token, lineCol); String msg = "unknown token " + token; msg = buildErrInfo(lineCol) + msg; error(msg + " at " + lineCol); errorList.add(new CompilingError(msg, lineCol, CompilingError.UnknownToken)); } public void DuplicateVariableNameException(String name, LineCol lineCol) throws DuplicateVariableNameException { if (fastFail) throw new DuplicateVariableNameException(buildErrInfo(lineCol), name, lineCol); String msg = "duplicate name " + name; msg = buildErrInfo(lineCol) + msg; error(msg + " at " + lineCol); errorList.add(new CompilingError(msg, lineCol, CompilingError.DuplicateVariableName)); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy