Пример #1
0
        public void Insert(TreeNode pNode)
        {
            // pNode.nodekind must be funK,
            // pNode.name	must be not in FunDecListRec;
            FunDecListRec temp = new FunDecListRec(pNode.Name, pNode.Type);

            // count the params
            TreeNode p = pNode.Child[0];	// params link in pNode.chilld[0].sibling
            temp.lineno = pNode.LineNum;// record functions' line

            if (p != null)
            {
                temp.Params = new ParamListRec(p.Type, p.IsArray);
                temp.count++;

                ParamListRec l = temp.Params;
                while (p.Sibling  != null)
                {
                    p = p.Sibling;
                    l.next = new ParamListRec(p.Type, p.IsArray);
                    l = l.next;
                    temp.count++;
                }
            }

            if (first == null)  // has not function declarations in list
            {
                first = last = temp;
            }
            else
            {
                last.next = temp;
                last = last.next;
            }
        }
Пример #2
0
 /// <summary>
 /// 构造函数,传入词法的tokenlist
 /// </summary>
 /// <param name="tokenList"></param>
 public Parser(List<Token> ttokenList)
 {
     _good = false;
     this.tokenList = ttokenList;
     root = null;
     currentTokenIndex = -1;
 }
Пример #3
0
        /// <summary>
        /// 递归生成语法树,节点的名字从0开始编号,显示的内容不是这些数字
        /// </summary>
        /// <param name="TN"></param>
        /// <param name="FatherNode"></param>
        private void BuildingTree(TreeNode TN, TreeContainer.TreeNode CurrentNode, TreeContainer.TreeNode FatherNode)
        {
            TreeContainer.TreeNode temp, tempFatherNode;
            //生成所有的孩子节点
            for (int i = 0; i < 4; ++i) {
                if (TN.Child[i] == null) {
                    continue;
                }
                temp = CreaterTreeNode(TN.Child[i]);
                temp = Tree.AddNode(temp, CurrentNode);
                tempFatherNode = CurrentNode;
                BuildingTree(TN.Child[i], temp, tempFatherNode);
            }
            //生成兄弟节点
            TreeNode tempTN = TN;
            //开始用while,错了,改成if。
            if (tempTN.Sibling != null)
            {
                tempTN = tempTN.Sibling;

                temp = CreaterTreeNode(tempTN);
                temp = Tree.AddNode(temp, FatherNode);
                BuildingTree(tempTN, temp, FatherNode);
            }
        }
Пример #4
0
 /// <summary>
 /// 产生语法树,传入虚拟根节点,由他扩展。
 /// </summary>
 /// <param name="vitualRoot"></param>
 public void CreatSyntaxTree(TreeNode vitualRoot)
 {
     TreeContainer.TreeNode treeRoot;
     //命名树节点
     treeRoot = CreaterTreeNode(vitualRoot);
     treeRoot = Tree.AddRoot(treeRoot);
     BuildingTree(vitualRoot, treeRoot, null);
 }
Пример #5
0
 /// <summary>
 ///  build parse tree
 /// </summary>
 public TreeNode BuildSyntaxTree()
 {
     root = new TreeNode(NodeKind.proK, TokenType.NONE , "Root", 0, "global");
     TreeNode p = null;
     scope = "global";
     p = root.Child[0] = Program();
     if (p != null)
         p.Father = root;
     //
     while (p != null && p.Sibling != null)
     {
         p = p.Sibling;
         p.Father = root;
     }
     return root;
 }
