📄 parse.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 + -