218 lines
6.5 KiB
C#
218 lines
6.5 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Text;
|
|
|
|
namespace Flee.Parsing
|
|
{
|
|
/**
|
|
* 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.
|
|
*/
|
|
internal 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
|
|
|
|
|
|
|
|
}
|
|
|
|
private readonly ErrorType _type;
|
|
private readonly string _name;
|
|
private readonly string _info;
|
|
private readonly ArrayList _details;
|
|
|
|
public ParserCreationException(ErrorType type,
|
|
String info)
|
|
: this(type, null, info)
|
|
{
|
|
}
|
|
|
|
public ParserCreationException(ErrorType type,
|
|
String name,
|
|
String info)
|
|
: this(type, name, info, null)
|
|
{
|
|
}
|
|
|
|
public ParserCreationException(ErrorType type,
|
|
String name,
|
|
String info,
|
|
ArrayList details)
|
|
{
|
|
|
|
this._type = type;
|
|
this._name = name;
|
|
this._info = info;
|
|
this._details = details;
|
|
}
|
|
|
|
public ErrorType Type => _type;
|
|
|
|
public ErrorType GetErrorType()
|
|
{
|
|
return Type;
|
|
}
|
|
|
|
public string Name => _name;
|
|
|
|
public string GetName()
|
|
{
|
|
return Name;
|
|
}
|
|
|
|
public string Info => _info;
|
|
|
|
public string GetInfo()
|
|
{
|
|
return Info;
|
|
}
|
|
|
|
public string Details
|
|
{
|
|
get
|
|
{
|
|
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();
|
|
}
|
|
}
|
|
|
|
public string GetDetails()
|
|
{
|
|
return Details;
|
|
}
|
|
|
|
public override string Message
|
|
{
|
|
get
|
|
{
|
|
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(Details);
|
|
}
|
|
break;
|
|
default:
|
|
buffer.Append("internal error");
|
|
break;
|
|
}
|
|
return buffer.ToString();
|
|
}
|
|
}
|
|
|
|
public string GetMessage()
|
|
{
|
|
return Message;
|
|
}
|
|
}
|
|
}
|