コード例 #1
0
ファイル: Parser.cs プロジェクト: 2hanson/cminus
 /// <summary>
 /// get next token and check if its type is expected..
 /// </summary>
 /// <param name="type"></param>
 /// <returns></returns>
 bool Match(int type)
 {
     bool flag;
     currentToken = GetNextToken();
     flag = (currentToken.TokenTypes == type);
     //--currentTokenIndex;
     return flag;
 }
コード例 #2
0
ファイル: Parser.cs プロジェクト: 2hanson/cminus
 bool Match(char ch)
 {
     int type = Convert.ToInt32(ch);
     bool flag;
     currentToken = GetNextToken();
     flag = (currentToken.TokenTypes == type);
     //--currentTokenIndex;
     return flag;
 }
コード例 #3
0
ファイル: Parser.cs プロジェクト: 2hanson/cminus
        /// <summary>
        ///  4. var-declaration → type-specifier ID(,...); | type-specifier ID [ NUM ](,...);
        ///  5. type-specifier → int | void
        /// </summary>
        /// <returns></returns>
        TreeNode VarDeclaration()
        {
            // now, cToken.str == ";", "," or "["
            Word iToken = idNameToken as Word;
            TreeNode temp = new TreeNode(NodeKind.varK, (TokenType)typeToken.TokenTypes, iToken.Lexeme, currentToken.LineNumber, scope);
            if (CheckCurrentToken('[')) {
                currentToken = GetNextToken();//must NUMber
                if (!CheckCurrentToken(TokenType.NUMBER)) {
                    ErrorRecord(ParseErrorType.MissingArraySize);
                    ConsumeUntil(";", "}");
                    //error
                    /*scan->add_err();
                    sprintf(msg_temp,
                        "Syntax error: missing array size in declaration of array %s[]",
                        iToken.str.c_str());
                    outputMsg(scan->lineno(), msg_temp);
                    delete temp;
                    consumeUntil(SEMI, RBRACE);	// error recovery in global declaration

                    return NULL;*/
                    return null;
                }
                temp.IsArray = true;
                Number num = currentToken as Number;
                temp.ArraySize = Convert.ToInt32(num.Lexeme);
                if (!Match(Convert.ToInt32(']'))) {
                    ErrorRecord(ParseErrorType.MissingRBracketInArray);
                    --currentTokenIndex;
                    // need ']'
                    /*
                    scan->add_err();
                    sprintf(msg_temp,
                        "Syntax error: missing \']\' in declaration of array %s[]",
                        iToken.str.c_str());
                    scan->push();
                    */
                }
                currentToken = GetNextToken();//  ";" or ","
            }
            if (CheckCurrentToken(',')) {
                idNameToken = currentToken = GetNextToken();//next id
                if (idNameToken.TokenTypes != Convert.ToInt32( TokenType.ID)) {
                    //错误处理
                    ErrorRecord(ParseErrorType.ReservedToken);
                    ConsumeUntil(";", "}");
                    return temp;
                }
                currentToken = GetNextToken();//expected ";", ",", "["
                if (CheckCurrentToken(';')||
                    CheckCurrentToken(',') ||
                   CheckCurrentToken('['))
                {
                    temp.Sibling = VarDeclaration();
                }
                else {
                    //错误处理
                    ErrorRecord(ParseErrorType.MissingSemi);
                    --currentTokenIndex;
                    return temp;
                }
            }
            else if ( !CheckCurrentToken(';')) {
                //错误处理
                ErrorRecord(ParseErrorType.MissingSemiAfterDeclarationSequence);
                ConsumeUntil(";", "}");
            }
            return temp;
        }
コード例 #4
0
ファイル: Parser.cs プロジェクト: 2hanson/cminus
        /// <summary>
        /// 11. local-declarations→ local-declarations var-declaration | empty
        /// </summary>
        /// <returns></returns>
        TreeNode LocalDeclarations()
        {
            TreeNode temp = null;
            idNameToken = currentToken = GetNextToken();
            if (idNameToken.TokenTypes != Convert.ToInt32(TokenType.ID))
            {
                //错误处理
                ErrorRecord(ParseErrorType.ReservedToken);
                ConsumeUntil(";");
                return null;
            }

            currentToken = GetNextToken();//';', '[', ','

            if (CheckCurrentToken(';') || CheckCurrentToken('[') || CheckCurrentToken(','))
            {
                temp = VarDeclaration();
            }
            else
            {
                //错误处理
                ErrorRecord(ParseErrorType.MissingSemi);
                --currentTokenIndex;
            }
            return temp;
        }
コード例 #5
0
ファイル: Parser.cs プロジェクト: 2hanson/cminus
        /// <summary>
        /// sub_compoundstmt → ID; | call; | expression_stmt
        /// </summary>
        /// <returns></returns>
        TreeNode SubcompoundStmt()
        {
            TreeNode temp = null;

            // cout << "Subcompound_stmt()" <<endl;
            idNameToken = currentToken;
            currentToken = GetNextToken();
            if (CheckCurrentToken('('))
            {	// call statement
                temp = Call();
                if (!Match(';'))
                {
                    ErrorRecord(ParseErrorType.MissingSemiAfterFunCall);
                    --currentTokenIndex;
                    //scan->add_err();
                    //outputMsg(scan->lineno(), "Syntax error: missing \';\' after fun call");
                    //scan->push();
                }
            }
            else
            {
                --currentTokenIndex;
                currentToken = idNameToken;
                temp = ExpressionStmt();
            }
            return temp;
        }
コード例 #6
0
ファイル: Parser.cs プロジェクト: 2hanson/cminus
        /// <summary>
        /// 19. var → ID | ID [ expression ]
        /// </summary>
        /// <returns></returns>
        TreeNode Var()
        {
            Word iToken = idNameToken as Word;
            TreeNode temp = new TreeNode(ExpKind.IDK, (TokenType)currentToken.TokenTypes, iToken.Lexeme, currentToken.LineNumber, scope);
            // "["
            currentToken = GetNextToken();
            if (CheckCurrentToken('['))
            {
                temp.IsArray = true;
                currentToken = GetNextToken();
                temp.Child[0] = Expression();

                if (!Match(']'))
                {
                    ErrorRecord(ParseErrorType.MissingRBracket);
                    --currentTokenIndex;
                    //scan->add_err();
                    //outputMsg(scan->lineno(), "Syntax error: missing \']\'");
                    //scan->push();
                }
                //改动,不把数组的大小变成一个单独的节点。
                temp.ArraySize = Convert.ToInt16(temp.Child[0].Name.ToString());
                temp.Child[0] = null;
            }
            else
            {
                --currentTokenIndex;
            }

            return temp;
        }
コード例 #7
0
ファイル: Parser.cs プロジェクト: 2hanson/cminus
        /// <summary>
        /// 3. declaration → var-declaration | fun-declaration
        /// </summary>
        /// <returns></returns>
        TreeNode Declaration()
        {
            scope = "global";	// use global fun or var
            TreeNode temp = null;
            typeToken = currentToken;
            currentToken = GetNextToken();
            idNameToken = currentToken;

            if (idNameToken.TokenTypes != Convert.ToInt32(TokenType.ID))
            {
                ErrorRecord(ParseErrorType.ReservedToken);
                ConsumeUntil(";", "}");
                //错误处理
                //scan->add_err();
                //sprintf(msg_temp, "Syntax error: %s is a reserved token", iToken.str.c_str());
                //outputMsg(scan->lineno(), msg_temp);
                //consumeUntil(SEMI, RBRACE);
            }
            else {
                currentToken = GetNextToken();// expected a '(', '[' or  ','
                if (CheckCurrentToken('(')) {
                    // '(' is fun declaration
                    temp = FunDeclaration();
                }
                else if (CheckCurrentToken(';')||
                    CheckCurrentToken(',')||
                    CheckCurrentToken('['))
                {
                    temp = VarDeclaration();
                }
                else {
                    ErrorRecord(ParseErrorType.MissingSemi);
                    ConsumeUntil(";", "}");
                    //错误处理
                    //scan->add_err();
                    //sprintf(msg_temp, "Syntax error: missing \';\' after indentifer %s",iToken.str.c_str());
                    //outputMsg(scan->lineno(), msg_temp);
                    //consumeUntil(SEMI, RBRACE);
                }
            }
            return temp;
        }
