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

📄 parse.cpp

📁 pascal的编译器 交作业没问题
💻 CPP
字号:
#include<stdlib.h>
#include<string.h>
#include "parse.h"

void Parse::Init(FILE *source)
{
     Error = FALSE;
	 indentno = 0;
	 scan.Init(source);
	 listing=scan.listing;
}
void Parse::syntaxError(char * message)
{
	fprintf(listing,"\n>>> ");
    fprintf(listing,"Syntax error at line %d: %s",scan.lineno,message);
    Error = TRUE;
}

void Parse::match(TokenType expected)    //如果匹配当前TOKEN,读下一个TOKEN
{
	if (scan.token.type == expected) scan.getToken();
    else {
        syntaxError("unexpected token -> ");
        fprintf(listing,"      ");
	}
}

TreeNode * Parse::stmt_sequence(void)
{
	TreeNode * t = statement();
    TreeNode * p = t;
    while ((scan.token.type!=ENDFILE) && (scan.token.type!=END) &&
         (scan.token.type!=ELSE) && (scan.token.type!=UNTIL))
	{
		TreeNode * q;
        match(SEMI);
        q = statement();
        if (q!=NULL) {
        if (t==NULL) t = p = q;
        else  
		{
			p->sibling = q;
            p = q;
		}
    }
  }
  return t;
}

TreeNode * Parse::statement(void)
{
	TreeNode * t = NULL;
    switch (scan.token.type)
	{
        case IF : t = if_stmt(); break;
        case REPEAT : 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 -> ");    
            scan.getToken();
            break;
	} 
    return t;
}

TreeNode * Parse::if_stmt(void)  //三个子节点,分别是condition,stmt,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 (scan.token.type==ELSE) {
        match(ELSE);
        if (t!=NULL) t->child[2] = stmt_sequence();
	}
    match(END);
    return t;
}

TreeNode * Parse::repeat_stmt(void)
{
	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 * Parse::assign_stmt(void)
{
	TreeNode * t = newStmtNode(AssignK);
    if ((t!=NULL) && (scan.token.type==ID))
    t->attr.name = Strcpy(scan.token.string);
    match(ID);
    match(ASSIGN);
    if (t!=NULL) t->child[0] = exp();
    return t;
}

TreeNode * Parse::read_stmt(void)
{
	TreeNode * t = newStmtNode(ReadK);
    match(READ);
    if ((t!=NULL) && (scan.token.type==ID))
    t->attr.name = Strcpy(scan.token.string);
    match(ID);
    return t;
}

TreeNode * Parse::write_stmt(void)
{
	TreeNode * t = newStmtNode(WriteK);
    match(WRITE);
    if (t!=NULL) t->child[0] = exp();
    return t;
}

TreeNode * Parse::exp(void)
{
	TreeNode * t = simple_exp();
    if ((scan.token.type==LT)||(scan.token.type==EQ)) {
    TreeNode * p = newExpNode(OpK);
    if (p!=NULL) {
      p->child[0] = t;
      p->attr.op =scan.token.type;
      t = p;
    }
    match(scan.token.type);
    if (t!=NULL)
      t->child[1] = simple_exp();
  }
  return t;
}

TreeNode * Parse::simple_exp(void)
{
	TreeNode * t = term();
    while ((scan.token.type==PLUS)||(scan.token.type==MINUS))
	{
		TreeNode * p = newExpNode(OpK);
        if (p!=NULL) {
           p->child[0] = t;
           p->attr.op = scan.token.type;
           t = p;
           match(scan.token.type);
           t->child[1] = term();
		}
	}
  return t;
}

TreeNode * Parse::term(void)
{
	TreeNode * t = factor();
    while ((scan.token.type==TIMES)||(scan.token.type==OVER))
	{
		TreeNode * p = newExpNode(OpK);
        if (p!=NULL) {
           p->child[0] = t;
           p->attr.op =scan.token.type;
           t = p;
           match(scan.token.type);
           p->child[1] = factor();
		}
	}
    return t;
}

TreeNode * Parse::factor(void)
{
	TreeNode * t = NULL;
    switch (scan.token.type)
	{
    case NUM :
      t = newExpNode(ConstK);
      if ((t!=NULL) && (scan.token.type==NUM))
        t->attr.val = atoi(scan.token.string);
      match(NUM);
      break;
    case ID :
      t = newExpNode(IdK);
      if ((t!=NULL) && (scan.token.type==ID))
        t->attr.name = Strcpy(scan.token.string);
      match(ID);
      break;
    case LPAREN :
      match(LPAREN);
      t = exp();
      match(RPAREN);
      break;
    default:
      syntaxError("unexpected token -> ");
      scan.getToken();
      break;
    }
  return t;
}

/****************************************/
void Parse::MyParse(void)               // 语法分析主函数  
{
	TreeNode * t;
    scan.getToken();
    t = stmt_sequence();
    if (scan.token.type!=ENDFILE)
       syntaxError("Code ends before file\n");
    syntaxTree=t;
}
/****************************************/
TreeNode * Parse::newStmtNode(StmtKind kind)
{
	TreeNode * t = new TreeNode();    //产生一个树节点
    int i;
    for (i=0;i<MAXCHILDREN;i++) t->child[i] = NULL;
    t->sibling = NULL;
    t->nodekind = StmtK;
    t->kind.stmt = kind;
    t->lineno = scan.lineno;
    return t;
}
TreeNode * Parse::newExpNode(ExpKind kind)
{
	TreeNode * t = new TreeNode();
    int i;
    for (i=0;i<MAXCHILDREN;i++) t->child[i] = NULL;
    t->sibling = NULL;
    t->nodekind = ExpK;
    t->kind.exp = kind;
    t->lineno = scan.lineno;
    t->type = Void;
    return t;
}
char * Parse::Strcpy(char * s)
{ 
    if (s==NULL) return NULL;
    char * t = new char[strlen(s)+1];
    strcpy(t,s);
    return t;
}
/****************************************/

void Parse::printTree( TreeNode * tree )
{
  int i;
  indentno+=2;
  while (tree != NULL) {
    printSpaces();
    if (tree->nodekind==StmtK)
    { switch (tree->kind.stmt) {
        case IfK:
          fprintf(listing,"If\n");
          break;
        case RepeatK:
          fprintf(listing,"Repeat\n");
          break;
        case AssignK:
          fprintf(listing,"Assign to: %s\n",tree->attr.name);
          break;
        case ReadK:
          fprintf(listing,"Read: %s\n",tree->attr.name);
          break;
        case WriteK:
          fprintf(listing,"Write\n");
          break;
        default:
          fprintf(listing,"Unknown ExpNode kind\n");
          break;
      }
    }
    else if (tree->nodekind==ExpK)
    { switch (tree->kind.exp) {
        case OpK:
          fprintf(listing,"Op: ");
          printToken(tree->attr.op,"\0");
          break;
        case ConstK:
          fprintf(listing,"Const: %d\n",tree->attr.val);
          break;
        case IdK:
          fprintf(listing,"Id: %s\n",tree->attr.name);
          break;
        default:
          fprintf(listing,"Unknown ExpNode kind\n");
          break;
      }
    }
    else fprintf(listing,"Unknown node kind\n");
    for (i=0;i<MAXCHILDREN;i++)
         printTree(tree->child[i]);
    tree = tree->sibling;
  }
  indentno-=2;
}
//---------------------------
void Parse::printToken( TokenType token, const char* tokenString )
{
   switch (token)
  {
	case IF:
    case THEN:
    case ELSE:
    case END:
    case REPEAT:
    case UNTIL:
    case READ:
    case WRITE:
      fprintf(listing,
         "reserved word: %s\n",tokenString);
      break;
    case ASSIGN: fprintf(listing,":=\n"); break;
    case LT: fprintf(listing,"<\n"); break;
    case EQ: fprintf(listing,"=\n"); break;
    case LPAREN: fprintf(listing,"(\n"); break;
    case RPAREN: fprintf(listing,")\n"); break;
    case SEMI: fprintf(listing,";\n"); break;
    case PLUS: fprintf(listing,"+\n"); break;
    case MINUS: fprintf(listing,"-\n"); break;
    case TIMES: fprintf(listing,"*\n"); break;
    case OVER: fprintf(listing,"/\n"); break;
    case ENDFILE: fprintf(listing,"EOF\n"); break;
    case NUM:
      fprintf(listing,
          "NUM, val= %s\n",tokenString);
      break;
    case ID:
      fprintf(listing,
          "ID, name= %s\n",tokenString);
      break;
    case ERROR:
      fprintf(listing,
          "ERROR: %s\n",tokenString);
	  Error=TRUE;
      break;
    default:  
      fprintf(listing,"Unknown token: %d\n",token);
  }
}
//------------
void Parse::printSpaces(void)
{
	int i;
    for (i=0;i<indentno;i++)
    fprintf(listing," ");
}

⌨️ 快捷键说明

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