📄 parser.cpp
字号:
scan->add_err();
outputMsg(scan->lineno(), "Syntax error: missing \'}\' before file end");
scan->push();
break;
}
switch (cToken.type){
case k_READ:
temp = read_stmt();
break;
case k_WRITE:
temp = write_stmt();
break;
case SEMI: //;
case k_NUM:
case LPARAN:
// cout << "k_NUM, LPARAN, expression_stmt()" <<endl; // debug
temp = expression_stmt();
break;
case k_ID:
// cout << "k_ID, subcompound_stmt()"<<endl;
temp = subcompound_stmt();
break;
case k_IF:
temp = if_stmt();
break;
case k_WHILE:
temp = while_stmt();
break;
case k_RETURN:
temp = return_stmt();
break;
case k_ELSE:
scan->add_err();
outputMsg(scan->lineno(), " unpaired \'else\' statement");
consumeUntil(SEMI, RBRACE);
break;
default:
scan->add_err();
sprintf(msg_temp, "Syntax error: undefined symbol \"%s\"", cToken.str.c_str());
outputMsg(scan->lineno(), msg_temp);
consumeUntil(SEMI, RBRACE);
break;
}
if (noBraces) return temp; // no braces
if (temp)
{
if (!first)
{
first = temp;
last = temp->LastSibling();
}
else
{
last->sibling = temp;
last = temp->LastSibling();
}
}
cToken = scan->nextToken();
}
return first;
}
/**: 11. local-declarations→ local-declarations var-declaration | empty
&
* author: lonelyforest
* data: 2006.03.31
*/
TreeNode* Parser::local_declarations()
{
TreeNode *temp = NULL;
iToken = cToken = scan->nextToken();
if (iToken.type != k_ID)
{
scan->add_err();
sprintf(msg_temp, "\"%s\" is a reserved token", iToken.str.c_str());
outputMsg(scan->lineno(), msg_temp);
consumeUntil(SEMI);
return NULL;
}
cToken = scan->nextToken(); // ';', '[', ','
if (cToken.type == SEMI || cToken.type == LSQUARE
|| cToken.type == COMMA)
{
temp = var_declaration();
}
else
{
scan->add_err();
sprintf(msg_temp, "missing \';\' after indentifier \"%s\"", iToken.str.c_str());
outputMsg(scan->lineno(), msg_temp);
scan->push();
}
return temp;
}
/**: 12. statement-list → statement-list statement | empty
&
* author: lonelyforest
* data: 2006.03.30
*/
/**: 13. statement → expression-stmt | compound-stmt | selection-stmt
& | iteration-stmt | return-stmt
*
* author: lonelyforest
* data: 2006.03.30
*/
/**: 14. expression-stmt --> expression; | ;
&
* author: lonelyforest
* data: 2006.03.31
*/
TreeNode* Parser::expression_stmt()
{// cToken == ( / k_ID / k_NUM / ;
//cout <<"expressino_stmt()"<<endl; // use debug
if (cToken.type == SEMI) return NULL;
TreeNode* temp = expression();
if (!match(SEMI))
{
scan->add_err();
outputMsg(scan->lineno(), "Syntax error: missing \';\'");
scan->push();
}
return temp;
}
/**: 15. selection-stmt → if (expression ) s tatement
& | if ( expression ) statement else statement
*
* author: lonelyforest
* data: 2006.03.31
*/
TreeNode* Parser::if_stmt()
{
TreeNode* temp = newStmtNode(ifK, cToken.str);
TreeNode* p = NULL;
if (!match(LPARAN))
{ // if (
scan->add_err();
outputMsg(scan->lineno(), "Syntax error: missing \'(\' in \"if\" statement");
}
else
{
cToken = scan->nextToken();
}
temp->child[0] = expression();
if (temp->child[0]) temp->child[0]->father = temp;
if (!match(RPARAN))
{ // if ( )
scan->add_err();
outputMsg(scan->lineno(), "Syntax error: missing \')\' in if statement");
scan->push();
}
p = temp->child[1] = compound_stmt();
if (p) p->father = temp;
while (p && p->sibling )
{
p = p->sibling ;
p->father = temp;
}
cToken = scan->nextToken();
if (cToken.type == k_ELSE)
{
p = temp->child[2] = compound_stmt();
if (p) p->father = temp;
while (p && p->sibling)
{
p = p->sibling;
p->father = temp;
}
}
else
{ // if has no 'else' statement, push the next token back
scan->push();
}
return temp;
}
/**: 16. iteration-stmt → while ( expression ) statement
&
* author: lonelyforest
* data: 2006.03.31
*/
TreeNode* Parser::while_stmt()
{ // current token is "while"
TreeNode* temp = newStmtNode( whileK, cToken.str);
TreeNode* p = NULL;
if (!match(LPARAN))
{ // while (
scan->add_err(); // add error count,
// out put the error message
outputMsg(scan->lineno(), "Syntax error: missing \'(\' in \"while\" statement");
}
else
{
cToken = scan->nextToken();
}
// cToken should be the first token of expression now ...
temp->child[0] = expression();
if (temp->child[0]) temp->child[0]->father = temp;
if (!match(RPARAN))
{ // while ( )
scan->add_err(); // record the parser error into class Scanner ...
outputMsg(scan->lineno(), "Syntax error: missing \')\' in \"while\" statement");
scan->push();
}
p = temp->child[1] = compound_stmt();
if (p) p->father = temp;
while (p && p->sibling )
{
p = p->sibling ;
p->father = temp;
}
return temp;
}
/**: 17. return-stmt → return; | return expression;
&
* author: lonelyforest
* data: 2006.03.31
*/
TreeNode* Parser::return_stmt()
{ // cToken.str == "return"
TreeNode* temp = newStmtNode(returnK, cToken.str);
cToken = scan->nextToken();
if (cToken.type != SEMI)
{
temp->child[0] = expression();
if (!match(SEMI))
{
scan->add_err();
outputMsg(scan->lineno(), "Syntax error: missing \';\' in \"return\" stamtement");
scan->push();
}
}
return temp;
}
/**: 18. expression → var = expression | simple-expression
&
* author: lonelyforest
* data: 2006.03.31
*/
TreeNode* Parser::expression()
{ // cToken == (, k_ID, k_NUM
TreeNode* temp = simple_expression();
TreeNode* p = temp; // 曾今忘记赋值, 使我的语法树没有了许多的节点!!=_=
cToken = scan->nextToken();
// cout << "expression()"<<endl;
if (cToken.type == ASSIGN)
{
if (temp->type != k_ID && temp->type != ASSIGN)
{
scan->add_err();
outputMsg(scan->lineno(), "Syntax error: left of \'=\' should be a ID");
consumeUntil(SEMI, RPARAN);
delete temp;
return NULL;
}
p = newExpNode(OpK, cToken.type, cToken.str);
p->child[0] = temp;
if (p->child[0]) p->child[0]->father = p;
cToken = scan->nextToken();
p->child[1] = expression();
if (p->child[1]) p->child[1]->father = p;
}
else
{
scan->push();
}
return p;
}
/**: 19. var → ID | ID [ expression ]
&
* author: lonelyforest
* data: 2006.03.31
*/
TreeNode* Parser::var()
{
TreeNode* temp = newExpNode(IDK, iToken.type, iToken.str);
cToken = scan->nextToken(); // "["
if (cToken.type == LSQUARE)
{
temp->bArr = true;
cToken = scan->nextToken();
temp->child[0] = expression();
if (!match(RSQUARE))
{
scan->add_err();
outputMsg(scan->lineno(), "Syntax error: missing \']\'");
scan->push();
}
}
else
{
scan->push();
}
return temp;
}
/**: 20. simple-expression → additive-expression relop additive-expression
& |additive-expression
& 21. relop →<= | < | > | >= | == | !=
*
* author: lonelyforest
* data: 2006.03.31
*/
TreeNode* Parser::simple_expression()
{
TreeNode* p = additive_expression();
// cout << "simple_expression()"<<endl;
cToken = scan->nextToken();
if (cToken.type == NGT || cToken.type == LT ||
cToken.type == GT || cToken.type == NLT
|| cToken.type == EQ || cToken.type == NEQ)
{
TreeNode *temp = newExpNode(OpK, cToken.type, cToken.str);
temp->child[0] = p;
p = temp;
if (p->child[0]) p->child[0]->father = p;
cToken = scan->nextToken();
p->child[1] = additive_expression();
if (p->child[1])
p->child[1]->father = p;
}
else
{
scan->push();
}
return p;
}
/**: 22. additive-expression → additive-expression addop term | term
& 23. addop →+ | -
*
* author: lonelyforest
* data: 2006.03.31
*/
TreeNode* Parser::additive_expression()
{
TreeNode *p = term();
cToken = scan->nextToken();
while (cToken.type == PLUS || cToken.type == MINUS)
{
TreeNode *temp = newExpNode( OpK, cToken.type, cToken.str);
temp->child[0] = p;
p = temp;
if (p->child[0]) p->child[0]->father = p;
cToken = scan->nextToken();
p->child[1] = term();
if (p->child[1]!= NULL)
{
p->child[1]->father = p;
}
cToken = scan->nextToken();
}
scan->push();
return p;
}
/**: 24. term → term mulop factor | factor
& 25. mulop →* | /
*
* author: lonelyforest
* data: 2006.03.30
*/
TreeNode* Parser::term()
{
TreeNode *p = factor();
cToken = scan->nextToken();
while (cToken.type == TIMES || cToken.type == DIV
|| cToken.type == MOD)
{
TreeNode *temp = newExpNode(OpK, cToken.type, cToken.str);
temp->child[0] = p;
p = temp;
if (p->child[0]) p->child[0]->father = p;
cToken = scan->nextToken();
p->child[1] = factor();
if (p->child[1] != NULL) p->child[1]->father = p;
cToken = scan->nextToken();
}
scan->push();
return p;
}
/**: 26. factor → ( expression ) | var | call | NUM
&
* author: lonelyforest
* data: 2006.03.30
*/
TreeNode* Parser::factor()
{
TreeNode* temp = NULL;
switch (cToken.type ){
case k_NUM:
temp = newExpNode(ConstK, cToken.type, cToken.str);
break;
case k_ID:
iToken = cToken;
cToken = scan->nextToken();
if (cToken.type == LPARAN) temp = call();
else {
scan->push();
temp = var();
}
break;
case LPARAN:
cToken = scan->nextToken();
temp = expression();
if (!match(RPARAN))
{
scan->add_err();
outputMsg(scan->lineno(), "Syntax Error: missing \')\'");
scan->push();
}
break;
default:
scan->add_err();
sprintf(msg_temp, "Syntax error: \'%s\' expression is unexpected!", cToken.str.c_str());
outputMsg(scan->lineno(), msg_temp);
consumeUntil(SEMI, RBRACE);
}
return temp;
}
/**: 27. call → ID ( args )
&
* author: lonelyforest
* data: 2006.03.31
*/
TreeNode* Parser::call()
{
TreeNode* p = newStmtNode(callK, iToken.str);
TreeNode* temp = NULL;
p->scope = "global";
p->child[0] = args();
if (p->child[0])
{
p->child[0]->father = p;
}
temp = p->child[0];
while (temp && temp->sibling)
{
temp = temp->sibling;
temp->father = p;
}
if (!match(RPARAN))
{
scan->add_err();
outputMsg(scan->lineno(), "Syntax error: missing \')\'");
scan->push();
}
return p;
}
/**: 28. args → arg-list | empty
& 29. arg-list → arg-list , expression | expression
*
* author: lonelyforest
* data: 2006.03.31
*/
TreeNode* Parser::args()
{
TreeNode *first = NULL,
*temp = NULL;
cToken = scan->nextToken();
if (cToken.type == RPARAN)
{ // ()
scan->push();
return NULL;
}
while (true)
{
if ((temp=expression()) != NULL)
{
if (!first) first = temp;
else
{
temp->sibling = first;
first = temp;
}
}
cToken = scan->nextToken();
if (cToken.type == COMMA)
{
cToken = scan->nextToken();
}
else
{
break;
}
}
scan->push();
return first;
}
/**: 30. read → read( int );
&
* author: lonelyforest
* data: 2006.03.30
*/
TreeNode* Parser::read_stmt()
{// currentToken.str == "read"
TreeNode* temp = NULL;
if (!match(LPARAN))
{
scan->add_err();
outputMsg(scan->lineno(),"Syntax error: missing \'(\'");
consumeUntil(SEMI, RBRACE);
return NULL;
}
iToken = cToken = scan->nextToken();
if (cToken.type != k_ID)
{
scan->add_err();
sprintf(msg_temp, "\"%s\" is a bad argument", cToken.str.c_str());
outputMsg(scan->lineno(), msg_temp);
consumeUntil(SEMI, RBRACE);
return NULL;
}
temp = newStmtNode(readK, "read");
if ((temp->child[0] = var()) != NULL)
{
temp->child[0]->father = temp;
}
if (!match(RPARAN))
{
scan->add_err();
outputMsg(scan->lineno(), "Syntax error: missing \')\'");
consumeUntil(SEMI, RBRACE);
return temp;
}
if (!match(SEMI))
{
scan->add_err();
outputMsg(scan->lineno(), "Syntax error: missing \';\'");
scan->push();
}
return temp;
}
/**: 31. write → write( int );
&
* author: lonelyforest
* data: 2006.03.30
*/
TreeNode* Parser::write_stmt()
{// cToken.str == "write"
TreeNode* temp = NULL;
if (!match(LPARAN))
{
scan->add_err();
outputMsg(scan->lineno(), "Syntax error: missing \')\'");
consumeUntil(SEMI, RBRACE);
return NULL;
}
temp = newStmtNode(writeK, "write");
cToken = scan->nextToken();
if ((temp->child[0] = expression()) != NULL)
{
temp->child[0]->father = temp;
}
if (!match(RPARAN))
{ // "}"
scan->add_err();
outputMsg(scan->lineno(), "Syntax Error: missing \')\'");
consumeUntil(SEMI, RBRACE);
return temp;
}
if (!match(SEMI))
{
scan->add_err();
outputMsg(scan->lineno(), "Syntax error: missing \';\'");
scan->push();
}
return temp;
}
//
/**: sub_compoundstmt → ID; | call; | expression_stmt
&
* author: lonelyforest
* data: 2006.03.31
*/
TreeNode* Parser::subcompound_stmt()
{
TreeNode* temp = NULL;
// cout << "Subcompound_stmt()" <<endl;
iToken = cToken;
cToken = scan->nextToken();
if (cToken.type == LPARAN)
{ // call statement
temp = call();
if (!match(SEMI)){
scan->add_err();
outputMsg(scan->lineno(), "Syntax error: missing \';\' after fun call");
scan->push();
}
}
else
{
scan->push();
cToken = iToken;
temp = expression_stmt();
}
return temp;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -