From 5519f68050c6f221c5a358569c9b5759bf69f75c Mon Sep 17 00:00:00 2001 From: Lotes Date: Mon, 16 Apr 2018 09:41:52 +0200 Subject: [PATCH] unify exceptions --- .../Automaton/AutomatonConstructionException.cs | 15 +++++++++++++++ Lexer/Automaton/Impl/AutomatonBuilder.cs | 4 ++-- Lexer/LexerExecutionException.cs | 12 ++++++++++++ Lexer/LexerExtensions.cs | 16 +++++++++++++++- Lexer/RegexParser.cs | 12 ++++++------ Lexer/RegexParserException.cs | 17 +++++++++++++++++ Main/Program.cs | 5 +++-- 7 files changed, 70 insertions(+), 11 deletions(-) create mode 100644 Lexer/Automaton/AutomatonConstructionException.cs create mode 100644 Lexer/LexerExecutionException.cs create mode 100644 Lexer/RegexParserException.cs diff --git a/Lexer/Automaton/AutomatonConstructionException.cs b/Lexer/Automaton/AutomatonConstructionException.cs new file mode 100644 index 0000000..21a7bb4 --- /dev/null +++ b/Lexer/Automaton/AutomatonConstructionException.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Lexer.Automaton +{ + public class AutomatonConstructionException : Exception + { + public AutomatonConstructionException(string message) : base(message) + { + } + } +} diff --git a/Lexer/Automaton/Impl/AutomatonBuilder.cs b/Lexer/Automaton/Impl/AutomatonBuilder.cs index 044aa2a..2e518c2 100644 --- a/Lexer/Automaton/Impl/AutomatonBuilder.cs +++ b/Lexer/Automaton/Impl/AutomatonBuilder.cs @@ -39,9 +39,9 @@ public void AcceptState(int state) public IAutomaton Build() { if(StateCounter == 0) - throw new InvalidOperationException("No states defined!"); + throw new AutomatonConstructionException("No states defined!"); if(startState == -1) - throw new InvalidOperationException("No start defined!"); + throw new AutomatonConstructionException("No start defined!"); return new Automaton(StateCounter, startState, acceptingStates, transitions.ToDictionary(kv => kv.Key, kv => (ITransitionTargets)kv.Value)); } diff --git a/Lexer/LexerExecutionException.cs b/Lexer/LexerExecutionException.cs new file mode 100644 index 0000000..4bca494 --- /dev/null +++ b/Lexer/LexerExecutionException.cs @@ -0,0 +1,12 @@ +using System; +using System.Runtime.Serialization; + +namespace Lexer +{ + public class LexerExecutionException : Exception + { + public LexerExecutionException(string message) : base(message) + { + } + } +} \ No newline at end of file diff --git a/Lexer/LexerExtensions.cs b/Lexer/LexerExtensions.cs index 7e16271..55a6acb 100644 --- a/Lexer/LexerExtensions.cs +++ b/Lexer/LexerExtensions.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Text; namespace Lexer { @@ -15,7 +16,20 @@ public static IEnumerable Read(this ILexer lexer, string input) index += token.Value.Length; } if (index < input.Length) - throw new InvalidOperationException("EOF not reached!"); + throw new LexerExecutionException("EOF not reached!"); + } + + public static string Times(this string str, int factor) + { + if (factor < 0) + throw new ArgumentException("Factor must be non-negative!", nameof(factor)); + var builder = new StringBuilder(str.Length*factor); + while(factor > 0) + { + builder.Append(str); + factor--; + } + return builder.ToString(); } } } diff --git a/Lexer/RegexParser.cs b/Lexer/RegexParser.cs index 153346c..bd3549c 100644 --- a/Lexer/RegexParser.cs +++ b/Lexer/RegexParser.cs @@ -255,7 +255,7 @@ private IAutomaton PrimaryExpression() private int Number() { if(Lookahead < '0' || Lookahead > '9') - throw new InvalidOperationException("Digit expected, but '"+Lookahead+"' found!"); + throw new RegexParserException(index, "Digit expected, but '"+Lookahead+"' found!"); var num = ""; while (Lookahead >= '0' && Lookahead <= '9') { @@ -290,7 +290,7 @@ private bool MayConsume(string str) private void Consumes(char c) { if(Lookahead != c) - throw new InvalidOperationException("'"+c+"' expected, but '"+Lookahead+"' found."); + throw new RegexParserException(index, "'"+c+"' expected, but '"+Lookahead+"' found."); index++; } @@ -330,7 +330,7 @@ private ICharSet CharRange() { var last = Char(); if (last.Length != 1) - throw new InvalidOperationException("Invalid upper bound for character range!"); + throw new RegexParserException(index, "Invalid upper bound for character range!"); result = new CharSet(new CharRange(first.First().First(), last.First().First())); } else @@ -348,7 +348,7 @@ private ICharSet Char() switch(asciiTable[Lookahead]) { case CharType.Invalid: - throw new InvalidOperationException("Invalid character!"); + throw new RegexParserException(index, "Invalid character: "+Lookahead+"!"); case CharType.Literal: var first = Lookahead; index++; @@ -382,11 +382,11 @@ private ICharSet Char() } } if (!found) - throw new InvalidOperationException("Invalid escape character: " + Lookahead); + throw new RegexParserException(index, "Invalid escape character: " + Lookahead); } } else - throw new InvalidOperationException("Invalid character!"); + throw new RegexParserException(index, "Invalid character: "+Lookahead+"!"); break; } } diff --git a/Lexer/RegexParserException.cs b/Lexer/RegexParserException.cs new file mode 100644 index 0000000..754bdc4 --- /dev/null +++ b/Lexer/RegexParserException.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Lexer +{ + public class RegexParserException : Exception + { + public RegexParserException(int index, string message) : base(message) + { + Index = index; + } + public int Index { get; } + } +} diff --git a/Main/Program.cs b/Main/Program.cs index afd2434..747eebd 100644 --- a/Main/Program.cs +++ b/Main/Program.cs @@ -21,11 +21,12 @@ public static void Main(string[] args) var automaton = parser.Parse(input); automaton.Print(); } - catch (Exception e) + catch (RegexParserException e) { + Console.WriteLine(" "+(" ".Times(e.Index))+"^"); Console.Error.WriteLine(e.Message); - Console.Error.WriteLine(e.StackTrace); } + Console.WriteLine(); } while (true); } }