📄 parse.cpp
字号:
/*函数名的结点也用表达式类型结点*/
TreeNode * child0 = newExpNode(VariK);
if(child0!=NULL)
{
child0->lineno = line0;
strcpy(child0->name[0],temp_name);
(child0->idnum)++;
t->child[0] = child0;
}
t->child[1] = actParamList();
}
match(RPAREN);
return t;
}
/********************************************************************/
/* 函数名 actParamList */
/* 功 能 函数调用实参部分的处理函数 */
/* 产生式 < actParamList > ::= ε | exp actParamMore */
/* 说 明 函数根据文法产生式,调用相应的递归处理函数,生成语法树节点 */
/********************************************************************/
TreeNode * actParamList(void)
{
TreeNode * t = NULL;
switch(token.Lex)
{
case RPAREN: break;
case ID:
case INTC:
t =exp();
if(t!=NULL)
t->sibling = actParamMore();
break;
default:
ReadNextToken(&token);
syntaxError("unexpected token is here!");
break;
}
return t;
}
/********************************************************************/
/* 函数名 actParamMore */
/* 功 能 函数调用实参部分的处理函数 */
/* 产生式 < actParamMore > ::= ε | , actParamList */
/* 说 明 函数根据文法产生式,调用相应的递归处理函数,生成语法树节点 */
/********************************************************************/
TreeNode * actParamMore(void)
{
TreeNode * t = NULL;
switch(token.Lex)
{
case RPAREN: break;
case COMMA:
match(COMMA);
t = actParamList();
break;
default:
ReadNextToken(&token);
syntaxError("unexpected token is here!");
break;
}
return t;
}
/*************************表达式部分********************************/
/****************************************************************************/
/* 函数名 exp */
/* 功 能 表达式处理函数 */
/* 产生式 < 表达式 > ::= < 简单表达式 > [< 关系运算符 > < 简单表达式 > ] */
/* 说 明 该函数根据产生式调用相应递归处理函数,生成表达式类型语法树节点 */
/****************************************************************************/
TreeNode * exp(void)
{
/* 调用简单表达式处理函数simple_exp(),返回语法树节点指针给t */
TreeNode * t = simple_exp();
/* 当前单词token为逻辑运算单词LT或者EQ */
if ((token.Lex==LT)||(token.Lex==EQ))
{
/* 创建新的OpK类型语法树节点,新语法树节点指针赋给p */
TreeNode * p = newExpNode(OpK);
/* 新语法树节点p创建成功,初始化p第一个子节点成员child[0]
* 并将当前单词token(为EQ或者LT)赋给语法树节点p的运算符成员attr.op*/
if (p!=NULL)
{
p->lineno = line0;
p->child[0] = t;
p->attr.ExpAttr.op = token.Lex;
/* 将新的表达式类型语法树节点p作为函数返回值t */
t = p;
}
/* 当前单词token与指定逻辑运算符单词(为EQ或者LT)匹配 */
match(token.Lex);
/* 语法树节点t非空,调用简单表达式处理函数simple_exp() *
* 函数返回语法树节点指针给t的第二子节点成员child[1] */
if (t!=NULL)
t->child[1] = simple_exp();
}
/* 函数返回表达式类型语法树节点t */
return t;
}
/************************************************************************/
/* 函数名 simple_exp */
/* 功 能 简单表达式处理函数 */
/* 产生式 < 简单表达式 >::= < 项 > { < 加法运算符 > < 项 > } */
/* 说 明 该函数根据产生式调用相应递归处理函数,生成表达式类型语法树节点 */
/************************************************************************/
TreeNode * simple_exp(void)
{
/* 调用元处理函数term(),函数返回语法树节点指针给t */
TreeNode * t = term();
/* 当前单词token为加法运算符单词PLUS或MINUS */
while ((token.Lex==PLUS)||(token.Lex==MINUS))
{
/* 创建新OpK表达式类型语法树节点,新语法树节点指针赋给p */
TreeNode * p = newExpNode(OpK);
/* 语法树节点p创建成功,初始化p第一子节点成员child[0] *
* 返回语法树节点指针给p的运算符成员attr.op */
if (p!=NULL)
{
p->lineno = line0;
p->child[0] = t;
p->attr.ExpAttr.op = token.Lex;
/* 将函数返回值t赋成语法树节点p */
t = p;
/* 当前单词token与指定加法运算单词(为PLUS或MINUS)匹配 */
match(token.Lex);
/* 调用元处理函数term(),函数返回语法树节点指针给t的第二子节点成员child[1] */
t->child[1] = term();
}
}
/* 函数返回表达式类型语法树节点t */
return t;
}
/****************************************************************************/
/* 函数名 term */
/* 功 能 项处理函数 */
/* 产生式 < 项 > ::= < 因子 > { < 乘法运算符 > < 因子 > } */
/* 说 明 该函数根据产生式调用相应递归处理函数,生成表达式类型语法树节点 */
/****************************************************************************/
TreeNode * term(void)
{
/* 调用因子处理函数factor(),函数返回语法树节点指针给t */
TreeNode * t = factor();
/* 当前单词token为乘法运算符单词TIMES或OVER */
while ((token.Lex==TIMES)||(token.Lex==OVER))
{
/* 创建新的OpK表达式类型语法树节点,新节点指针赋给p */
treeNode * p = newExpNode(OpK);
/* 新语法树节点p创建成功,初始化第一个子节点成员child[0]为t *
* 将当前单词token赋值给语法树节点p的运算符成员attr.op */
if (p!=NULL)
{
p->lineno= line0;
p->child[0] = t;
p->attr.ExpAttr.op = token.Lex;
t = p;
}
/* 当前单词token与指定乘法运算符单词(为TIMES或OVER)匹配 */
match(token.Lex);
/* 调用因子处理函数factor(),函数返回语法树节点指针赋给p第二个子节点成员child[1] */
p->child[1] = factor();
}
/* 函数返回表达式类型语法树节点t */
return t;
}
/****************************************************************************/
/* 函数名 factor */
/* 功 能 因子处理函数 */
/* 产生式 factor ::= ( exp ) | INTC | variable */
/* 说 明 该函数根据产生式调用相应的递归处理函数,生成表达式类型语法树节点 */
/****************************************************************************/
TreeNode * factor(void)
{
/* 函数返回语法树节点指针t初始为为NULL */
TreeNode * t = NULL;
switch (token.Lex)
{
case INTC :
/* 创建新的ConstK表达式类型语法树节点,赋值给t */
t = newExpNode(ConstK);
/* 新语法树节点t创建成功,当前单词token为数字单词NUM *
* 将当前单词名tokenString转换为整数并赋给语法树节点t的数值成员attr.val */
if ((t!=NULL) && (token.Lex==INTC))
{
t->lineno = line0;
t->attr.ExpAttr.val = atoi(token.Sem);
}
/* 当前单词token与数字单词NUM匹配 */
match(INTC);
break;
/* 当前单词token为标识符单词ID */
case ID :
/* 创建新的IdK表达式类型语法树节点t */
t = variable();
break;
/* 当前单词token为左括号单词LPAREN */
case LPAREN :
/* 当前单词token与左括号单词LPAREN匹配 */
match(LPAREN);
/* 调用表达式处理函数exp(),函数返回语法树节点指针给t */
t = exp();
/* 当前单词token与右括号单词RPAREN匹配 */
match(RPAREN);
break;
/* 当前单词token为其它单词 */
default:
ReadNextToken(&token);
syntaxError("unexpected token is here!");
break;
}
/* 函数返回表达式类型语法树节点t */
return t;
}
/********************************************************************/
/* 函数名 variable */
/* 功 能 变量处理函数 */
/* 产生式 variable ::= id variMore */
/* 说 明 该函数根据产生式, 处理变量,生成其语法树节点 */
/********************************************************************/
TreeNode * variable(void)
{
TreeNode * t = newExpNode(VariK);
if ((t!=NULL) && (token.Lex==ID))
{
t->lineno = line0;
strcpy(t->name[0] ,token.Sem);
(t->idnum)++;
}
match(ID);
variMore(t);
return t;
}
/********************************************************************/
/* 函数名 variMore */
/* 功 能 变量处理函数 */
/* 产生式 variMore ::= ε */
/* | [exp] {[} */
/* | . fieldvar {DOT} */
/* 说 明 该函数根据产生式调用相应的递归处理变量中的几种不同类型 */
/********************************************************************/
void variMore(TreeNode * t)
{
switch(token.Lex)
{
case ASSIGN:
case TIMES:
case EQ:
case LT:
case PLUS:
case MINUS:
case OVER:
case RPAREN:
case RMIDPAREN:
case SEMI:
case COMMA:
case THEN:
case ELSE:
case FI:
case DO:
case ENDWH:
case END:
break;
case LMIDPAREN:
match(LMIDPAREN);
/*用来以后求出其表达式的值,送入用于数组下标计算*/
t->child[0] = exp();
t->attr.ExpAttr.varkind = ArrayMembV;
/*此表达式为数组成员变量类型*/
t->child[0]->attr.ExpAttr.varkind = IdV;
match(RMIDPAREN);
break;
case DOT:
match(DOT);
/*第一个儿子指向域成员变量结点*/
t->child[0] = fieldvar();
t->attr.ExpAttr.varkind = FieldMembV;
t->child[0]->attr.ExpAttr.varkind = IdV;
break;
default:
ReadNextToken(&token);
syntaxError("unexpected token is here!");
break;
}
}
/********************************************************************/
/* 函数名 fieldvar */
/* 功 能 变量处理函数 */
/* 产生式 fieldvar ::= id fieldvarMore */
/* 说 明 该函数根据产生式,处理域变量,并生成其语法树节点 */
/********************************************************************/
TreeNode * fieldvar(void)
{
/*注意,可否将此处的IdEK改为一个新的标识,用来记录记录类型的域*/
TreeNode * t = newExpNode(VariK);
if ((t!=NULL) && (token.Lex==ID))
{
t->lineno = line0;
strcpy(t->name[0] ,token.Sem);
(t->idnum)++;
}
match(ID);
fieldvarMore(t);
return t;
}
/********************************************************************/
/* 函数名 fieldvarMore */
/* 功 能 变量处理函数 */
/* 产生式 fieldvarMore ::= ε */
/* | [exp] {[} */
/* 说 明 该函数根据产生式调用相应的递归处理域变量为数组类型的情况 */
/********************************************************************/
void fieldvarMore(TreeNode * t )
{
switch(token.Lex)
{
case ASSIGN:
case TIMES:
case EQ:
case LT:
case PLUS:
case MINUS:
case OVER:
case RPAREN:
case SEMI:
case COMMA:
case THEN:
case ELSE:
case FI:
case DO:
case ENDWH:
case END:
break;
case LMIDPAREN:
match(LMIDPAREN);
/*用来以后求出其表达式的值,送入用于数组下标计算*/
t->child[0] = exp();
t->child[0]->attr.ExpAttr.varkind = ArrayMembV;
match(RMIDPAREN);
break;
default:
ReadNextToken(&token);
syntaxError("unexpected token is here!");
break;
}
}
/********************************************************************/
/* 函数名 parse */
/* 功 能 语法分析函数 */
/* 说 明 该函数把词法分析程序作为子程序调用,采用递归下降法 */
/* 根据产生式调用递归处理函数,函数为源程序创建语法分析树 */
/********************************************************************/
TreeNode * parse(void)
{
TreeNode * t=NULL;
/* 从文件Tokenlist中取得第一个单词,将词法信息送给token */
ReadNextToken(&token);
/* 开始调用基本语法分析处理函数,递归下降处理 */
t = program();
/* 当前单词token不是ENDFILE,报代码在文件结束前提前结束错误 */
if (token.Lex!=ENDFILE)
syntaxError("Code ends before file\n");
/* 函数返回语法树根节点t */
return t;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -