⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.cpp

📁 用C++语言在VC6.0环境下编写的小型c语言编译器
💻 CPP
字号:
// parser.cpp: implementation of the parser class.
//
//////////////////////////////////////////////////////////////////////

#include "parser.h"
#include"stdio.h"
#include"stdlib.h"
#include"iostream.h"
#include"string.h"
#include"token.h"
#include "fstream.h"
#include "ctype.h"
#include "scanner.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

parser::parser()
{   indentno=0;
	ftree=fopen(FILENAME2,"w");
   // token tok =ss.getToken()
}

parser::~parser()
{


}



Treenode * parser::newExpnode(Expkind kind)
{   Treenode * t=(Treenode *)malloc(sizeof(Treenode));
    int i;
	if(t==NULL)
	    fprintf(ftree,"out of memory error at line %d\n",tok.line);
    else {
		for(i=0;i<MAXCHILD;i++)  { t->child[i]=NULL;}
    t->sibling=NULL;
	t->nodekind=Expk;
    t->kind.exp=kind;
	t->lineno=tok.line;
	t->checktype=Void;
	}
	return t;
}

Treenode * parser::newStmtnode(Stmtkind kind)
{  Treenode * t=(Treenode *)malloc(sizeof(Treenode));
    int i;
	if(t==NULL)
	    fprintf(ftree,"out of memory error at line %d\n",tok.line);
    else {
		for(i=0;i<MAXCHILD;i++)  { t->child[i]=NULL;}
        t->sibling=NULL;
	    t->nodekind=Stmtk;
		t->kind.stmt=kind;
	    t->lineno=tok.line;
		
	}
	return t; 

}

char * parser::copystr(char *s)
{    int n;
     char *t;
	 if(s==NULL) return NULL;
	 n=strlen(s)+1;
	 t=(char *)malloc(n);
	 if(t==NULL)
         fprintf(ftree,"out of memory error at line %d\n",tok.line);  
	 else strcpy(t,s);
	 return t;

}

parser::printtree(Treenode *tree)
{
  indentno=indentno+2;
  while(tree!=NULL)
  {  for(int j=0;j<indentno;j++){ fprintf(ftree," ");}
     if(tree->nodekind==Stmtk)
	 {  switch (tree->kind.stmt)
	 { 
		   case Ifk:
			   fprintf(ftree,"If\n");
			   break;
		   case Repeatk:
               fprintf(ftree,"Repeatk\n");
			   break;
           case Assignk:
			   fprintf(ftree,"Assign to:  %s\n",tree->attr.name);
			   break;
           case Readk:
			   fprintf(ftree,"Read:  %s\n",tree->attr.name);
			   break;
           case Writek:
			   fprintf(ftree,"Write\n");
			   break;
		   default:
			   fprintf(ftree,"Unknown Expnode kind\n");
			   break;
	 }
	 }
     else if(tree->nodekind==Expk)
	 {  switch (tree->kind.exp)
	 { 
		   case Opk:
			   fprintf(ftree,"op\n");
			   ss.foutput(ftree,tree->attr.op,'\0');
			   break;
		   case Constk:
               fprintf(ftree,"Constk:  %d\n",tree->attr.val);
			   break;
           case Idk:
			   fprintf(ftree,"Id:  %s\n",tree->attr.name);
			   break;
		   default:
			   fprintf(ftree,"Unknown Expnode kind\n");
			   break;
	 }
	 }
     else   fprintf(ftree,"Unknown  node kind\n");
	 for (int i=0;i<MAXCHILD;i++)
	 {printtree(tree->child[i]);}
	 tree=tree->sibling;
  }//while
  indentno=indentno-2;
}



parser::syntaxerror(char *message)
{  fprintf(ftree,"\n>>>  ");
   fprintf(ftree,"syntax error at line %d",tok.line,message);
}

parser::match(TokenType expected)
{  if(tok.ttype==expected)  tok=ss.getToken();
   else {
	   syntaxerror("unexpected token->  ");
	   ss.foutput(ftree,tok.ttype,tok.str);
	   fprintf(ftree,"              ");
   }
}

Treenode * parser::stmt_sequence()
{   Treenode * t=statement();
    Treenode * p=t;
	while((tok.ttype!=ENDFILE)&&(tok.ttype!=END)&&(tok.ttype!=ELSE)&&(tok.ttype!=UNTIL))
	{  
		Treenode * q;
		match(SEMI);
		q=statement();
		if(q==NULL)
		{  if(t==NULL) t=p=q;
		   else
		   {p->sibling=q;
		    p=q;
		   }
		}
	}
	return t;
	cout<<"ok";
}


Treenode * parser::statement()
{
  Treenode * t=NULL;
  switch(tok.ttype)
  {  case IF: t=if_stmt(); break;
     case REPET: t=repeat_stmt(); break;
	 case ID: t=assign_stmt(); break;
	 case READ: t=read_stmt(); break;
	 case WRITE: t=write_stmt(); break;
	 default: 
		 syntaxerror("unexpected token->  ");
	     ss.foutput(ftree,tok.ttype,tok.str);
         tok=ss.getToken();
		 break;
  }
  return t;
  
}



Treenode * parser::if_stmt()
{
   Treenode * t=newStmtnode(Ifk);
   match(IF);
   if(t!=NULL) t->child[0]=exp();
   match(THEN);
   if(t!=NULL) t->child[1]=stmt_sequence();
   if(tok.ttype==ELSE)
   {match(ELSE);
    if(t!=NULL) t->child[2]=stmt_sequence();
   }
   match(END);
   return t;
}

Treenode * parser::repeat_stmt()
{ 
   Treenode * t=newStmtnode(Repeatk);
   match(REPEAT);
   if(t!=NULL) t->child[0]=stmt_sequence();
   match(UNTIL);
   if(t!=NULL) t->child[1]=exp();
   return t;  
}


Treenode * parser::assign_stmt()
{
   Treenode * t=newStmtnode(Assignk);
   if((t!=NULL)&&(tok.ttype==ID))
	   t->attr.name=copystr(tok.str);
   match(ID);
   match(ASSIGN);
   if(t!=NULL) t->child[0]=exp();
   return t; 
}

Treenode * parser::read_stmt()
{  Treenode * t=newStmtnode(Readk);
   match(READ);
   if((t!=NULL)&&(tok.ttype==ID))
	   t->attr.name=copystr(tok.str);
   match(ID);
   return t;
}

Treenode * parser::write_stmt()
{  Treenode * t=newStmtnode(Writek);
   match(WRITE);
   if(t!=NULL) t->child[0]=exp();
   return t;

}

Treenode * parser::exp()
{
   Treenode * t=simple_exp();
   if((tok.ttype==LT)||(tok.ttype==EQ)){
	   Treenode * p=newExpnode(Opk);
	   if(p!=NULL) {
		   p->child[0]=t;
		   p->attr.op=tok.ttype;
		   t=p;
	   }
	   match(tok.ttype);
	   if(t!=NULL)
		   t->child[1]=simple_exp();
   }
   return t;
}

Treenode * parser::simple_exp()
{   Treenode * t=term();
   while((tok.ttype==PLUS)||(tok.ttype==MINUS))
   {
	   Treenode * p=newExpnode(Opk);
	   if(p!=NULL) {
		   p->child[0]=t;
		   p->attr.op=tok.ttype;
		   t=p;
	       match(tok.ttype);
		   t->child[1]=term();
	   }
   }
   return t;
}

Treenode * parser::term()
{   Treenode * t=factor();
   while((tok.ttype==TIMES)||(tok.ttype==OVER))
   {
	   Treenode * p=newExpnode(Opk);
	   if(p!=NULL) {
		   p->child[0]=t;
		   p->attr.op=tok.ttype;
		   t=p;
	       match(tok.ttype);
		   t->child[1]=factor();
	   }
   }
   return t;
}

Treenode * parser::factor()
{   Treenode * t=NULL;
    switch (tok.ttype){
	case NUM:
		t=newExpnode(Constk);
		if((t!=NULL)&&(tok.ttype==NUM))
			t->attr.val=atoi(tok.str);
		match(NUM);
		break;
	case ID:
		t=newExpnode(Idk);
		if((t!=NULL)&&(tok.ttype==ID))
			t->attr.name=copystr(tok.str);
		match(ID);
		break;
    case LPAREN:
		match(LPAREN);
		t=exp();
		match(RPAREN);
		break;
	default:
		syntaxerror("unexpected token -> ");
		ss.foutput(ftree,tok.ttype,tok.str);
		tok=ss.getToken();
		break;
	}
	return t;
}

Treenode * parser::parse()
{   Treenode * t;
    token tok =ss.getToken();
    //cout<<tok.str;
	//ss.foutput(ftree,tok.ttype,tok.str);
	t=stmt_sequence();
	if(tok.ttype!=ENDFILE)
        syntaxerror("Code ends \n");
	return t;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -