📄 syntax.cpp
字号:
#include "StdAfx.h"
#include ".\syntax.h"
#define DEBUG true
Syntax::Syntax(void)
{
}
Syntax::~Syntax(void)
{
}
///// Lex
extern Word g_token;
extern token current_token;
extern bool matched;
///// Semantic
extern Level curLevel;
// <system goal> -> <program> SCANEOF #finish
void system_goal (void) {
program();
match( SCANEOF );
finish();
}
// <program> -> #start <function> {, <function> }
void program (void) {
if( DEBUG )
fprintf(stderr, "program:\n");
start();
token tk = next_token();
while( tk == FUNCTION ) {
function();
tk = next_token();
}
}
// <function> -> function <fname> ( <param list> ) begin <statement list> end
// <function> -> function <fname> ( ) begin <statement list> end
void function (void) { // new added
if( DEBUG )
fprintf(stderr, "function:\n");
expr_rec fun_name;
match( FUNCTION );
curLevel = LOCAL;// 进入局部作用域
fname( & fun_name );
match( LPAREN ); if( next_token() == ID ) { param_list(); } match( RPAREN );
match( BEGIN );
statement_list();
match( END );
curLevel = GLOBAL;// 进入全局作用域
}
void statement_list () {
statement();
while( true ) {
if( DEBUG )
fprintf(stderr, "statement_list:\n");
switch( next_token() ) {
case ID:
case READ:
case WRITE:
statement();
break;
default:
return;
}
}
}
/*
<statement> -> <ident> := <expression> #assign ;
<statement> -> read( <read list> );
<statement> -> write ( <write list> );
<statement> -> <ident> ( <argument list> ) #process_func_call;
<statement> -> <ident> ( ) #process_func_call;
*/
void statement (void) {
token tok = next_token();
if( DEBUG ) fprintf(stderr, "statement: %d\n", tok);
expr_rec left, right;
switch( tok ) {
case ID:
ident(&left); // match(ID);
if( next_token() == ASSIGNOP ) {
match(ASSIGNOP); expression(&right); assign(left, right); // #
} else if ( next_token() == LPAREN ) {
match( LPAREN );
if( next_token() == ID ) { argument_list(); }
match( RPAREN );
process_func_call();// # check and generate
} else {
syntax_error( next_token() );
}
match(SEMICOLON);
break;
case READ:
match(READ); match(LPAREN); read_list(); match(RPAREN); match(SEMICOLON);
break;
case WRITE:
match(WRITE); match(LPAREN); write_list(); match(RPAREN); match(SEMICOLON);
break;
}
}
// <param list> -> <ident> #process_param {, <ident> #process_param }
void param_list (void) { // new added
expr_rec id;
ident( & id);
process_param( );// #
while( next_token() == COMMA ) {
match( COMMA );
ident( & id );
process_param( );// #
}
}
// <argument list> -> <ident> #process_argu {, <ident> #process_argu }
void argument_list (void) { // new added
expr_rec id;
ident( & id );
process_argu();// #
while( next_token() == COMMA ) {
ident( & id );
process_argu();// #
}
}
void read_list (void) { // id_list
expr_rec t;
ident( &t );// <ident> match(ID);
read_id(t);
while( next_token() == COMMA ) {
match(COMMA);
ident( &t );// <ident> match(ID);
read_id(t);
}
}
void write_list (void) { // write_list
expr_rec exp;
expression(&exp);
write_expr(exp);// #
while( next_token() == COMMA ) {
match( COMMA );
expression(&exp);
write_expr(exp);// #
}
}
// <expression> -> <mul expr> { <add op> <mul expr> #gen_infix }
void expression ( expr_rec * result ) {
token t;
expr_rec left, right;
op_rec op;
if( DEBUG ) { fprintf(stderr, "expression:\n"); }
mul_expr( &left );//primary( &left ); before change is primary
for( t = next_token(); t == PLUSOP || t == MINUSOP ; t = next_token() ) {
add_op( &op );
mul_expr( &right );//primary( &right ); before change is primary
left = gen_infix(left, op, right);// #
}
*result = left;
}
// <mul expr> -> <primary> { <mul op> <primary> }
void mul_expr (expr_rec * result) { // new added
token t;
expr_rec left, right;
op_rec op;
if( DEBUG ) { fprintf(stderr, "mul_expr:\n"); }
primary( &left );
for( t = next_token(); t == MULOP || t == DIVOP ; t = next_token() ) {
mul_op( &op );
primary( &right );
left = gen_infix(left, op, right);// #
}
*result = left;
}
void primary (expr_rec * exp) {
token tok = next_token();
if( DEBUG ) fprintf(stderr, "primary: %d\n", tok);
switch(tok) {
case LPAREN:
match(LPAREN); expression(exp); match(RPAREN);
break;
case ID:
ident( exp );// match(ID); #
break;
case INTLITERAL:
match(INTLITERAL);
*exp = process_literal();// #
break;
default:
syntax_error(tok);
break;
}
}
void add_op (op_rec * op) {
token t = next_token();
if( DEBUG ) fprintf(stderr, "add_op: %d\n", t);
if( t == PLUSOP || t == MINUSOP ) {
match(t);
*op = process_op();
} else {
syntax_error(t);
}
}
void mul_op (op_rec * op) {
token t = next_token();
if( DEBUG ) fprintf(stderr, "mul_op: %d\n", t);
if( t == MULOP || t == DIVOP ) {
match(t);
*op = process_op();
} else {
syntax_error(t);
}
}
void ident (expr_rec * exp) {
match(ID);
*exp = process_id();// #
}
void fname (expr_rec * exp) { // new added
match(ID);
gen_func_name( *exp );
}
token next_token() {
if( matched ) {
current_token = scanner();
matched = false;
}
return current_token;
}
void match(token tk) {
if( matched ) {
current_token = next_token();
}
if( current_token != tk ) {
char buf[50];
if( tk == ID || INTLITERAL == tk )
sprintf(buf, "[ Unmatch ] expect:%d cur-tok:%d text:%s", tk, current_token, g_token.buf);
else
sprintf(buf, "[ Unmatch ] expect:%d cur-tok:%d", tk, current_token);
error(buf);
exit(3);
}
matched = true;
if( DEBUG ) {
if( ID == tk || INTLITERAL == tk ) {
fprintf(stderr, "match %d %s %s\n", tk, getTokenText(tk), g_token.buf);
}
else
fprintf(stderr, "match %d %s\n", tk, getTokenText(tk));
}
}
void syntax_error(token t) {
char buf[100];
fprintf(stderr, "[ Syntax Error ] - text:%s tok:%d", g_token.buf, t);
exit(4);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -