/* * ParserCreationException.cs * * This work 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 2 of the License, * or (at your option) any later version. * * This work 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * * As a special exception, the copyright holders of this library give * you permission to link this library with independent modules to * produce an executable, regardless of the license terms of these * independent modules, and to copy and distribute the resulting * executable under terms of your choice, provided that you also meet, * for each linked independent module, the terms and conditions of the * license of that module. An independent module is a module which is * not derived from or based on this library. If you modify this * library, you may extend this exception to your version of the * library, but you are not obligated to do so. If you do not wish to * do so, delete this exception statement from your version. * * Copyright (c) 2003 Per Cederberg. All rights reserved. */ using System; using System.Collections; using System.Text; namespace PerCederberg.Grammatica.Parser { /** * A parser creation exception. This exception is used for signalling * an error in the token or production patterns, making it impossible * to create a working parser or tokenizer. * * @author Per Cederberg, <per at percederberg dot net> * @version 1.0 */ public class ParserCreationException : Exception { /** * The error type enumeration. */ public enum ErrorType { /* * The internal error type is only used to signal an * error that is a result of a bug in the parser or * tokenizer code. */ INTERNAL, /* * The invalid parser error type is used when the parser * as such is invalid. This error is typically caused by * using a parser without any patterns. */ INVALID_PARSER, /* * The invalid token error type is used when a token * pattern is erroneous. This error is typically caused * by an invalid pattern type or an erroneous regular * expression. */ INVALID_TOKEN, /* * The invalid production error type is used when a * production pattern is erroneous. This error is * typically caused by referencing undeclared productions, * or violating some other production pattern constraint. */ INVALID_PRODUCTION, /* * The infinite loop error type is used when an infinite * loop has been detected in the grammar. One of the * productions in the loop will be reported. */ INFINITE_LOOP, /* * The inherent ambiguity error type is used when the set * of production patterns (i.e. the grammar) contains * ambiguities that cannot be resolved. */ INHERENT_AMBIGUITY } /** * The error type. */ private ErrorType type; /** * The token or production pattern name. This variable is only * set for some error types. */ private string name; /** * The additional error information string. This variable is only * set for some error types. */ private string info; /** * The error details list. This variable is only set for some * error types. */ private ArrayList details; /** * Creates a new parser creation exception. * * @param type the parse error type * @param info the additional error information */ public ParserCreationException(ErrorType type, String info) : this(type, null, info) { } /** * Creates a new parser creation exception. * * @param type the parse error type * @param name the token or production pattern name * @param info the additional error information */ public ParserCreationException(ErrorType type, String name, String info) : this(type, name, info, null) { } /** * Creates a new parser creation exception. * * @param type the parse error type * @param name the token or production pattern name * @param info the additional error information * @param details the error details list */ public ParserCreationException(ErrorType type, String name, String info, ArrayList details) { this.type = type; this.name = name; this.info = info; this.details = details; } /** * The message property. This property contains the detailed * exception error message. */ public override string Message { get{ return GetMessage(); } } /** * Returns the error type. * * @return the error type */ public ErrorType GetErrorType() { return type; } /** * Returns the token or production name. * * @return the token or production name */ public string GetName() { return name; } /** * Returns the additional error information. * * @return the additional error information */ public string GetInfo() { return info; } /** * Returns the detailed error information as a string * * @return the detailed error information */ public string GetDetails() { StringBuilder buffer = new StringBuilder(); if (details == null) { return null; } for (int i = 0; i < details.Count; i++) { if (i > 0) { buffer.Append(", "); if (i + 1 == details.Count) { buffer.Append("and "); } } buffer.Append(details[i]); } return buffer.ToString(); } /** * Returns the error message. This message will contain all the * information available. * * @return the error message */ public string GetMessage() { StringBuilder buffer = new StringBuilder(); switch (type) { case ErrorType.INVALID_PARSER: buffer.Append("parser is invalid, as "); buffer.Append(info); break; case ErrorType.INVALID_TOKEN: buffer.Append("token '"); buffer.Append(name); buffer.Append("' is invalid, as "); buffer.Append(info); break; case ErrorType.INVALID_PRODUCTION: buffer.Append("production '"); buffer.Append(name); buffer.Append("' is invalid, as "); buffer.Append(info); break; case ErrorType.INFINITE_LOOP: buffer.Append("infinite loop found in production pattern '"); buffer.Append(name); buffer.Append("'"); break; case ErrorType.INHERENT_AMBIGUITY: buffer.Append("inherent ambiguity in production '"); buffer.Append(name); buffer.Append("'"); if (info != null) { buffer.Append(" "); buffer.Append(info); } if (details != null) { buffer.Append(" starting with "); if (details.Count > 1) { buffer.Append("tokens "); } else { buffer.Append("token "); } buffer.Append(GetDetails()); } break; default: buffer.Append("internal error"); break; } return buffer.ToString(); } } }