コード例 #8
0
ファイル: Parser.cs プロジェクト: 2hanson/cminus
        /// <summary>
        /// 17. return-stmt → return; | return expression;
        /// </summary>
        /// <returns></returns>
        TreeNode ReturnStmt()
        {
            // cToken.str == "return"
            Word NToken = currentToken as Word;
            TreeNode temp = new TreeNode(StmtKind.returnK, NToken.Lexeme, currentToken.LineNumber, scope);
            currentToken = GetNextToken();

            //TreeNode temp11 = new TreeNode(StmtKind.returnK, NToken.Lexeme, currentToken.LineNumber, scope);

            //TreeNode temp1 = new TreeNode(StmtKind.returnK, NToken.Lexeme, currentToken.LineNumber, scope);
            if (!CheckCurrentToken(';')) {
                temp.Child[0] = Expression();
                if (!Match(';')) {
                    //错误处理
                    ErrorRecord(ParseErrorType.MissingSemiInReturn);
                    --currentTokenIndex;
                }
            }
            return temp;
        }
コード例 #9
0
ファイル: Parser.cs プロジェクト: 2hanson/cminus
        /// <summary>
        /// 10. compound-stmt → { local-declarations statement-list }
        /// </summary>
        /// <returns></returns>
        TreeNode CompoundStmt()
        {
            TreeNode first = null;
            TreeNode last = null;
            TreeNode temp = null;
            bool noBraces = false;
            if (!Match(Convert.ToInt32('{')))
            {// match "{"
                noBraces = true;
                --currentTokenIndex;
            }
            // local-declarations
            while (true)
            {

                typeToken = currentToken = GetNextToken();
                if (CheckCurrentToken(TokenType.INT) ||
                    CheckCurrentToken(TokenType.VOID))
                {
                    temp = LocalDeclarations();
                }
                else
                {
                    --currentTokenIndex;
                    break;
                }
                if (noBraces)
                    return temp;
                if (temp != null)
                {
                    if (first == null)
                    {
                        first = temp;
                        last = temp.LastSibling();
                    }
                    else
                    {
                        last.Sibling = temp;
                        last = temp.LastSibling();
                    }
                }
            }

            //currentToken = GetNextToken();
            currentToken = GetNextToken();
            while (true) {
                temp = null;
                if (CheckCurrentToken('}')) {
                    if (noBraces) {
                        //错误处理
                        ErrorRecord(ParseErrorType.UnpairedRBrace);
                    }
                    break;
                }
                if (CheckCurrentToken(TokenType.EOF)) {
                    //错误处理
                    ErrorRecord(ParseErrorType.MissingRBraceBeforeEOF);
                    --currentTokenIndex;
                    break;
                }
                switch (currentToken.TokenTypes) {
                    case (Int32)TokenType.READ:
                        temp = ReadStmt();
                        break;
                    case (Int32)TokenType.WRITE:
                        temp = WriteStmt();
                        break;
                    case (Int32)(';'):
                    case (Int32)TokenType.NUMBER:
                    case (Int32)('('):
                        temp = ExpressionStmt();
                        break;
                    case (Int32)TokenType.ID:
                        temp = SubcompoundStmt();
                        break;
                    case (Int32)TokenType.IF:
                        temp = IfStmt();
                      //  currentToken = GetNextToken();
                        break;
                    case (Int32)TokenType.WHILE:
                        temp = WhileStmt();
                        break;
                    case (Int32)TokenType.RETURN:
                        temp = ReturnStmt();
                        break;
                    case (Int32)TokenType.ELSE:
                        //错误处理
                        ErrorRecord(ParseErrorType.UnpairedElseStatement);
                        ConsumeUntil(";", "}");
                        //scan->add_err();
                        //outputMsg(scan->lineno(), " unpaired \'else\' statement");
                        //consumeUntil(SEMI, RBRACE);
                        break;
                    default:
                        //错误处理
                        ErrorRecord(ParseErrorType.UndefinedSymbol);
                        ConsumeUntil(";", "}");

                        //scan->add_err();
                        //sprintf(msg_temp, "Syntax error: undefined symbol \"%s\"", cToken.str.c_str());
                        //outputMsg(scan->lineno(), msg_temp);
                        //consumeUntil(SEMI, RBRACE);
                        break;
                }

                if (noBraces)
                    return temp;//// no braces
                if (temp != null) {
                    if (first == null)
                    {
                        first = temp;
                        last = temp.LastSibling();
                    }
                    else {
                        last.Sibling = temp;
                        last = temp.LastSibling();
                    }
                }

                currentToken = GetNextToken();
            }
            return first;
        }
コード例 #10
0
ファイル: Parser.cs プロジェクト: 2hanson/cminus
 private void ConsumeUntil(string type)
 {
     while (currentToken.TokenInfo != type && currentToken.TokenInfo != "EOF")
         currentToken = GetNextToken();
 }
コード例 #11
0
ファイル: Parser.cs プロジェクト: 2hanson/cminus
        /// <summary>
        /// 28. args → arg-list | empty & 29. arg-list → arg-list , expression | expression
        /// </summary>
        /// <returns></returns>
        private TreeNode Args()
        {
            TreeNode first = null;
            TreeNode temp = null;
            currentToken = GetNextToken();
            if (CheckCurrentToken(')')) {
                --currentTokenIndex;
                return null;
            }
            while (true) {
                if ((temp = Expression()) != null)
                {
                    if (first == null) first = temp;
                    else
                    {
                        temp.Sibling = first;
                        first = temp;
                    }
                }

                currentToken = GetNextToken();
                if (currentToken.TokenTypes == Convert.ToInt32(','))
                {
                    currentToken = GetNextToken();
                }
                else
                {
                    break;
                }
            }
            --currentTokenIndex;
            return first;
        }
コード例 #12
0
ファイル: Parser.cs プロジェクト: 2hanson/cminus
        /// <summary>
        /// 31. write → write( int );
        /// </summary>
        /// <returns></returns>
        TreeNode WriteStmt()
        {
            TreeNode temp = null;
            if (!Match('('))
            {
                ErrorRecord(ParseErrorType.MissingRParenthesis);
                ConsumeUntil(";", "}");

                //scan->add_err();
                //outputMsg(scan->lineno(), "Syntax error: missing \'(\'");
                //consumeUntil(SEMI, RBRACE);
                return null;
            }

            temp = new TreeNode(StmtKind.writeK, "write", currentToken.LineNumber, scope);
            currentToken = GetNextToken();
            if ((temp.Child[0] = Expression()) != null)
            {
                temp.Child[0].Father = temp;
            }

            if (!Match(')'))
            {
                ErrorRecord(ParseErrorType.MissingRParenthesis);
                ConsumeUntil(";", "}");
                //scan->add_err();
                //outputMsg(scan->lineno(), "Syntax error: missing \')\'");
                //consumeUntil(SEMI, RBRACE);
                return temp;
            }

            if (!Match(';'))
            {
                ErrorRecord(ParseErrorType.MissingSemiOnly);
                --currentTokenIndex;
                //scan->add_err();
                //outputMsg(scan->lineno(), "Syntax error: missing \';\'");
                //scan->push();
            }

            return temp;
        }
