Ejemplo n.º 1
0
        private static string ConstructErrorMessage(ScannerErrorState error)
        {
            string errMsg = string.Empty;

            switch (error)
            {
            case ScannerErrorState.CannotHaveBlankExponent:
                errMsg = "Cannot have blank exponent";
                break;

            case ScannerErrorState.CannotHaveBlankMantissa:
                errMsg = "Cannot have blank mantissa";
                break;

            case ScannerErrorState.InternalErrorCouldNotResolveTokenType:
                errMsg = "Internal error could not resolve token type";
                break;

            case ScannerErrorState.InternalErrorCouldNotTransitionState:
                errMsg = "Internal error could not transition scanner state";
                break;

            case ScannerErrorState.UnexpectedCharacter:
                errMsg = "Unexpected character";
                break;

            case ScannerErrorState.UnexpectedSymbol:
                errMsg = "Unexpected symbol";
                break;
            }
            return(errMsg);
        }
Ejemplo n.º 2
0
 public ScannerException(ScannerErrorState error, int line, int startPos, int endPos)
     : base(line, startPos, endPos, ConstructErrorMessage(error))
 {
 }
Ejemplo n.º 3
0
        public Token GetNextToken()
        {
            StringBuilder     tokenValue   = new StringBuilder();
            ScannerState      scannerState = ScannerState.Start;
            ScannerErrorState scannerError = ScannerErrorState.None;
            bool finishedScan = false;

            _startPosition = _pos;
            while (!finishedScan)
            {
                bool ignoreCharacter = false;
                char nextChar        = GetNextRelevantChar();
                #region DFA Implementation
                switch (scannerState)
                {
                case ScannerState.Start:
                    if (char.IsWhiteSpace(nextChar))
                    {
                        scannerState    = ScannerState.Start;
                        ignoreCharacter = true;
                    }
                    else if (char.IsLetter(nextChar))
                    {
                        scannerState = ScannerState.Identifier;
                    }
                    else if (char.IsDigit(nextChar))
                    {
                        scannerState = ScannerState.Number;
                    }
                    else if (IsSymbol(nextChar))
                    {
                        #region Scan symbol
                        switch (nextChar)
                        {
                        case '^':
                            scannerState = ScannerState.Power;
                            finishedScan = true;
                            break;

                        case '+':
                            scannerState = ScannerState.Plus;
                            finishedScan = true;
                            break;

                        case '-':
                            scannerState = ScannerState.Minus;
                            finishedScan = true;
                            break;

                        case '*':
                            scannerState = ScannerState.Multiplication;
                            finishedScan = true;
                            break;

                        case '/':
                            scannerState = ScannerState.Division;
                            finishedScan = true;
                            break;

                        case '[':
                            scannerState = ScannerState.OpenBracket;
                            finishedScan = true;
                            break;

                        case ']':
                            scannerState = ScannerState.CloseBracket;
                            finishedScan = true;
                            break;

                        case '(':
                            scannerState = ScannerState.OpenParenthesis;
                            finishedScan = true;
                            break;

                        case ')':
                            scannerState = ScannerState.CloseParenthesis;
                            finishedScan = true;
                            break;

                        case '{':
                            scannerState = ScannerState.BeginBracket;
                            finishedScan = true;
                            break;

                        case '}':
                            scannerState = ScannerState.EndBracket;
                            finishedScan = true;
                            break;

                        case '=':
                            scannerState = ScannerState.Assign;
                            break;

                        case '&':
                            scannerState = ScannerState.AlmostAnd;
                            break;

                        case '|':
                            scannerState = ScannerState.AlmostOr;
                            break;

                        case ',':
                            scannerState = ScannerState.Comma;
                            finishedScan = true;
                            break;

                        case '.':
                            scannerState = ScannerState.Dot;
                            finishedScan = true;
                            break;

                        case ';':
                            scannerState = ScannerState.SemiColon;
                            finishedScan = true;
                            break;

                        case '!':
                            scannerState = ScannerState.Not;
                            break;

                        case '<':
                            scannerState = ScannerState.LessThan;
                            break;

                        case '>':
                            scannerState = ScannerState.GreaterThan;
                            break;

                        case '%':
                            scannerState = ScannerState.Modulus;
                            finishedScan = true;
                            break;

                        default:
                            finishedScan = true;
                            scannerError = ScannerErrorState.UnexpectedSymbol;
                            RestoreChar(nextChar);
                            break;
                        }
                        #endregion
                    }
                    else if (nextChar == char.MaxValue)
                    {
                        scannerState = ScannerState.EndOfCode;
                        finishedScan = true;
                    }
                    else
                    {
                        finishedScan = true;
                        scannerError = ScannerErrorState.UnexpectedCharacter;
                        RestoreChar(nextChar);
                        ignoreCharacter = true;
                    }
                    break;

                case ScannerState.Identifier:
                    if (char.IsLetterOrDigit(nextChar))
                    {
                        scannerState = ScannerState.Identifier;
                    }
                    else
                    {
                        finishedScan = true;
                        RestoreChar(nextChar);
                        ignoreCharacter = true;
                    }
                    break;

                case ScannerState.Number:
                    if (char.IsDigit(nextChar))
                    {
                        scannerState = ScannerState.Number;
                    }
                    else if (nextChar == '.')
                    {
                        scannerState = ScannerState.AlmostDecimal;
                    }
                    else if (nextChar == 'E')
                    {
                        scannerState = ScannerState.NumberWithExponent;
                    }
                    else
                    {
                        finishedScan = true;
                        RestoreChar(nextChar);
                        ignoreCharacter = true;
                    }
                    break;

                case ScannerState.AlmostDecimal:
                    if (char.IsDigit(nextChar))
                    {
                        scannerState = ScannerState.Decimal;
                    }
                    else
                    {
                        finishedScan = true;
                        scannerError = ScannerErrorState.CannotHaveBlankMantissa;
                        RestoreChar(nextChar);
                        ignoreCharacter = true;
                    }
                    break;

                case ScannerState.Decimal:
                    if (char.IsDigit(nextChar))
                    {
                        scannerState = ScannerState.Decimal;
                    }
                    else if (nextChar == 'E')
                    {
                        scannerState = ScannerState.NumberWithExponent;
                    }
                    else
                    {
                        finishedScan = true;
                        RestoreChar(nextChar);
                        ignoreCharacter = true;
                    }
                    break;

                case ScannerState.NumberWithExponent:
                    if (char.IsDigit(nextChar))
                    {
                        scannerState = ScannerState.NumberWithUnsignedExponent;
                    }
                    else if (nextChar == '+')
                    {
                        scannerState = ScannerState.NumberWithSignedExponent;
                    }
                    else if (nextChar == '-')
                    {
                        scannerState = ScannerState.NumberWithSignedExponent;
                    }
                    else
                    {
                        finishedScan = true;
                        scannerError = ScannerErrorState.CannotHaveBlankExponent;
                        RestoreChar(nextChar);
                        ignoreCharacter = true;
                    }
                    break;

                case ScannerState.NumberWithSignedExponent:
                    if (char.IsDigit(nextChar))
                    {
                        scannerState = ScannerState.NumberWithSignedExponent;
                    }
                    else
                    {
                        finishedScan = true;
                        RestoreChar(nextChar);
                        ignoreCharacter = true;
                    }
                    break;

                case ScannerState.NumberWithUnsignedExponent:
                    if (char.IsDigit(nextChar))
                    {
                        scannerState = ScannerState.NumberWithUnsignedExponent;
                    }
                    else
                    {
                        finishedScan = true;
                        RestoreChar(nextChar);
                        ignoreCharacter = true;
                    }
                    break;

                case ScannerState.Assign:
                    if (nextChar == '=')
                    {
                        scannerState = ScannerState.Equality;
                        finishedScan = true;
                    }
                    else
                    {
                        finishedScan = true;
                        RestoreChar(nextChar);
                        ignoreCharacter = true;
                    }
                    break;

                case ScannerState.Not:
                    if (nextChar == '=')
                    {
                        scannerState = ScannerState.Inequality;
                        finishedScan = true;
                    }
                    else
                    {
                        finishedScan = true;
                        RestoreChar(nextChar);
                        ignoreCharacter = true;
                    }
                    break;

                case ScannerState.LessThan:
                    if (nextChar == '=')
                    {
                        scannerState = ScannerState.LessThanEqualTo;
                        finishedScan = true;
                    }
                    else
                    {
                        finishedScan = true;
                        RestoreChar(nextChar);
                        ignoreCharacter = true;
                    }
                    break;

                case ScannerState.GreaterThan:
                    if (nextChar == '=')
                    {
                        scannerState = ScannerState.GreaterThanEqualTo;
                        finishedScan = true;
                    }
                    else
                    {
                        finishedScan = true;
                        RestoreChar(nextChar);
                        ignoreCharacter = true;
                    }
                    break;

                case ScannerState.AlmostOr:
                    if (nextChar == '|')
                    {
                        scannerState = ScannerState.Or;
                        finishedScan = true;
                    }
                    else
                    {
                        finishedScan = true;
                        RestoreChar(nextChar);
                        ignoreCharacter = true;
                    }
                    break;

                case ScannerState.AlmostAnd:
                    if (nextChar == '&')
                    {
                        scannerState = ScannerState.And;
                        finishedScan = true;
                    }
                    else
                    {
                        finishedScan = true;
                        RestoreChar(nextChar);
                        ignoreCharacter = true;
                    }
                    break;

                default:
                    scannerError = ScannerErrorState.InternalErrorCouldNotTransitionState;
                    break;
                }
                #endregion
                if (scannerError != ScannerErrorState.None)
                {
                    RestoreChar(nextChar);
                    ignoreCharacter = true;
                    throw new ScannerException(
                              scannerError,
                              _line,
                              _startPosition,
                              _pos
                              );
                }
                else
                {
                    if (!ignoreCharacter)
                    {
                        tokenValue.Append(nextChar);
                    }
                }
            }

            string tokenString = tokenValue.ToString();
            Token  token       = new Token(
                ResolveTokenType(scannerState, tokenString),
                tokenString,
                _line,
                _startPosition,
                !_haveRestoredChar ? _pos : _pos - 1
                );
            return(token);
        }