Пример #1
0
 // Change the scope state
 // Report an error if the token is being used in the wrong place (such as a declaration
 // after an executable statement).
 bool ChangeState(SimpleToken token)
 {
     BlockState newState = TokenToState(token);
     if (newState != BlockState.SUBFUNC && newState < _state) {
         _messages.Error(MessageCode.TOKENNOTPERMITTED, String.Format("{0} not permitted here", token));
         return false;
     }
     if (newState != BlockState.UNORDERED) {
         _state = newState;
     }
     if (newState == BlockState.STATEMENT) {
         if (_currentProcedure == null) {
             _ls.BackToken();
             _ptree.Add(KCreateProgram(_entryPointName));
             return false;
         }
     }
     return true;
 }
Пример #2
0
        /// Returns the block state to which the specified token belongs. For example,
        /// IMPLICIT must precede any declaration which must precede any executable
        /// statement in the same program group.
        BlockState TokenToState(SimpleToken token)
        {
            BlockState state = BlockState.NONE;
            switch (token.ID) {
                case TokenID.KPROGRAM:
                    state = BlockState.PROGRAM;
                    break;

                case TokenID.KIMPLICITNONE:
                    state = BlockState.IMPLICITNONE;
                    break;

                case TokenID.KIMPLICIT:
                    state = BlockState.IMPLICIT;
                    break;

                case TokenID.KFORMAT:
                case TokenID.KINCLUDE:
                    // May appear anywhere.
                    state = BlockState.UNORDERED;
                    break;

                case TokenID.KINTEGER:
                case TokenID.KREAL:
                case TokenID.KCHARACTER:
                case TokenID.KDIMENSION:
                case TokenID.KLOGICAL:
                case TokenID.KDPRECISION:
                case TokenID.KCOMPLEX:
                case TokenID.KCOMMON:
                case TokenID.KPARAMETER:
                case TokenID.KINTRINSIC:
                case TokenID.KEXTERNAL:
                case TokenID.KEQUIVALENCE:
                case TokenID.KSAVE:
                    state = BlockState.SPECIFICATION;
                    break;

                case TokenID.IDENT:
                case TokenID.KSTMTFUNC:
                case TokenID.KCALL:
                case TokenID.KCLOSE:
                case TokenID.KCONTINUE:
                case TokenID.KDO:
                case TokenID.KEND:
                case TokenID.KGO:
                case TokenID.KGOTO:
                case TokenID.KIF:
                case TokenID.KINQUIRE:
                case TokenID.KOPEN:
                case TokenID.KPAUSE:
                case TokenID.KPRINT:
                case TokenID.KREAD:
                case TokenID.KRETURN:
                case TokenID.KSTOP:
                case TokenID.KWRITE:
                case TokenID.KENDFILE:
                case TokenID.KREWIND:
                case TokenID.KBACKSPACE:
                case TokenID.KASSIGN:
                case TokenID.KDATA:
                case TokenID.KENTRY:
                    state = BlockState.STATEMENT;
                    break;

                case TokenID.KSUBROUTINE:
                case TokenID.KFUNCTION:
                case TokenID.KBLOCKDATA:
                    state = BlockState.SUBFUNC;
                    break;
            }
            return state;
        }
Пример #3
0
 /// <summary>
 /// Get the next keyword from the source file, or TokenID.IDENT if the keyword
 /// isn't recognised but looks like a valid identifier.
 /// 
 /// This function also handles merging keywords that are represented by
 /// multiple tokens into a single keyword token. Thus:
 /// 
 ///   GO TO -> GOTO
 ///   DOUBLE PRECISION -> DOUBLEPRECISION
 ///   (etc...)
 ///   
 /// </summary>
 /// <returns>A SimpleToken representing the keyword found</returns>
 public SimpleToken GetKeyword()
 {
     SimpleToken token = GetToken();
     if (!(token is IdentifierToken)) {
         return token;
     }
     TokenID id = token.KeywordID;
     if (id == TokenID.IDENT) {
         return token;
     }
     if (id == TokenID.KGO) {
         // BUGBUG: Hack until full tokeniser implemented.
         LocalExpectToken(TokenID.KTO);
         id = TokenID.KGOTO;
         _tokens[_tindex - 2] = new SimpleToken(id);
         _tokens.RemoveAt(--_tindex);
     } else if (id == TokenID.KEND && PeekKeyword() == TokenID.KIF) {
         // BUGBUG: Hack until full tokeniser implemented.
         LocalExpectToken(TokenID.KIF);
         id = TokenID.KENDIF;
         _tokens[_tindex - 2] = new SimpleToken(id);
         _tokens.RemoveAt(--_tindex);
     } else if (id == TokenID.KELSE && PeekKeyword() == TokenID.KIF) {
         // BUGBUG: Hack until full tokeniser implemented.
         LocalExpectToken(TokenID.KIF);
         id = TokenID.KELSEIF;
         _tokens[_tindex - 2] = new SimpleToken(id);
         _tokens.RemoveAt(--_tindex);
     } else if (id == TokenID.KDOUBLE) {
         // BUGBUG: Hack until full tokeniser implemented.
         LocalExpectToken(TokenID.KPRECISION);
         id = TokenID.KDPRECISION;
         _tokens[_tindex - 2] = new SimpleToken(id);
         _tokens.RemoveAt(--_tindex);
     } else if (id == TokenID.KBLOCK) {
         // BUGBUG: Hack until full tokeniser implemented.
         LocalExpectToken(TokenID.KDATA);
         id = TokenID.KBLOCKDATA;
         _tokens[_tindex - 2] = new SimpleToken(id);
         _tokens.RemoveAt(--_tindex);
     } else if (id == TokenID.KIMPLICIT && PeekKeyword() == TokenID.KNONE) {
         GetToken();
         id = TokenID.KIMPLICITNONE;
     }
     return new SimpleToken(id);
 }