コード例 #13
0
ファイル: Parser.cs プロジェクト: 2hanson/cminus
        /// <summary>
        /// 16. iteration-stmt → while ( expression ) statement
        /// </summary>
        /// <returns></returns>
        TreeNode WhileStmt()
        {
            Word CToken = currentToken as Word;
            TreeNode temp = new TreeNode(StmtKind.whileK,CToken.Lexeme,currentToken.LineNumber,scope);
            TreeNode p = null;
            if (!Match('('))
            {
                ErrorRecord(ParseErrorType.MissingLParenthesisInWhile);
                /*
                // while (
                scan->add_err();	// add error count,
                // out put the error message
                outputMsg(scan->lineno(), "Syntax error: missing \'(\' in \"while\" statement");

                 */
            }
            else {
                currentToken = GetNextToken();
            }

            // cToken should be the first token of expression now ...
            temp.Child[0] = Expression();
            if (temp.Child[0] != null)
                temp.Child[0].Father = temp;
            if (!Match(')')) {
                //while()
                //错误处理
                ErrorRecord(ParseErrorType.MissingRParenthesisInWhile);
            }

            p = temp.Child[1] = CompoundStmt();
            if (p != null)
                p.Father = temp;
            while (p != null && p.Sibling != null) {
                p = p.Sibling;
                p.Father = temp;
            }
            return temp;
        }
コード例 #14
0
ファイル: Parser.cs プロジェクト: 2hanson/cminus
 /// <summary>
 ///  7. params → params-list | void
 ///  8. param-list→ param-list, param | param
 ///  9. param→ type-specifier ID | type-specifier ID [ ]
 /// </summary>
 /// <returns></returns>
 TreeNode Params()
 {
     TreeNode first = null;
     TreeNode temp = null;
     typeToken = currentToken = GetNextToken();
     if (CheckCurrentToken(')')) {
         --currentTokenIndex;//scan->push();
         return temp;//null
     }
     if (typeToken.TokenTypes == Convert.ToInt32(TokenType.VOID))
     {
         if (Match(Convert.ToInt32( ')')))
         {
             --currentTokenIndex;
             return temp;	// NULL
         }
         else
         {
             --currentTokenIndex;//scan->push();	// not ")"
         }
     }
     while (typeToken.TokenTypes == Convert.ToInt32(TokenType.INT) ||
         typeToken.TokenTypes == Convert.ToInt32(TokenType.VOID))
     {
         idNameToken = currentToken = GetNextToken();
         if (idNameToken.TokenTypes != Convert.ToInt32(TokenType.ID))
         {
             //error
             ErrorRecord(ParseErrorType.InvalidParameter);
         }
         else {
             Word iToken = idNameToken as Word;
             temp = new TreeNode(NodeKind.paramK, (TokenType)typeToken.TokenTypes, iToken.Lexeme, currentToken.LineNumber, scope);
             temp.Sibling = first;
             first = temp;
         }
         currentToken = GetNextToken();
         if (CheckCurrentToken('[')) {
             temp.IsArray = true;
             if (!Match(Convert.ToInt32(']')))
             {
                 //错误处理
                 ErrorRecord(ParseErrorType.MissingArrayParameter);
                 ConsumeUntil(";", ")");
             }
             else {
                 currentToken = GetNextToken();//','
             }
         }
         if (CheckCurrentToken(')')) {//')'
             break;//')'
         }
         else if (CheckCurrentToken(','))//','
         {
             typeToken = currentToken = GetNextToken();
         }
         else {
             break;
         }
     }
     --currentTokenIndex; //next is ')'
     return first;
 }
コード例 #15
0
ファイル: Parser.cs プロジェクト: 2hanson/cminus
 /// <summary>
 /// 2. declaration-list → declaration-list declaration | declaration
 /// </summary>
 /// <returns></returns>
 TreeNode DeclarationList()
 {
     TreeNode program = null;
     TreeNode last = null;
     TreeNode temp = null;
     currentToken = GetNextToken();
     while (!CheckCurrentToken(TokenType.EOF)) {
         if (!CheckCurrentToken(TokenType.INT)&&
             !CheckCurrentToken(TokenType.VOID) &&!CheckCurrentToken(';'))
         {
             ErrorRecord(ParseErrorType.InvalidType);
             ConsumeUntil(";","}");
             //错误处理
             //scan->add_err();
             //sprintf(msg_temp, "Syntax error: invalid type \'%s\'",
             //    cToken.str.c_str());
             //outputMsg(scan->lineno(), msg_temp);
             //consumeUntil(SEMI, RBRACE); // ';', '}'
         }
         else if ((temp = Declaration()) != null)
         {
             if (program == null)
             {
                 program = temp;
                 last = temp.LastSibling();
             }
             else
             {
                 last.Sibling = temp;
                 last = temp.LastSibling();
             }
         }
         currentToken = GetNextToken();
     }
     return program;
 }
コード例 #16
0
ファイル: Parser.cs プロジェクト: 2hanson/cminus
        /// <summary>
        /// 30. read → read( int ); 
        /// </summary>
        /// <returns></returns>
        TreeNode ReadStmt()
        {
            // currentToken.str == "read"
            TreeNode temp = null;
            if (!Match('('))
            {
                ErrorRecord(ParseErrorType.MissingLParenthesis);
                ConsumeUntil(";","}");
                //scan->add_err();
                //outputMsg(scan->lineno(), "Syntax error: missing \'(\'");
                //consumeUntil(SEMI, RBRACE);
                return null;
            }

            idNameToken = currentToken = GetNextToken();
            if (!CheckCurrentToken(TokenType.ID))
            {
                //错误处理
                ErrorRecord(ParseErrorType.BadArgument);
                ConsumeUntil(";", "}");
                return null;
            }
            temp = new TreeNode(StmtKind.readK, "read", currentToken.LineNumber, scope);
            if ((temp.Child[0] = Var()) != null)
            {
                temp.Child[0].Father = temp;
            }

            if (!Match(')'))
            {
                ErrorRecord(ParseErrorType.MissingRParenthesis);
                ConsumeUntil(";", "}");
                //scan->add_err();
                //outputMsg(scan->lineno(), "Syntax error: missing \')\'");
                //consumeUntil(SEMI, RBRACE);
                return temp;
            }

            if (!Match(';'))
            {
                ErrorRecord(ParseErrorType.MissingSemiOnly);
                --currentTokenIndex;
                //scan->add_err();
                //outputMsg(scan->lineno(), "Syntax error: missing \';\'");
                //scan->push();
            }

            return temp;
        }
コード例 #17
0
ファイル: Parser.cs プロジェクト: 2hanson/cminus
        /// <summary>
        /// 18. expression → var = expression | simple-expression
        /// </summary>
        /// <returns></returns>
        private TreeNode Expression()
        {
            // cToken == (, k_ID, k_NUM
            TreeNode temp = SimpleExpression();
            TreeNode p = temp;

            currentToken = GetNextToken();

            if (CheckCurrentToken('='))
            {
                if (temp.Type != TokenType.ID && (Int32)temp.Type != (Int32)('='))
                {
                    //错误处理
                    ErrorRecord(ParseErrorType.LeftID);
                    ConsumeUntil(";", ")");
                    return null;
                }
                p = new TreeNode(ExpKind.OpK, (TokenType)currentToken.TokenTypes, currentToken.TokenInfo, currentToken.LineNumber, scope);
                p.Child[0] = temp;
                if (p.Child[0] != null)
                    p.Child[0].Father = p;
                currentToken = GetNextToken();
                p.Child[1] = Expression();
                if (p.Child[1] != null)
                    p.Child[1].Father = p;
            }
            else {
                --currentTokenIndex;
            }
            return p;
        }
コード例 #18
0
ファイル: Parser.cs プロジェクト: 2hanson/cminus
 /// <summary>
 /// 20. simple-expression → additive-expression relop additive-expression
 /// |additive-expression
 /// 21. relop →<= | < | > | >= | == | !=
 /// </summary>
 /// <returns></returns>
 private TreeNode SimpleExpression()
 {
     TreeNode p = AdditiveExpression();
     currentToken = GetNextToken();
     if (CheckCurrentToken(TokenType.LESSEQUAL) ||
         CheckCurrentToken('<') || CheckCurrentToken('>') ||
         CheckCurrentToken(TokenType.GREATERQUAL) || CheckCurrentToken(TokenType.EQUAL) ||
         CheckCurrentToken(TokenType.NOTEQUAL))
     {
         TreeNode temp = new TreeNode(ExpKind.OpK, (TokenType)currentToken.TokenTypes, currentToken.TokenInfo, currentToken.LineNumber, scope);
         temp.Child[0] = p;
         p = temp;
         if (p.Child[0] != null)
             p.Child[0].Father = p;
         currentToken = GetNextToken();
         p.Child[1] = AdditiveExpression();
         if (p.Child[1] != null) {
             p.Child[1].Father = p;
         }
     }
     else {
         --currentTokenIndex;
     }
     return p;
 }
コード例 #19
0
ファイル: Parser.cs プロジェクト: 2hanson/cminus
        /// <summary>
        /// 26. factor → ( expression ) | var | call | NUM
        /// </summary>
        /// <returns></returns>
        private TreeNode Factor()
        {
            TreeNode temp = null;
            switch (currentToken.TokenTypes)
            {

                case (Int32)TokenType.NUMBER:
                    Number NToken = currentToken as Number;
                    temp = new TreeNode(ExpKind.ConstK, (TokenType)currentToken.TokenTypes, NToken.Lexeme , currentToken.LineNumber, scope);
                    break;
                case (Int32)TokenType.ID:
                    idNameToken = currentToken;
                    currentToken = GetNextToken();
                    if (CheckCurrentToken('(')) temp = Call();
                    else
                    {
                        --currentTokenIndex;
                        temp = Var();
                    }
                    break;
                case (Int32)('('):
                    currentToken = GetNextToken();
                    temp = Expression();
                    if (!Match(')'))
                    {
                        ErrorRecord(ParseErrorType.MissingRParenthesis);
                        --currentTokenIndex;
                        //scan->add_err();
                        //outputMsg(scan->lineno(), "Syntax Error: missing \')\'");
                        //scan->push();
                    }
                    break;
                default:
                    ErrorRecord(ParseErrorType.ExpressionIsUnexpected);
                    ConsumeUntil(";", "}");
                    //scan->add_err();
                    //sprintf(msg_temp, "Syntax error: \'%s\' expression is unexpected!", cToken.str.c_str());
                    //outputMsg(scan->lineno(), msg_temp);
                    //consumeUntil(SEMI, RBRACE);
                    break;
            }

            return temp;
        }
コード例 #20
0
ファイル: Parser.cs プロジェクト: 2hanson/cminus
        /// <summary>
        ///  24. term → term mulop factor | factor
        ///  25. mulop →* | /
        /// </summary>
        /// <returns></returns>
        private TreeNode Term()
        {
            TreeNode p = Factor();
            currentToken = GetNextToken();
            while (CheckCurrentToken('*') || CheckCurrentToken('/') || CheckCurrentToken('%')) {

                TreeNode temp = new TreeNode(ExpKind.OpK, (TokenType)currentToken.TokenTypes, currentToken.TokenInfo, currentToken.LineNumber, scope);
                temp.Child[0] = p;
                p = temp;
                if (p.Child[0] != null)
                    p.Child[0].Father = p;
                currentToken = GetNextToken();
                p.Child[1] = Factor();
                if (p.Child[1] != null)
                {
                    p.Child[1].Father = p;
                }
                currentToken = GetNextToken();
            }
            --currentTokenIndex;
            return p;
        }
コード例 #21
0
ファイル: Parser.cs プロジェクト: 2hanson/cminus
        /// <summary>
        ///  15. selection-stmt → if (expression ) s tatement
        ///  | if ( expression ) statement else statement 
        /// </summary>
        /// <returns></returns>
        TreeNode IfStmt()
        {
            Word CToken = currentToken as Word;
            TreeNode temp = new TreeNode(StmtKind.ifK,CToken.Lexeme,currentToken.LineNumber,scope);
            TreeNode p = null;
            if (!Match('('))
            { // if (
                //错误处理
                ErrorRecord(ParseErrorType.MissingLParenthesisInIf);
                //scan->add_err();
                //outputMsg(scan->lineno(), "Syntax error: missing \'(\' in \"if\" statement");
            }
            else
            {
                currentToken = GetNextToken();
            }

            temp.Child[0] = Expression();

            if (temp.Child[0] != null)
                temp.Child[0].Father = temp;
            if (!Match(')')) {
                //错误处理
                ErrorRecord(ParseErrorType.MissingRParenthesisInIf);
            }

            p = temp.Child[1] = CompoundStmt();
            if (p != null)
                p.Father = temp;
            while (p != null && p.Sibling != null) {
                p = p.Sibling;
                p.Father = temp;
            }

            currentToken = GetNextToken();
            if (CheckCurrentToken(TokenType.ELSE))
            {
                p = temp.Child[2] = CompoundStmt();
                if (p != null) p.Father = temp;
                while (p!=null && p.Sibling!=null)
                {
                    p = p.Sibling;
                    p.Father = temp;
                }
            }
            else {
                // if has no 'else' statement, push the next token back
                --currentTokenIndex;
            }

            return temp;
        }
コード例 #22
0
ファイル: Lexer.cs プロジェクト: 2hanson/cminus
 /// <summary>
 /// 把token加到token链表
 /// </summary>
 /// <param name="token">token类型</param>
 private void AddToTokenList(Token token)
 {
     token.LineNumber += 1;
     token.ColumnNumber += 1;
     tokenList.Add(token);
 }
コード例 #23
0
ファイル: Parser.cs プロジェクト: 2hanson/cminus
        public void ParseLL1(List<Token> tokenList)
        {
            ///*语法树的根节点*/
            TreeNode rootPointer;
            currentToken = GetNextToken();
            int pNum = 0; //纪录选中的产生式编号

            LL1Table.CreatLL1Table();

            ///*指向整个语法树根节点的指针,由它得到语法树*/
            rootPointer = OperateTree.NewRootNode();
            treeStack.Push(rootPointer);
            ///*从这里开始进行语法分析和语法树的生成*/
            elementStack.Push(new LL1StackElement(true, NonTerminalType.Program,-1));
            
          
            /*取一个token*/
            int lineNum = currentToken.LineNumber;
            while (elementStack.Count != 0)
            {
                LL1StackElement element = (LL1StackElement)elementStack.Peek();
                
                /*检测终极符是否匹配*/
                if (element.Flag == false)
                {
                    if (Convert.ToInt16(element.TokenType) == currentToken.TokenTypes)
                    {
                        elementStack.Pop();
                        currentToken = GetNextToken();
                        if (currentToken == null) {//空
                            break;
                        }
                        //lineno = currentToken.lineshow;

                    }
                    else
                    {
                        //syntaxError("unexpected  token ->  ");
                        //fprintf(listing, "  %s", currentToken.Sem);
                        //fprintf(listing, "		");
                        ////printf("terminal not match!\n");
                        ////printf("%d\n",stacktopT);
                        //exit(0);
                    }
                }
                else
                {  /*根据非终极符和栈中符号进行预测*/
                    pNum = LL1Table.LL1table[Convert.ToInt16(element.NonTerminalType), currentToken.TokenTypes];
                    if (pNum == 39)
                    {
                        //向前看一个 读完i返回原处
                    }
                    else if (pNum == 7)
                    {
                        //向前看两个 读完i返回原处
                    }
                    
                    elementStack.Pop();
                    //	if (0==pnum)
                    //	{	printf("no predict!\n");
                    //        printf("%d\n",stacktopN);
                    //	}
                    Predict(pNum);

                    }
                }

                if (tokenList[i].TokenTypes != Convert.ToInt16(TokenType.EOF))
                {
                    //syntaxError("Code  ends  before  file \n");
                }
                //return rootPointer;
        }