?? parse.cpp
字號(hào):
/*函數(shù)名的結(jié)點(diǎn)也用表達(dá)式類型結(jié)點(diǎn)*/
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;
}
/********************************************************************/
/* 函數(shù)名 actParamList */
/* 功 能 函數(shù)調(diào)用實(shí)參部分的處理函數(shù) */
/* 產(chǎn)生式 < actParamList > ::= ε | exp actParamMore */
/* 說(shuō) 明 函數(shù)根據(jù)文法產(chǎn)生式,調(diào)用相應(yīng)的遞歸處理函數(shù),生成語(yǔ)法樹(shù)節(jié)點(diǎn) */
/********************************************************************/
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;
}
/********************************************************************/
/* 函數(shù)名 actParamMore */
/* 功 能 函數(shù)調(diào)用實(shí)參部分的處理函數(shù) */
/* 產(chǎn)生式 < actParamMore > ::= ε | , actParamList */
/* 說(shuō) 明 函數(shù)根據(jù)文法產(chǎn)生式,調(diào)用相應(yīng)的遞歸處理函數(shù),生成語(yǔ)法樹(shù)節(jié)點(diǎn) */
/********************************************************************/
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;
}
/*************************表達(dá)式部分********************************/
/****************************************************************************/
/* 函數(shù)名 exp */
/* 功 能 表達(dá)式處理函數(shù) */
/* 產(chǎn)生式 < 表達(dá)式 > ::= < 簡(jiǎn)單表達(dá)式 > [< 關(guān)系運(yùn)算符 > < 簡(jiǎn)單表達(dá)式 > ] */
/* 說(shuō) 明 該函數(shù)根據(jù)產(chǎn)生式調(diào)用相應(yīng)遞歸處理函數(shù),生成表達(dá)式類型語(yǔ)法樹(shù)節(jié)點(diǎn) */
/****************************************************************************/
TreeNode * exp(void)
{
/* 調(diào)用簡(jiǎn)單表達(dá)式處理函數(shù)simple_exp(),返回語(yǔ)法樹(shù)節(jié)點(diǎn)指針給t */
TreeNode * t = simple_exp();
/* 當(dāng)前單詞token為邏輯運(yùn)算單詞LT或者EQ */
if ((token.Lex==LT)||(token.Lex==EQ))
{
/* 創(chuàng)建新的OpK類型語(yǔ)法樹(shù)節(jié)點(diǎn),新語(yǔ)法樹(shù)節(jié)點(diǎn)指針賦給p */
TreeNode * p = newExpNode(OpK);
/* 新語(yǔ)法樹(shù)節(jié)點(diǎn)p創(chuàng)建成功,初始化p第一個(gè)子節(jié)點(diǎn)成員child[0]
* 并將當(dāng)前單詞token(為EQ或者LT)賦給語(yǔ)法樹(shù)節(jié)點(diǎn)p的運(yùn)算符成員attr.op*/
if (p!=NULL)
{
p->lineno = line0;
p->child[0] = t;
p->attr.ExpAttr.op = token.Lex;
/* 將新的表達(dá)式類型語(yǔ)法樹(shù)節(jié)點(diǎn)p作為函數(shù)返回值t */
t = p;
}
/* 當(dāng)前單詞token與指定邏輯運(yùn)算符單詞(為EQ或者LT)匹配 */
match(token.Lex);
/* 語(yǔ)法樹(shù)節(jié)點(diǎn)t非空,調(diào)用簡(jiǎn)單表達(dá)式處理函數(shù)simple_exp() *
* 函數(shù)返回語(yǔ)法樹(shù)節(jié)點(diǎn)指針給t的第二子節(jié)點(diǎn)成員child[1] */
if (t!=NULL)
t->child[1] = simple_exp();
}
/* 函數(shù)返回表達(dá)式類型語(yǔ)法樹(shù)節(jié)點(diǎn)t */
return t;
}
/************************************************************************/
/* 函數(shù)名 simple_exp */
/* 功 能 簡(jiǎn)單表達(dá)式處理函數(shù) */
/* 產(chǎn)生式 < 簡(jiǎn)單表達(dá)式 >::= < 項(xiàng) > { < 加法運(yùn)算符 > < 項(xiàng) > } */
/* 說(shuō) 明 該函數(shù)根據(jù)產(chǎn)生式調(diào)用相應(yīng)遞歸處理函數(shù),生成表達(dá)式類型語(yǔ)法樹(shù)節(jié)點(diǎn) */
/************************************************************************/
TreeNode * simple_exp(void)
{
/* 調(diào)用元處理函數(shù)term(),函數(shù)返回語(yǔ)法樹(shù)節(jié)點(diǎn)指針給t */
TreeNode * t = term();
/* 當(dāng)前單詞token為加法運(yùn)算符單詞PLUS或MINUS */
while ((token.Lex==PLUS)||(token.Lex==MINUS))
{
/* 創(chuàng)建新OpK表達(dá)式類型語(yǔ)法樹(shù)節(jié)點(diǎn),新語(yǔ)法樹(shù)節(jié)點(diǎn)指針賦給p */
TreeNode * p = newExpNode(OpK);
/* 語(yǔ)法樹(shù)節(jié)點(diǎn)p創(chuàng)建成功,初始化p第一子節(jié)點(diǎn)成員child[0] *
* 返回語(yǔ)法樹(shù)節(jié)點(diǎn)指針給p的運(yùn)算符成員attr.op */
if (p!=NULL)
{
p->lineno = line0;
p->child[0] = t;
p->attr.ExpAttr.op = token.Lex;
/* 將函數(shù)返回值t賦成語(yǔ)法樹(shù)節(jié)點(diǎn)p */
t = p;
/* 當(dāng)前單詞token與指定加法運(yùn)算單詞(為PLUS或MINUS)匹配 */
match(token.Lex);
/* 調(diào)用元處理函數(shù)term(),函數(shù)返回語(yǔ)法樹(shù)節(jié)點(diǎn)指針給t的第二子節(jié)點(diǎn)成員child[1] */
t->child[1] = term();
}
}
/* 函數(shù)返回表達(dá)式類型語(yǔ)法樹(shù)節(jié)點(diǎn)t */
return t;
}
/****************************************************************************/
/* 函數(shù)名 term */
/* 功 能 項(xiàng)處理函數(shù) */
/* 產(chǎn)生式 < 項(xiàng) > ::= < 因子 > { < 乘法運(yùn)算符 > < 因子 > } */
/* 說(shuō) 明 該函數(shù)根據(jù)產(chǎn)生式調(diào)用相應(yīng)遞歸處理函數(shù),生成表達(dá)式類型語(yǔ)法樹(shù)節(jié)點(diǎn) */
/****************************************************************************/
TreeNode * term(void)
{
/* 調(diào)用因子處理函數(shù)factor(),函數(shù)返回語(yǔ)法樹(shù)節(jié)點(diǎn)指針給t */
TreeNode * t = factor();
/* 當(dāng)前單詞token為乘法運(yùn)算符單詞TIMES或OVER */
while ((token.Lex==TIMES)||(token.Lex==OVER))
{
/* 創(chuàng)建新的OpK表達(dá)式類型語(yǔ)法樹(shù)節(jié)點(diǎn),新節(jié)點(diǎn)指針賦給p */
treeNode * p = newExpNode(OpK);
/* 新語(yǔ)法樹(shù)節(jié)點(diǎn)p創(chuàng)建成功,初始化第一個(gè)子節(jié)點(diǎn)成員child[0]為t *
* 將當(dāng)前單詞token賦值給語(yǔ)法樹(shù)節(jié)點(diǎn)p的運(yùn)算符成員attr.op */
if (p!=NULL)
{
p->lineno= line0;
p->child[0] = t;
p->attr.ExpAttr.op = token.Lex;
t = p;
}
/* 當(dāng)前單詞token與指定乘法運(yùn)算符單詞(為TIMES或OVER)匹配 */
match(token.Lex);
/* 調(diào)用因子處理函數(shù)factor(),函數(shù)返回語(yǔ)法樹(shù)節(jié)點(diǎn)指針賦給p第二個(gè)子節(jié)點(diǎn)成員child[1] */
p->child[1] = factor();
}
/* 函數(shù)返回表達(dá)式類型語(yǔ)法樹(shù)節(jié)點(diǎn)t */
return t;
}
/****************************************************************************/
/* 函數(shù)名 factor */
/* 功 能 因子處理函數(shù) */
/* 產(chǎn)生式 factor ::= ( exp ) | INTC | variable */
/* 說(shuō) 明 該函數(shù)根據(jù)產(chǎn)生式調(diào)用相應(yīng)的遞歸處理函數(shù),生成表達(dá)式類型語(yǔ)法樹(shù)節(jié)點(diǎn) */
/****************************************************************************/
TreeNode * factor(void)
{
/* 函數(shù)返回語(yǔ)法樹(shù)節(jié)點(diǎn)指針t初始為為NULL */
TreeNode * t = NULL;
switch (token.Lex)
{
case INTC :
/* 創(chuàng)建新的ConstK表達(dá)式類型語(yǔ)法樹(shù)節(jié)點(diǎn),賦值給t */
t = newExpNode(ConstK);
/* 新語(yǔ)法樹(shù)節(jié)點(diǎn)t創(chuàng)建成功,當(dāng)前單詞token為數(shù)字單詞NUM *
* 將當(dāng)前單詞名tokenString轉(zhuǎn)換為整數(shù)并賦給語(yǔ)法樹(shù)節(jié)點(diǎn)t的數(shù)值成員attr.val */
if ((t!=NULL) && (token.Lex==INTC))
{
t->lineno = line0;
t->attr.ExpAttr.val = atoi(token.Sem);
}
/* 當(dāng)前單詞token與數(shù)字單詞NUM匹配 */
match(INTC);
break;
/* 當(dāng)前單詞token為標(biāo)識(shí)符單詞ID */
case ID :
/* 創(chuàng)建新的IdK表達(dá)式類型語(yǔ)法樹(shù)節(jié)點(diǎn)t */
t = variable();
break;
/* 當(dāng)前單詞token為左括號(hào)單詞LPAREN */
case LPAREN :
/* 當(dāng)前單詞token與左括號(hào)單詞LPAREN匹配 */
match(LPAREN);
/* 調(diào)用表達(dá)式處理函數(shù)exp(),函數(shù)返回語(yǔ)法樹(shù)節(jié)點(diǎn)指針給t */
t = exp();
/* 當(dāng)前單詞token與右括號(hào)單詞RPAREN匹配 */
match(RPAREN);
break;
/* 當(dāng)前單詞token為其它單詞 */
default:
ReadNextToken(&token);
syntaxError("unexpected token is here!");
break;
}
/* 函數(shù)返回表達(dá)式類型語(yǔ)法樹(shù)節(jié)點(diǎn)t */
return t;
}
/********************************************************************/
/* 函數(shù)名 variable */
/* 功 能 變量處理函數(shù) */
/* 產(chǎn)生式 variable ::= id variMore */
/* 說(shuō) 明 該函數(shù)根據(jù)產(chǎn)生式, 處理變量,生成其語(yǔ)法樹(shù)節(jié)點(diǎn) */
/********************************************************************/
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;
}
/********************************************************************/
/* 函數(shù)名 variMore */
/* 功 能 變量處理函數(shù) */
/* 產(chǎn)生式 variMore ::= ε */
/* | [exp] {[} */
/* | . fieldvar {DOT} */
/* 說(shuō) 明 該函數(shù)根據(jù)產(chǎn)生式調(diào)用相應(yīng)的遞歸處理變量中的幾種不同類型 */
/********************************************************************/
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);
/*用來(lái)以后求出其表達(dá)式的值,送入用于數(shù)組下標(biāo)計(jì)算*/
t->child[0] = exp();
t->attr.ExpAttr.varkind = ArrayMembV;
/*此表達(dá)式為數(shù)組成員變量類型*/
t->child[0]->attr.ExpAttr.varkind = IdV;
match(RMIDPAREN);
break;
case DOT:
match(DOT);
/*第一個(gè)兒子指向域成員變量結(jié)點(diǎn)*/
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;
}
}
/********************************************************************/
/* 函數(shù)名 fieldvar */
/* 功 能 變量處理函數(shù) */
/* 產(chǎn)生式 fieldvar ::= id fieldvarMore */
/* 說(shuō) 明 該函數(shù)根據(jù)產(chǎn)生式,處理域變量,并生成其語(yǔ)法樹(shù)節(jié)點(diǎn) */
/********************************************************************/
TreeNode * fieldvar(void)
{
/*注意,可否將此處的IdEK改為一個(gè)新的標(biāo)識(shí),用來(lái)記錄記錄類型的域*/
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;
}
/********************************************************************/
/* 函數(shù)名 fieldvarMore */
/* 功 能 變量處理函數(shù) */
/* 產(chǎn)生式 fieldvarMore ::= ε */
/* | [exp] {[} */
/* 說(shuō) 明 該函數(shù)根據(jù)產(chǎn)生式調(diào)用相應(yīng)的遞歸處理域變量為數(shù)組類型的情況 */
/********************************************************************/
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);
/*用來(lái)以后求出其表達(dá)式的值,送入用于數(shù)組下標(biāo)計(jì)算*/
t->child[0] = exp();
t->child[0]->attr.ExpAttr.varkind = ArrayMembV;
match(RMIDPAREN);
break;
default:
ReadNextToken(&token);
syntaxError("unexpected token is here!");
break;
}
}
/********************************************************************/
/* 函數(shù)名 parse */
/* 功 能 語(yǔ)法分析函數(shù) */
/* 說(shuō) 明 該函數(shù)把詞法分析程序作為子程序調(diào)用,采用遞歸下降法 */
/* 根據(jù)產(chǎn)生式調(diào)用遞歸處理函數(shù),函數(shù)為源程序創(chuàng)建語(yǔ)法分析樹(shù) */
/********************************************************************/
TreeNode * parse(void)
{
TreeNode * t=NULL;
/* 從文件Tokenlist中取得第一個(gè)單詞,將詞法信息送給token */
ReadNextToken(&token);
/* 開(kāi)始調(diào)用基本語(yǔ)法分析處理函數(shù),遞歸下降處理 */
t = program();
/* 當(dāng)前單詞token不是ENDFILE,報(bào)代碼在文件結(jié)束前提前結(jié)束錯(cuò)誤 */
if (token.Lex!=ENDFILE)
syntaxError("Code ends before file\n");
/* 函數(shù)返回語(yǔ)法樹(shù)根節(jié)點(diǎn)t */
return t;
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -