Exemplo n.º 1
0
            public void Parse()
            {
                (SourceCode.NotEmpty()).OrThrows("Null Source Code");

                // avoid re-parse
                if (state_ == State.Finished)
                {
                    return;
                }

                while (currentIdx_ < SourceCode.Length)
                {
                    var ch = SourceCode[currentIdx_];
                    switch (state_)
                    {
                    case State.Start:
                        parseStart(ch);
                        break;    // start

                    case State.InComment:
                        if (ch == '\n')
                        {
                            resetState();
                            lineCount_++;
                            currentLineIdx_ = currentIdx_ + 1;
                        }
                        break;

                    case State.InNote:
                        if (ch == '\n')
                        {
                            currentIdx_--;
                            addToken(TokenType.Note);
                            currentIdx_++;
                            resetState();
                        }
                        break;

                    case State.InInteger:
                        if (currentIdx_ != SourceCode.Count() - 1)
                        {
                            var next = SourceCode[currentIdx_ + 1];
                            if (ch == '.' && next.IsDigit())
                            {
                                state_ = State.InFloat;
                            }
                            else if (ch == 'E' || ch == 'e')
                            {
                                state_ = State.InSciNumber;
                            }
                            else if (!ch.IsDigit())
                            {
                                currentIdx_--;
                                addToken(TokenType.Integer);
                                resetState();
                            }
                        }
                        else if (ch.IsDigit())    // last char
                        {
                            addToken(TokenType.Integer);
                            resetState();
                        }
                        else     // last char is not digit
                        {
                            currentIdx_--;
                            addToken(TokenType.Integer);
                            currentIdx_++;
                            if (tryAddSingle(ch))
                            {
                                resetState();
                            }
                            else
                            {
                                addError("Illegal Ending Char[" + ch + "] Following Integer");
                            }
                        }
                        break;

                    case State.InFloat:
                        if (currentIdx_ != SourceCode.Count() - 1)
                        {
                            var next = SourceCode[currentIdx_ + 1];
                            if (next == 'E' || next == 'e')
                            {
                                state_ = State.InSciNumber;
                                currentIdx_++;
                            }
                            if (!ch.IsDigit())
                            {
                                currentIdx_--;
                                addToken(TokenType.Float);
                                resetState();
                            }
                        }
                        else if (ch.IsDigit())     // last char
                        {
                            addToken(TokenType.Float);
                            resetState();
                        }
                        else     // last char is not digit
                        {
                            currentIdx_--;
                            addToken(TokenType.Float);
                            currentIdx_++;
                            if (tryAddSingle(ch))
                            {
                                resetState();
                            }
                            else
                            {
                                addError("Illegal Ending Char[" + ch + "] Following Integer");
                            }
                        }
                        break;

                    case State.InSciNumber:
                        if (ch == '+' || ch == '-')
                        {
                            var prev = SourceCode[currentIdx_ - 1];
                            if (prev != 'E' && prev != 'e')
                            {
                                currentIdx_--;
                                addToken(TokenType.SciNumber);
                                resetState();
                                Console.WriteLine(" cur idx{0}", currentIdx_);
                            }
                        }
                        else if (!ch.IsDigit())
                        {
                            currentIdx_--;
                            addToken(TokenType.SciNumber);
                            resetState();
                        }
                        break;

                    case State.InIdentifier:
                        if (!ch.IsValidTailingIdCh())
                        {
                            currentIdx_--;
                            addToken(TokenType.Identifier);
                            resetState();
                        }

                        break;

                    case State.InString:
                    {
                        if (ch == '\"')
                        {
                            currentIdx_--;         // skip "
                            addToken(TokenType.String);
                            currentIdx_++;
                            resetState();
                            break;
                        }
                        else if (ch == '\\')
                        {
                            state_ = State.InEscapingString;
                            Console.WriteLine("escape");
                        }
                        else if (ch == '\n')
                        {
                            addError("Multi-line string");
                        }
                    }
                    break;

                    case State.InEscapingString:    // next char after
                        if (ch == '\n')
                        {
                            addError("Multi-line string");
                            resetState();
                        }
                        else
                        {
                            state_ = State.InString;
                        }

                        break;
                    } // while: foreach ch
                    currentIdx_++;
                }

                currentIdx_--;
                switch (state_)
                {
                case State.InInteger:
                    addToken(TokenType.Integer);
                    break;

                case State.InFloat:
                    addToken(TokenType.Float);
                    break;

                case State.InSciNumber:
                    addToken(TokenType.SciNumber);
                    break;

                case State.InIdentifier:
                    addToken(TokenType.Identifier);
                    break;

                case State.InString:
                case State.InEscapingString:
                    addError("Multi-Line String!");
                    break;
                }
                // ok we are done
                // mark as finished to prevent reparse
                // to re do parsing, see Reparse();
                state_ = State.Finished;
            }