Пример #4
0
        // Parse one statement.
        // Note that this may be called as part of a logical or block IF statement. Non-executable statements
        // won't be allowed in this context but, happily, if we're parsing an IF statement then we're already
        // in STATEMENT state.
        ParseNode Statement(SimpleToken token)
        {
            // First make sure this statement is allowed here.
            if (ChangeState(token)) {
                switch (token.ID) {
                    case TokenID.KASSIGN:           return KAssign();
                    case TokenID.KBACKSPACE:        return KBackspace();
                    case TokenID.KBLOCKDATA:        return KBlockData();
                    case TokenID.KCALL:             return KCall();
                    case TokenID.KCHARACTER:        return KCharacter();
                    case TokenID.KCLOSE:            return KClose();
                    case TokenID.KCOMMON:           return KCommon();
                    case TokenID.KCOMPLEX:          return KComplex();
                    case TokenID.KCONTINUE:         return KContinue();
                    case TokenID.KDATA:             return KData();
                    case TokenID.KDIMENSION:        return KDimension();
                    case TokenID.KDO:               return KDo();
                    case TokenID.KDPRECISION:       return KDouble();
                    case TokenID.KENDFILE:          return KEndFile();
                    case TokenID.KENTRY:            return KEntry();
                    case TokenID.KEQUIVALENCE:      return KEquivalence();
                    case TokenID.KEXTERNAL:         return KExternal();
                    case TokenID.KFORMAT:           return KFormat();
                    case TokenID.KFUNCTION:         return KFunction();
                    case TokenID.KGOTO:             return KGoto();
                    case TokenID.KIF:               return KIf();
                    case TokenID.KIMPLICIT:         return KImplicit();
                    case TokenID.KIMPLICITNONE:     return KImplicitNone();
                    case TokenID.KINCLUDE:          return KInclude();
                    case TokenID.KINQUIRE:          return KInquire();
                    case TokenID.KINTEGER:          return KInteger();
                    case TokenID.KINTRINSIC:        return KIntrinsic();
                    case TokenID.KLOGICAL:          return KLogical();
                    case TokenID.KOPEN:             return KOpen();
                    case TokenID.KPAUSE:            return KPause();
                    case TokenID.KPARAMETER:        return KParameter();
                    case TokenID.KPRINT:            return KPrint();
                    case TokenID.KPROGRAM:          return KProgram();
                    case TokenID.KREAD:             return KRead();
                    case TokenID.KREAL:             return KReal();
                    case TokenID.KRETURN:           return KReturn();
                    case TokenID.KREWIND:           return KRewind();
                    case TokenID.KSAVE:             return KSave();
                    case TokenID.KSTOP:             return KStop();
                    case TokenID.KSUBROUTINE:       return KSubroutine();
                    case TokenID.KWRITE:            return KWrite();
                    case TokenID.IDENT:             return KAssignment();
                }

                // Anything else is unparseable, so assume the rest of the line is
                // too and skip it.
                _messages.Error(MessageCode.UNEXPECTEDTOKEN, _ls.LineNumber, String.Format("Unexpected {0} found in statement", token));
                SkipToEndOfLine();
            }
            return null;
        }
Пример #5
0
        // Parse an identifier parse node from the specified token.
        IdentifierParseNode ParseIdentifierParseNode()
        {
            IdentifierParseNode node = new IdentifierParseNode(null);
            Collection<ParseNode> indices = null;
            SimpleToken token = _ls.GetToken();
            bool isSubstring = false;

            while (token.ID == TokenID.LPAREN) {
                if (indices == null) {
                    indices = new Collection<ParseNode>();
                }
                if (_ls.PeekToken().ID != TokenID.RPAREN) {
                    do {
                        ParseNode item = null;

                        if (_ls.PeekToken().ID == TokenID.RPAREN) {
                            SkipToken(TokenID.RPAREN);
                            break;
                        }
                        if (_ls.PeekToken().ID != TokenID.COLON) {
                            item = Expression();
                        }
                        token = _ls.GetToken();
                        if (token.ID == TokenID.COLON) {
                            isSubstring = true;
                            if (item == null) {
                                item = new NumberParseNode(1);
                            }
                            node.SubstringStart = item;
                            token = new SimpleToken(TokenID.COMMA);
                            continue;
                        }
                        if (isSubstring) {
                            node.SubstringEnd = item;
                            break;
                        }
                        indices.Add(item);
                    } while (token.ID == TokenID.COMMA);
                    _ls.BackToken();
                }
                ExpectToken(TokenID.RPAREN);
                token = _ls.GetToken();
            }

            node.Indexes = indices;
            _ls.BackToken();
            return node;
        }