Exemplo n.º 1
0
        public void Push(char c)
        {
            try {
                //track line, column
                if (c == '\n')
                {
                    location.Line++;
                    location.Column = 1;
                }
                else
                {
                    location.Column++;
                }

                position++;
                for (int loopLimit = 0; loopLimit < 10; loopLimit++)
                {
                    currentStateLength++;
                    string rollback  = null;
                    State  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;
                    }

                    //"complex" rollbacks require actually skipping backwards.
                    //Note the previous state is invalid for this operation.
                    else if (rollback.Length > 0)
                    {
                        position -= (rollback.Length + 1);
                        foreach (char rollChar in rollback)
                        {
                            Push(rollChar);
                        }
                        position++;
                    }
                }
                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);
            }
        }
Exemplo n.º 2
0
        public void Push(char c)
        {
            try {
                //FIXME: position/location should be at current char, not after it
                position++;
                if (c == '\n')
                {
                    previousLineEnd = new TextLocation(location.Line, location.Column + 1);
                    location        = new TextLocation(location.Line + 1, 1);
                }
                else
                {
                    location = new TextLocation(location.Line, location.Column + 1);
                }

                for (int loopLimit = 0; loopLimit < 10; loopLimit++)
                {
                    currentStateLength++;
                    string rollback = null;
                    if (currentState == null)
                    {
                        return;
                    }
                    State 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 TextLocation(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 TextLocation(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);
            }
        }