📄 grammaranalysis.cpp
字号:
else
{
sprintf(buf, "行 %d: 常量声明错误\n", lineno);
msgOutPut(buf);
gerrLine = lineno;
if (ptokenid) free(ptokenid);
if (ptoken) free(ptoken);
if (ptokennum) free(ptokennum);
return phead;
}
}
sprintf(buf, "行 %d: 缺少标识符\n", lineno);
msgOutPut(buf);
gerrLine = lineno;
return phead;
}
/* 程序没有常量声明部分 */
return NULL;
}
/**
* 处理有关变量声明的程序部分
* 它将建立一个链表,指向程序中的变量序列
*/
static struct DecNode *PARSE_varDec(void)
{
struct DecNode *phead;
struct TokenType *ptoken;
int lineno;
phead = NULL;
if (ptoken = PARSE_match(VAR))
{
lineno = ptoken->lineno;
free(ptoken);
while (ptoken = PARSE_match(ID))
{
phead = PARSE_insert(phead, ptoken->lexval, PARSE_VAR, ptoken->lineno);
if (ptoken = PARSE_match(COMMA))
{
free(ptoken);
continue;
}
else if (ptoken = PARSE_match(COLON))
{
free(ptoken);
return phead;
}
else
{
sprintf(buf, "行 %d: 缺少逗号或分号\n", lineno);
msgOutPut(buf);
gerrLine = lineno;
return phead;
}
}
sprintf(buf, "行 %d: 缺少标识符\n", lineno);
msgOutPut(buf);
gerrLine = lineno;
return phead;
}
if (ptoken)
PARSE_ungetToken(ptoken);
/* 程序没有变量声明部分 */
return NULL;
}
/**
* 往常量或变量声明链表中插入常量声明或变量声明,
* 其中icval为PARSE_VAR的时候表示它是变量声明
*/
static struct DecNode *PARSE_insert(struct DecNode *phead, const char *id, int icval, int lineno)
{
struct DecNode *ptmp, *piter;
/**
* 先分配一个节点,然后将其内容全部赋值
* 节点的指定空间中去
*/
ptmp = (struct DecNode *)malloc(sizeof(struct DecNode));
if (ptmp == NULL)
{
printf("%s: %d\n", __FILE__, __LINE__);
exit(1);
}
strcpy(ptmp->idname, id);
ptmp->icval = icval;
ptmp->next= NULL;
ptmp->lineno = lineno;
/**
* 将以分配好的节点插入到链表phead的末尾。
*/
if (phead)
{
piter = phead;
while (piter->next)
{
piter = piter->next;
}
piter->next = ptmp;
return phead;
}
else
{
return ptmp;
}
}
/**
* 语句分析程序,根据源程序的第一个记号来决定程序应该使用
* 哪一个程序来进行分析。
*/
static struct TreeNode *PARSE_stmt(void)
{
struct TokenType *ptoken;
// ID开头表明是赋值语句
if (ptoken = PARSE_match(ID))
{
PARSE_ungetToken(ptoken);
free(ptoken);
return PARSE_assign();
}
// 关键字IF开头表明是条件语句
else if (ptoken = PARSE_match(IF))
{
PARSE_ungetToken(ptoken);
free(ptoken);
return PARSE_if();
}
// 关键字WHILE开头表明是循环语句
else if (ptoken = PARSE_match(WHILE))
{
PARSE_ungetToken(ptoken);
free(ptoken);
return PARSE_while();
}
// 关键字BEGIN开头表明是符合语句
else if (ptoken = PARSE_match(BEGIN))
{
PARSE_ungetToken(ptoken);
free(ptoken);
return PARSE_compound();
}
else
{
// 空语句
return NULL;
}
}
/**
* 分析赋值语句,依照文法依次匹配各个部分
*/
static struct TreeNode *PARSE_assign(void)
{
struct TreeNode *phead = PARSE_newTreeNode();
struct TokenType *ptoken;
int lineno;
phead->kind = STMT;
phead->subKind.stmt = ASSIGNSTMT;
ptoken = PARSE_match(ID);
if (ptoken)
{
strcpy(phead->attr.idname, ptoken->lexval);
}
else
{
printf("%s: %d\n", __FILE__, __LINE__);
exit(1);
}
phead->lineno = ptoken->lineno;
lineno = ptoken->lineno;
free(ptoken);
if (ptoken = PARSE_match(ASSIGN))
{
free(ptoken);
}
else
{
sprintf(buf, "行 %d: 缺少赋值号\n", lineno);
msgOutPut(buf);
gerrLine = lineno;
free(phead);
return NULL;
}
phead->child[0] = PARSE_expr();
return phead;
}
/**
* 分析条件语句,依照文法依次匹配各个部分
*/
static struct TreeNode *PARSE_if(void)
{
struct TreeNode *phead = PARSE_newTreeNode();
struct TokenType *ptoken;
int lineno;
phead->kind = STMT;
phead->subKind.stmt = IFSTMT;
ptoken = PARSE_match(IF);
lineno = ptoken->lineno;
free(ptoken);
phead->child[0] = PARSE_relationExpr();
if (gerrLine != -1) return phead;
if (ptoken = PARSE_match(THEN))
{
free(ptoken);
}
else
{
sprintf(buf, "行 %d: 缺少关键字then\n", lineno);
msgOutPut(buf);
gerrLine = lineno;
return phead;
}
phead->child[1] = PARSE_stmt();
if (gerrLine != -1)
{
return phead;
}
if (ptoken = PARSE_match(ELSE))
{
free(ptoken);
phead->child[2] = PARSE_stmt();
}
return phead;
}
/**
* 分析循环语句,依照文法依次匹配各个部分
*/
static struct TreeNode *PARSE_while(void)
{
struct TreeNode *phead = PARSE_newTreeNode();
struct TokenType *ptoken;
int lineno;
phead->kind = STMT;
phead->subKind.stmt = WHILESTMT;
ptoken = PARSE_match(WHILE);
lineno = ptoken->lineno;
free(ptoken);
phead->child[0] = PARSE_relationExpr();
if (gerrLine != -1)
{
return phead;
}
if (ptoken = PARSE_match(DO))
{
free(ptoken);
}
else
{
sprintf(buf, "行 %d: 缺少关键字do\n", lineno);
msgOutPut(buf);
gerrLine = lineno;
return phead;
}
phead->child[1] = PARSE_stmt();
return phead;
}
/**
* 分析复合语句,依照文法依次匹配各个部分
*/
static struct TreeNode *PARSE_compound(void)
{
struct TreeNode *ptmp, *phead;
struct TokenType *ptoken;
int lineno;
ptoken = PARSE_match(BEGIN);
lineno = ptoken->lineno;
free(ptoken);
phead = PARSE_stmt();
if (gerrLine != -1)
{
return phead;
}
while (ptoken = PARSE_match(COLON))
{
/* 表明还有下一条语句 */
ptmp = phead;
while (ptmp->sib)
{
ptmp = ptmp->sib;
}
ptmp->sib = PARSE_stmt();
if (gerrLine != -1)
{
return phead;
}
}
if (ptoken = PARSE_match(END))
{
free(ptoken);
}
else
{
sprintf(buf, "行 %d: 缺少关键字end\n", lineno);
msgOutPut(buf);
gerrLine = lineno;
}
return phead;
}
/*******************************************************************/
/**
* 往文件流中输出phead指向的表达式
*/
static void PARSE_printExpr(struct TreeNode *phead)
{
if (phead)
{
parseOutPut("(");
PARSE_printExpr(phead->child[0]);
if (phead->subKind.exp == OPEXP)
{
switch (phead->attr.op)
{
case ADD:
parseOutPut("+");
break;
case SUB:
parseOutPut("-");
break;
case MUL:
parseOutPut("*");
break;
case DIV:
parseOutPut("/");
break;
default:
printf("%s: %d\n", __FILE__, __LINE__);
exit(1);
}
}
else if (phead->subKind.exp == REALEXP)
{
switch (phead->attr.op)
{
case EQ:
parseOutPut("==");
break;
case NE:
parseOutPut("<>");
break;
case LT:
parseOutPut("<");
break;
case LE:
parseOutPut("<=");
break;
case GT:
parseOutPut(">");
break;
case GE:
parseOutPut(">=");
break;
default:
printf("%s: %d\n", __FILE__, __LINE__);
exit(1);
}
}
else if (phead->subKind.exp == CONSTEXP)
{
memset(buf, 0, sizeof(buf));
sprintf(buf, "%d", phead->attr.val);
parseOutPut(buf);
}
else if (phead->subKind.exp == IDEXP)
{
memset(buf, 0, sizeof(buf));
sprintf(buf, "%s", phead->attr.idname);
parseOutPut(buf);
}
else
{
printf("%s: %d\n", __FILE__, __LINE__);
exit(1);
}
PARSE_printExpr(phead->child[1]);
parseOutPut(")");
}
}
void PARSE_empty(int indent)
{
int i;
for (i = 0; i < indent; i++)
parseOutPut(" ");
}
void PARSE_printConstDec(struct DecNode *pconst, int indent)
{
PARSE_empty(indent);
parseOutPut("const declare\n");
indent += 4;
while (pconst)
{
PARSE_empty(indent);
memset(buf, 0, sizeof(buf));
sprintf(buf, "%s = %d\n", pconst->idname, pconst->icval);
parseOutPut(buf);
pconst = pconst->next;
}
}
void PARSE_printVarDec(struct DecNode *pvar, int indent)
{
PARSE_empty(indent);
parseOutPut("var declare\n");
indent += 4;
while (pvar)
{
PARSE_empty(indent);
memset(buf, 0, sizeof(buf));
sprintf(buf, "%s\n", pvar->idname);
parseOutPut(buf);
pvar = pvar->next;
}
}
void PARSE_printStmt(struct TreeNode *stmt, int indent)
{
int indent2 = indent;
PARSE_empty(indent2);
parseOutPut("stmt begin\n");
if (stmt)
{
indent += INDENTADD;
while (stmt)
{
switch (stmt->subKind.stmt)
{
case ASSIGNSTMT:
PARSE_empty(indent);
parseOutPut("assign stmt\n");
PARSE_empty(indent + INDENTADD);
memset(buf, 0, sizeof(buf));
sprintf(buf, "%s = ", stmt->attr.idname);
parseOutPut(buf);
PARSE_printExpr(stmt->child[0]);
parseOutPut("\n");
break;
case IFSTMT:
PARSE_empty(indent);
memset(buf, 0, sizeof(buf));
parseOutPut("if stmt\n");
PARSE_empty(indent + INDENTADD);
PARSE_printExpr(stmt->child[0]);
parseOutPut("\n");
PARSE_printStmt(stmt->child[1], indent + INDENTADD);
if (stmt->child[2])
{
PARSE_printStmt(stmt->child[2], indent + INDENTADD);
}
parseOutPut("\n");
break;
case WHILESTMT:
PARSE_empty(indent);
parseOutPut("while stmt\n");
PARSE_empty(indent + INDENTADD);
PARSE_printExpr(stmt->child[0]);
parseOutPut("\n");
PARSE_printStmt(stmt->child[1], indent + INDENTADD);
parseOutPut("\n");
break;
default:
printf("%s: %d\n", __FILE__, __LINE__);
exit(1);
}
stmt = stmt->sib;
}
}
PARSE_empty(indent2);
parseOutPut("stmt end\n");
}
/*
* 打印函数,将语法树打印到程序指定的文件中去
*/
void PARSE_printSyntaxTree(struct SyntaxTree *ptree)
{
int indent = INDENTADD;
parseOutPut("Syntax Tree\n");
PARSE_printConstDec(ptree->pconstDec, 4);
PARSE_printVarDec(ptree->pvarDec, 4);
PARSE_printStmt(ptree->pstmt, 4);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -