public override string ToString() { StringBuilder builder = new StringBuilder(); builder.AppendFormat("[Parser Location={0} CurrentStateLength={1}", position, currentStateLength); builder.AppendLine(); builder.Append(' ', 2); builder.AppendLine("Stack="); XObject rootOb = null; foreach (XObject ob in nodes) { rootOb = ob; builder.Append(' ', 4); builder.Append(ob.ToString()); builder.AppendLine(); } builder.Append(' ', 2); builder.AppendLine("States="); XmlParserState s = currentState; while (s != null) { builder.Append(' ', 4); builder.Append(s.ToString()); builder.AppendLine(); s = s.Parent; } if (buildTree && rootOb != null) { builder.Append(' ', 2); builder.AppendLine("Tree="); rootOb.BuildTreeString(builder, 3); } if (buildTree && errors.Count > 0) { builder.Append(' ', 2); builder.AppendLine("Errors="); foreach (Error err in errors) { builder.Append(' ', 4); builder.AppendFormat("[{0}@{1}:{2}, {3}]\n", err.ErrorType, err.Region.Begin.Line, err.Region.Begin.Column, err.Message); } } builder.AppendLine("]"); return(builder.ToString()); }
public override string ToString() { StringBuilder builder = new StringBuilder(); builder.AppendFormat("[Parser Location={0} CurrentStateLength={1}", Position, CurrentStateLength); builder.AppendLine(); builder.Append(' ', 2); builder.AppendLine("Stack="); XObject rootOb = null; foreach (XObject ob in Nodes) { rootOb = ob; builder.Append(' ', 4); builder.Append(ob.ToString()); builder.AppendLine(); } builder.Append(' ', 2); builder.AppendLine("States="); XmlParserState s = CurrentState; while (s != null) { builder.Append(' ', 4); builder.Append(s.ToString()); builder.AppendLine(); s = s.Parent; } if (BuildTree && rootOb != null) { builder.Append(' ', 2); builder.AppendLine("Tree="); rootOb.BuildTreeString(builder, 3); } if (BuildTree && Diagnostics.Count > 0) { builder.Append(' ', 2); builder.AppendLine("Errors="); foreach (XmlDiagnosticInfo err in Diagnostics) { builder.Append(' ', 4); builder.AppendLine($"[{err.Severity}@{err.Span}: {err.Message}]"); } } builder.AppendLine("]"); return(builder.ToString()); }
public void Push(char c) { try { //FIXME: position/location should be at current char, not after it position++; if (c == '\n') { previousLineEnd = new DocumentLocation(location.Line, location.Column + 1); location = new DocumentLocation(location.Line + 1, 1); } else { location = new DocumentLocation(location.Line, location.Column + 1); } for (int loopLimit = 0; loopLimit < 10; loopLimit++) { currentStateLength++; string rollback = null; if (currentState == null) { return; } XmlParserState nextState = currentState.PushChar(c, this, ref rollback); // no state change if (nextState == currentState || nextState == null) { return; } // state changed; reset stuff previousState = currentState; currentState = nextState; stateTag = 0; currentStateLength = 0; if (keywordBuilder.Length < 50) { keywordBuilder.Length = 0; } else { keywordBuilder = new StringBuilder(); } // only loop if the same char should be run through the new state if (rollback == null) { return; } //simple rollback, just run same char through again if (rollback.Length == 0) { continue; } //"complex" rollbacks require actually skipping backwards. //Note the previous state is invalid for this operation. //rollback position and location so they're valid position -= (rollback.Length + 1); location = new DocumentLocation(location.Line, location.Column - (rollback.Length + 1)); if (location.Column < 0) { throw new InvalidOperationException("Can't roll back across line boundary"); } foreach (char rollChar in rollback) { Push(rollChar); } //restore position and location position++; location = new DocumentLocation(location.Line, location.Column + 1); } throw new InvalidOperationException("Too many state changes for char '" + c + "'. Current state is " + currentState.ToString() + "."); } catch (Exception ex) { //attach parser state to exceptions throw new Exception(ToString(), ex); } }