Пример #6
0
        /// <summary>
        /// check if a function call's argument match its declaration parameters;
        /// return -1, not found;
        /// return -2, type not match;
        /// return -3, match;
        /// else return delcaration parameter count, not match,  and
        /// "string &args"  is the function's parament list, like "int, int[], int"
        /// line to record the functions' lineno that its defined here.
        /// </summary>
        public int Check(TreeNode pNode, string args,ref int line)
        {
            FunDecListRec l = first;

            while ((l!=null) && l.name != pNode.Name)	l = l.next;
            if (l==null)	return -1;	// function use before its declaration or not declara

            ParamListRec p = l.Params;
            TreeNode t = pNode.Child[0];

            // record paraments list, this is not a good idea
            while (p!=null) {
                if (p.type == TokenType.VOID) args  = "void, " + args;
                else if (p.type == TokenType.INT){
                     args =  (p.isArr ? "int[], " : "int, ") + args;
                }

                p = p.next;
            }

               // args.erase(args.Length-2);	// erase last ", "
            args = args.Remove(args.Length - 2,1);
            line = l.lineno;
            // set it point to l.params after record paraments list
            p = l.Params;
            while (p!=null &&t!=null)
            {
                if ((p.type == t.Type && p.isArr == t.IsArray)
                    || (t.NodeKind ==NodeKind.expK && t.exp ==ExpKind.ConstK && t.Type == TokenType.NUMBER))
                {
                    p = p.next;
                    t = t.Sibling ;
                }
                else
                {
                    return -2;	// type not match;
                }
            }

            if (p!=null || t!=null) {
             	        return l.count;	// params count not match
            }
            else	return -3;				// all match;
        }
Пример #7
0
        public Analyzer(List<Token> tokenlist)
        {
            traceAnalyze= true;
            traceParse = true;
            parse = new Parser(tokenlist);
            program = null;
            program = parse.BuildSyntaxTree();
            program = program.Child[0];
               // symbolTab.initial();   // because symbolTab and FunArgs is static member,
               // FunArgs.initial();     // so, before use , should reset/initial them

            //symFile = filename;
            //int pos = symFile.rfind('.');
            //symFile.erase(pos, symFile.length()-1);
            //symFile += ".tab";	// symbol table file

            is_good_ = true;
            location = 0;      //  intial memory location
            err = 0;           // there are static member, should initial before use
            warn = 0;
        }
Пример #8
0
        public void traverse1(TreeNode t)
        {
            if (t != null)
            {
                InsertNode(t);
                for (int i = 0; i <= 10; ++i)
                {
                    traverse1( t.Child[i]);
                }

               // postProc(t);
                traverse1( t.Sibling);
            }
        }
Пример #9
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="pNode"></param>
        void CheckNode(TreeNode pNode)
        {
            TreeNode t;
            string args;
            int ret, oldline; // record the return value and function defined lineno if its defined.

            // initial them
            ret = oldline = -1;
            args = "";
            t = pNode;

            switch (t.NodeKind) {
                //case NodeKind.stmtK:
                case NodeKind.stmtK:
                    switch (t.stmt) {
                        case StmtKind.readK:
                            if (t.Child[0] != null) {
                                t.Type = t.Child[0].Type;
                                if (t.Type != TokenType.INT){
                                    //outputMsg(t.lineno, "read statement can only read a \"int\" value to a int variable!");
                                    err++;
                                }
                            }
                            else
                            {
                                err++;
                                ErrorRecord(AnalyzerErrorType.MaybeCompilerBug,t);
                                //outputMsg(-1, "maybe compiler bug!");
                            }

                            break;
                        case StmtKind.writeK:
                            if (t.Child[0] != null) {
                                t.Type = t.Child[0].Type;
                                if (t.Type != TokenType.INT)
                                {
                                    //outputMsg(t.lineno, "write statement can only output a \"int\" variable or a number output!");
                                    err++;
                                }
                            }
                            else
                            {
                                err++;
                                ErrorRecord(AnalyzerErrorType.MaybeCompilerBug, t);
                                //outputMsg(-1, "maybe compiler bug!");
                            }

                            break;
                        case StmtKind.returnK:
                            if (t.Child[0] == null) { // return should be a void
                                if (symbolTab.SearchType(t.Name, "global") != TokenType.VOID)
                                {
                                    //sprintf(msg_temp, " function \"int %s(...)\" must have return value ", t.Name.c_str());
                                    //outputMsg(t.lineno, msg_temp);
                                    err++;
                                }
                            }
                            break;
                        case StmtKind.callK:
                            ret = FunArgs.Check(t, args, ref oldline);
                            if (ret != -3)  // -3 is ok
                            {
                                err++;
                                warn++;

                                if (ret >= 0) {
                                    //sprintf(msg_temp,
                                    //        "too few or many paramenters to call function \"%s(%s)\", its has %d params",
                                    //        t.Name.c_str(),
                                    //        args.c_str(),
                                    //        ret);
                                    //outputMsg(t.lineno, msg_temp);
                                    // out put the functions' declaration,
                                    //sprintf(msg_temp,
                                    //        "see the function \"%s(%s)\" declaration here!!",
                                    //        t.Name.c_str(),
                                    //        args.c_str());
                                    //outputMsg(oldline, msg_temp);

                                } else if (ret == -1) {
                                    //sprintf(msg_temp, "function \"%s\"(...) has not declared before use it", t.Name.c_str());
                                    //outputMsg(t.lineno, msg_temp);
                                } else {
                                    //sprintf(msg_temp,
                                    //        " call function \"%s(%s)\" with no matched Type paramenters!",
                                    //        t.Name.c_str(), args.c_str());
                                    //outputMsg(t.lineno, msg_temp);

                                    //sprintf(msg_temp,
                                    //        "see the function \"%s(%s)\" declaration here!!",
                                    //        t.Name.c_str(),
                                    //        args.c_str());
                                    //outputMsg(oldline, msg_temp);
                                }
                            }
                            else
                            {
                                t.Type = symbolTab.SearchType(t.Name, t.Scope);
                            }
                            break;
                        default:
                            break;
                    }
                    break;
                case NodeKind.expK:
                    switch (t.exp) {
                        case ExpKind.OpK:
                            if (Convert.ToInt32(t.Type) == Convert.ToInt32('='))
                            {
                                t.Type = t.Child[0].Type;
                            }
                            else
                            {
                                if (t.Child[0].Type == TokenType.VOID || t.Child[1].Type == TokenType.VOID)
                                {
                                    err++;
                                    //outputMsg(t.lineno, "illegal use of Type \"void\"");
                                }
                                else if (t.Child[0].Type == TokenType.INT || t.Child[1].Type == TokenType.INT)
                                {
                                    t.Type = TokenType.INT;
                                }
                                else
                                {
                                    // ...
                                }
                            }
                            break;
                        case ExpKind.IDK:
                            t.Type = symbolTab.SearchType(t.Name, t.Scope);
                            t.IsArray = symbolTab.SearchArray(t.Name, t.Scope);
                            break;
                        default:
                            break;
                    }
                    break;
                default:
                    break;
                }
        }
Пример #10
0
        /// <summary>
        ///  27. call → ID ( args )
        /// </summary>
        /// <returns></returns>
        private TreeNode Call()
        {
            Word iToken = idNameToken as Word;
            TreeNode p = new TreeNode(StmtKind.callK, iToken.Lexeme, currentToken.LineNumber, scope);
            TreeNode temp = null;
            p.Scope = "global";

            p.Child[0] = Args();
            if (p.Child[0] != null) {
                p.Child[0].Father = p;
            }

            temp = p.Child[0];
            while (temp != null && temp.Sibling != null) {
                temp = temp.Sibling;
                temp.Father = p;
            }
            if (!Match(')')) {
                //错误处理
                ErrorRecord(ParseErrorType.MissingRParenthesis);
                --currentTokenIndex;
            }
            return p;
        }
Пример #11
0
        public void InsertNode(TreeNode t)
        {
            if (t == null) return;

            switch (t.NodeKind )
            {
                case NodeKind.funK:
                    if (symbolTab.LookUp(t.Name, t.Scope) == -1)
                    {
                        symbolTab.Insert(t.Name, t.Scope, t.Type, t.LineNum, location, false);
                        ////addMemLoc();
                        FunArgs.Insert(t);
                    }
                    else
                    {
                        //Analyzer::parse.add_err();
                        err++;
                       // //sprintf(msg_temp, "function \"%s\"(...) redefinition", t.Name.c_str());
                        ////outputMsg(t.LineNum, msg_temp);
                    }

                    break;
                case NodeKind.varK:
                case NodeKind.paramK:
                    if (symbolTab.LookUp(t.Name, t.Scope) == -1)
                    {
                        symbolTab.Insert(t.Name, t.Scope, t.Type, t.LineNum, location, t.IsArray);
                        ////addMemLoc();
                    }
                    else
                    {
                        err++;

                        //sprintf(msg_temp, "variable \"%s\" redefinition", t.Name.c_str());
                        ErrorRecord(AnalyzerErrorType.VariableRedefinition, t);
                        //outputMsg(t.LineNum, msg_temp);
                    }
                    break;
                case NodeKind.stmtK:	// just call
                    if (t.stmt == StmtKind.callK)
                    {
                        if (symbolTab.LookUp(t.Name, t.Scope) == -1)
                        {
                            err++;
                            //sprintf(msg_temp, "unresolved external symbol \"%s\"", t.Name.c_str());
                            //outputMsg(t.LineNum, msg_temp);
                        }
                        else
                        {
                            symbolTab.Insert(t.Name, t.Scope, TokenType.ID, t.LineNum, 0, false);
                        }
                    }

                    break;
                case NodeKind.expK:
                    if (t.exp == ExpKind.IDK) {
                        if ( symbolTab.LookUp(t.Name, t.Scope) == -1
                            && symbolTab.LookUp(t.Name, "global") == -1)
                        {	// undeclared
                            //Analyzer::parse.add_err();
                            err++;
                            ErrorRecord(AnalyzerErrorType.IdentifierUndeclared, t);
                            //sprintf(msg_temp, "undeclared identifier: \"%s\"", t.Name.c_str());
                            //outputMsg(t.LineNum, msg_temp);
                        }
                        else if (symbolTab.LookUp(t.Name, t.Scope) !=  -1)
                        {	// local variable
                            if ((t.Father!=null) && (t.Father.NodeKind != NodeKind.stmtK || t.Father.stmt != StmtKind.callK)/* not in call statement */ &&
                            t.IsArray != symbolTab.SearchArray(t.Name,t.Scope))
                            {
                                //Analyzer::parse.add_err();
                                err++;
                                //sprintf(msg_temp, "\"%s\" is %s declared as array", t.Name.c_str(), t.bArr? "not" : "");
                                //outputMsg(t.LineNum, msg_temp);
                            }
                            else
                            {
                                symbolTab.Insert(t.Name, t.Scope, t.Type, t.LineNum, 0, false);
                            }
                        }
                        else
                        {	// global variable
                            t.Scope = "global";
                            if ((t.Father != null) && (t.Father.NodeKind != NodeKind.stmtK || t.Father.stmt != StmtKind.callK)/* not in call statement */ &&
                            t.IsArray != symbolTab.SearchArray(t.Name, t.Scope))
                            {
                                //Analyzer::parse.add_err();
                                err++;
                                //sprintf(msg_temp, "\"%s\" is %s declared as array", t.Name.c_str(), t.bArr? "not" : "");
                                //outputMsg(t.LineNum, msg_temp);
                            }
                            else
                            {
                                symbolTab.Insert(t.Name, t.Scope, t.Type, t.LineNum, 0, false);
                            }
                        }
                    }

                    break;
                default:
                    break;
            }
        }
Пример #12
0
 /// <summary>
 /// Type checking by a postorder syntax tree traversal
 /// </summary>
 /// <param name="pNode"></param>
 void TypeCheck(TreeNode pNode)
 {
     Traverse2(pNode);
     if ( symbolTab.LookUp("main", "global") == -1)
     {
         err++;
         is_good_ = false;
         ////outputMsg(-1, "Unresolved external symbol _main");
         warn++;
         ////outputMsg(-1, "program must have function \"main(void)\" !");
     }
 }
Пример #13
0
        /// <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;
        }
Пример #14
0
        /// <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;
        }
Пример #15
0
        /// <summary>
        /// 生成一个显示树的节点,给它付名字(0开始变化的数字),和内容
        /// </summary>
        /// <param name="LogicalTreeNode"></param>
        /// <returns></returns>
        private TreeContainer.TreeNode CreaterTreeNode(TreeNode LogicalTreeNode)
        {
            ++treeNodeCount;
            TreeContainer.TreeNode tempTreeNode = new TreeContainer.TreeNode();
            TextBlock NodeName = new TextBlock();
            NodeName.Width = 75;
            NodeName.Height = 30;
            NodeName.TextWrapping = TextWrapping.Wrap;
            NodeName.FontSize = 18;
            NodeName.FontWeight = FontWeights.Bold;
            NodeName.TextAlignment = TextAlignment.Center;
            NodeName.FontFamily = new FontFamily("Comic Sans MS");
            NodeName.Text = LogicalTreeNode.Name;

            ToolTip toolTip = new ToolTip();
            SyntaxTreeNodeToolTip toolTipContent = new SyntaxTreeNodeToolTip();

            String NodeKindName = "";
            switch (LogicalTreeNode.NodeKind)
            {
                case NodeKind.proK:
                    NodeKindName = "Program";
                    break;
                case NodeKind.funK:
                    NodeKindName = "Function declaration";
                    break;
                case NodeKind.paramK:
                    NodeKindName = "Parameter";
                    break;
                case NodeKind.varK:
                    NodeKindName = "Variable declaration";
                    break;
                case NodeKind.stmtK:
                    switch ((StmtKind)LogicalTreeNode.Kind)
                    {
                        case StmtKind.ifK:
                            NodeKindName = "If";
                            break;
                        case StmtKind.readK:
                            NodeKindName = "Call";
                            break;
                        case StmtKind.writeK:
                            NodeKindName = "Call";
                            break;
                        case StmtKind.returnK:
                            NodeKindName = "Return";
                            break;
                        case StmtKind.callK:
                            NodeKindName = "Call";
                            break;
                    }
                    break;
                case NodeKind.expK:
                    switch ((ExpKind)LogicalTreeNode.Kind)
                    {
                        case ExpKind.ConstK:
                            NodeKindName = "const";
                            break;
                        case ExpKind.IDK:
                            NodeKindName = "ID";
                            break;
                        case ExpKind.OpK:
                            NodeKindName = "Operater";
                            break;
                    }
                    break;
            }
            toolTipContent.NodeKindContent.Text = NodeKindName;

            toolTipContent.ScopeContent.Text = LogicalTreeNode.Scope;

            String TypeName ="";
            if(Convert.ToInt16(LogicalTreeNode.Type)<=255)
                TypeName = ((char)(Convert.ToInt16(LogicalTreeNode.Type))).ToString();
            else
            {
                switch(Convert.ToInt16(LogicalTreeNode.Type))
                {
                    case 256:
                        TypeName =  "ELSE";
                        break;
                    case 257:
                        TypeName =  "EQUAL";
                        break;
                    case 258:
                        TypeName =  "GREATERQUAL";
                        break;
                    case 259:
                        TypeName =  "ID";
                           break;
                    case 260:
                        TypeName =  "IF";
                        break;
                    case 261:
                        TypeName =  "INT";
                        break;
                    case 262:
                        TypeName =  "LEFTCOMMON";
                        break;
                    case 263:
                        TypeName =  "LESSEQUAL";
                        break;
                    case 264:
                        TypeName =  "MINUS";
                        break;
                    case 265:
                        TypeName =  "NOTEQUAL";
                        break;
                    case 266:
                        TypeName =  "NUMBER";
                        break;
                    case 267:
                        TypeName =  "RETURN";
                        break;
                    case 268:
                        TypeName =  "RIGHTCOMMON";
                        break;
                    case 269:
                        TypeName =  "WHILE";
                        break;
                    case 270:
                        TypeName =  "VOID";
                        break;
                    case 271:
                        TypeName =  "EOF";
                        break;
                    case 272:
                        TypeName =  "NONE";
                        break;
                    case 273:
                        TypeName =  "READ";
                        break;
                    case 274:
                        TypeName =  "WRITE";
                        break;
                }
            }

            toolTipContent.TypeContent.Text = TypeName;
            toolTipContent.IsArrayConent.Text = LogicalTreeNode.IsArray.ToString();
            toolTipContent.ArraySizeContent.Text = LogicalTreeNode.ArraySize.ToString();
            toolTipContent.LineNumberContent.Text = LogicalTreeNode.LineNum.ToString();

            toolTip.Background = Brushes.Transparent;
            toolTip.BorderThickness = new Thickness(0);
            toolTip.Content = toolTipContent;
            NodeName.ToolTip = toolTip;
            tempTreeNode.Content = NodeName;
            tempTreeNode.Name = "node" + treeNodeCount.ToString();
            return tempTreeNode;
        }
Пример #16
0
        /// <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;
        }
Пример #17
0
 /// <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;
 }
Пример #18
0
        /// <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;
        }
Пример #19
0
        /// <summary>
        ///  6. fun-declaration → type-specifier ID ( params )  compound-stmt
        /// </summary>
        /// <returns></returns>
        TreeNode FunDeclaration()
        {
            Word iToken = idNameToken as Word;
            TreeNode temp = new TreeNode(NodeKind.funK, (TokenType)typeToken.TokenTypes, iToken.Lexeme, currentToken.LineNumber, scope);
            TreeNode p = null;
            scope = iToken.Lexeme;
            p = temp.Child[0] = Params();

            if (p != null)
                p.Father = temp;
            //
            while (p != null && p.Sibling != null) {
                p = p.Sibling;
                p.Father = temp;
            }
            //scan->push();
            //--currentTokenIndex;//调了N久

            if (!Match(Convert.ToInt32(')')))
            {
                ErrorRecord(ParseErrorType.MissingRParenthesisInFunction);
                --currentTokenIndex;
                //error
                //scan->add_err();
                //sprintf(msg_temp,
                //    "Syntax error: missing \')\' in function %s(...) declaration",
                //    iToken.str.c_str());
                //outputMsg(scan->lineno(), msg_temp);
                //scan->push();

            }
            // compound statements
            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;
        }
Пример #20
0
        /// <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;
        }
Пример #21
0
 private void ErrorRecord(AnalyzerErrorType analyzerErrorType,TreeNode t)
 {
     ErrorBase.ErrorManager.AddAnalyzerError(new AnalyzerError( analyzerErrorType,t.LineNum, 0, t.Name) );
 }
Пример #22
0
        /// <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;
        }
Пример #23
0
        void Traverse2(TreeNode t)
        {
            if (t != null)
            {
                for (int i = 0; i < t.Child.Length; ++i)
                {
                    if (t.Child != null)
                        Traverse2( t.Child[i]);
                }

                CheckNode(t);
                Traverse2( t.Sibling);
            }
        }
Пример #24
0
        /// <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;
        }
Пример #25
0
 /// <summary>
 /// constructs the symbol table by preorder traversal of the syntax tree
 /// </summary>
 /// <param name="pNode"></param>
 public void BuildSymbolTable(TreeNode pNode)
 {
     traverse1(pNode);
 }
Пример #26
0
        /// <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;
        }
Пример #27
0
        /// <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;
        }
Пример #28
0
        /// <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;
        }
Пример #29
0
 private void SyntaxAnalysis(object sender, ExecutedRoutedEventArgs e)
 {
     LexicalAnalysis(sender, e);
     Parser parser = new Parser(tokenlist);
     root = parser.BuildSyntaxTree();
     if (ErrorManager.ErrorList.Count == 0)
     {
         error.Visibility = Visibility.Collapsed;
         SyntaxTree syntaxTree = new SyntaxTree();
         syntaxTree.CreatSyntaxTree(root);
         syntaxTree.Show();
     }
     else
     {
         error.Visibility = Visibility.Visible;
         dg.Visibility = Visibility.Collapsed;
         error.ItemsSource = null;
         error.ItemsSource = ErrorManager.ErrorList;
     }
 }
Пример #30
0
 /// <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;
 }