📄 lab3.y
字号:
}
}
;
expression
: var '=' expression
{
if ($1 != 0) {
if ($1->type != $3.type) {
printf("line %3d error: = :the left and the right type does not match\n", lineno, $1);
right = 0;
}
$$.type = $1->type;
}
if (debug) {
printf("expression => var = expression\n");
}
}
| simple_expression
{
$$.type = $1.type;
/* if (debug) {
printf("expression => simple_expression\n");
}*/
}
;
var
: ID
{
$$ = LookUp($1, symboltable[tablelen-1]);
if (0 == $$) {
printf("line %3d error: %s :undeclared identifier\n", lineno, $1);
right = 0;
}
if (debug) {
printf("var => ID\n");
}
}
| ID '[' expression ']'
{
$$ = LookUp($1, symboltable[tablelen-1]);
if (0 == $$) {
printf("line %3d error: %s :undeclared identifier\n", lineno, $1);
right = 0;
}
if (debug) {
printf("var => ID [ expression ]\n");
}
}
;
simple_expression
: additive_expression relop additive_expression
{
$$.type = INT;
if (($1.type == INT || $1.type == CHAR) && ($3.type == INT || $3.type == CHAR)) {
if (0 == strcmp($2, "<")) {
if ($1.value < $3.value) {
$$.value = 1;
} else {
$$.value = 0;
}
} else if (0 == strcmp($2, "<=")) {
if ($1.value <= $3.value) {
$$.value = 1;
} else {
$$.value = 0;
}
} else if (0 == strcmp($2, ">")) {
if ($1.value > $3.value) {
$$.value = 1;
} else {
$$.value = 0;
}
} else if (0 == strcmp($2, ">=")) {
if ($1.value >= $3.value) {
$$.value = 1;
} else {
$$.value = 0;
}
} else if (0 == strcmp($2, "==")) {
if ($1.value == $3.value) {
$$.value = 1;
} else {
$$.value = 0;
}
} else {
if ($1.value != $3.value) {
$$.value = 1;
} else {
$$.value = 0;
}
}
}
if ($1.type != INT && $1.type != CHAR) {
printf("line %3d error: %s :illegal, left operand is not constant or character\n", lineno, $2);
right = 0;
}
if ($3.type != INT && $3.type != CHAR) {
printf("line %3d error: %s :illegal, right operand is not constant or character\n", lineno, $2);
right = 0;
}
if (debug) {
printf("simple_expression => additive_expression relop additive_expression\n");
}
}
| additive_expression
{
$$.type = $1.type;
/* if (debug) {
printf("simple_expression => additive_expression\n");
}*/
}
;
relop
: LE
{
if (debug) {
printf("relop => LE\n");
}
}
| LT
{
if (debug) {
printf("relop => LT\n");
}
}
| GT
{
if (debug) {
printf("relop => GT\n");
}
}
| GE
{
if (debug) {
printf("relop => GE\n");
}
}
| EQ
{
if (debug) {
printf("relop => EQ\n");
}
}
| NE
{
if (debug) {
printf("relop => NE\n");
}
}
;
additive_expression
: additive_expression addop term
{
$$.type = INT;
if ($1.type == INT && $3.type == INT) {
if ($2[0] == '+') {
$$.value = $1.value + $3.value;
} else {
$$.value = $1.value - $3.value;
}
}
if ($1.type != INT) {
printf("line %3d error: %c :illegal, left operand is not constant\n", lineno, $2[0]);
right = 0;
}
if ($3.type != INT) {
printf("line %3d error: %c :illegal, right operand is not constant\n", lineno, $2[0]);
right = 0;
}
if (debug) {
printf("additive_expression => additive_expression addop term\n");
}
}
| term
{
$$.type = $1.type;
/* if (debug) {
printf("additive_expression => term\n");
}*/
}
;
addop
: '+'
{
$$[0] = '+';
if (debug) {
printf("addop => +\n");
}
}
| '-'
{
$$[0] = '-';
if (debug) {
printf("addop => -\n");
}
}
;
term
: term mulop unary_expression
{
$$.type = INT;
if ($1.type == INT && $3.type == INT) {
if ($2[0] == '*') {
$$.value = $1.value * $3.value;
} else if ($2[0] == '/') {
$$.value = $1.value / $3.value;
} else {
$$.value = $1.value % $3.value;
}
}
if ($1.type != INT) {
printf("line %3d error: %c :illegal, left operand is not constant\n", lineno, $2[0]);
right = 0;
}
if ($3.type != INT) {
printf("line %3d error: %c :illegal, right operand is not constant\n", lineno, $2[0]);
right = 0;
}
if (debug) {
printf("term => term mulop unary_expression\n");
}
}
| unary_expression
{
$$.type = $1.type;
/* if (debug) {
printf("term => unary_expression\n");
}*/
}
;
mulop
: '*'
{
$$[0] = '*';
if (debug) {
printf("mulop => *\n");
}
}
| '/'
{
$$[0] = '/';
if (debug) {
printf("mulop => /\n");
}
}
| '%'
{
$$[0] = '%';
if (debug) {
printf("mulop => %\n");
}
}
;
unary_expression
: unaryop unary_expression
{
$$.type = INT;
if ($2.type == INT) {
if ($1[0] == '+') {
$$.value = $2.value;
} else {
$$.value = -$2.value;
}
}
if ($2.type != INT) {
printf("line %3d error: %c :illegal, right operand is not constant\n", lineno, $1[0]);
right = 0;
}
if (debug) {
printf("unary_expression => unaryop unary_expression\n");
}
}
| factor
{
$$.type = $1.type;
/* if (debug) {
printf("unary_expression => factor\n");
}*/
}
;
unaryop
: '+'
{
$$[0] = '+';
if (debug) {
printf("unaryop => +\n");
}
}
| '-'
{
$$[0] = '-';
if (debug) {
printf("unaryop => -\n");
}
}
;
factor
: '(' expression ')'
{
$$.type = $2.type;
if (debug) {
printf("factor => ( expression )\n");
}
}
| var
{
if ($1 != 0) {
$$.type = $1->type;
$$.symadd = $1;
}
if (debug) {
printf("factor => var\n");
}
}
| call
{
$$.type = $1.type;
if (debug) {
printf("factor => call\n");
}
}
| NUM
{
$$.type = INT;
$$.value = atoi($1);
if (debug) {
printf("factor => NUM\n");
}
}
| CHAR_LITERAL
{
$$.type = CHAR;
$$.value = $1[1];
if (debug) {
printf("factor => CHAR_LITERAL\n");
}
}
| STRING_LITERAL
{
$$.type = CHAR + 100;
$$.string = $1;
if (debug) {
printf("factor => STRING_LITERAL\n");
}
}
;
call
: ID '(' args ')'
{
$$.type = LookUpFun($1);
if (0 == $$.type) {
printf("line %3d error: %s :undeclared function\n", lineno, $1);
right = 0;
}
typecheck = 0;
free(arg_in.temp);
if (0 == (arg_in.temp = (int *)malloc(50 * sizeof(int)))) {
printf("malloc for argument check buffer error\n");
exit(1);
}
arg_in.size = 50;
if (debug) {
printf("call => ID ( args )\n");
}
}
;
args
: arg_list
{/*
if (debug) {
printf("args => arg_list\n");
}*/
}
| /* empty */
;
arg_list
: arg_list ',' expression
{
if (typecheck + 1 > arg_in.size) {
arg_in.temp = (int *)realloc(arg_in.temp,(arg_in.size + BUFFINCREMENT) * sizeof(int));
if (0 == arg_in.temp) {
printf("realloc for argument check buffer error\n");
exit(1);
}
arg_in.size += BUFFINCREMENT;
}
arg_in.temp[typecheck++] = $3.type;
/* if (debug) {
printf("arg_list => arg_list , expression\n");
}*/
}
| expression
{
if (typecheck + 1 > arg_in.size) {
arg_in.temp = (int *)realloc(arg_in.temp,(arg_in.size + BUFFINCREMENT) * sizeof(int));
if (0 == arg_in.temp) {
printf("realloc for argument check buffer error\n");
exit(1);
}
arg_in.size += BUFFINCREMENT;
}
arg_in.temp[typecheck++] = $1.type;
/* if (debug) {
printf("arg_list => expression\n");
}*/
}
;
calling_convention
: CDECL
{
if (debug) {
printf("calling_convention => CDECL\n");
}
}
| STDCALL
{
if (debug) {
printf("calling_convention => STDCALL\n");
}
}
;
%%
void info()
{
printf("lab3.exe -- Copyright (C) 2007 cj4 No.04120004\n");
printf("Usage: lab3 [-d] filename\n");
printf("----------------------------------------------------\n");
printf("filename specifies the name of input file\n");
printf("-d debug mode\n");
exit(1);
}
int yyerror(char *s)
{
fprintf(stderr, "line %3d error: %s\n", lineno, s);
right = 0;
return (0);
}
int main(int argc, char *argv[])
{
debug = 0;
switch (argc) {
case 3:
if (0 == strcmp(argv[1], "-d")) {
printf("============= debug mode =============\n");
debug = 1;
} else {
info();
}
if (NULL == (yyin = fopen(argv[2],"r"))) {
printf("file: %s open error!\n", argv[2]);
exit(1);
}
yyparse();
free(argtemp.temp);
free(arg_in.temp);
fclose(yyin);
break;
case 2:
if (NULL == (yyin = fopen(argv[1],"r"))) {
printf("file: %s open error!\n", argv[1]);
exit(1);
}
yyparse();
free(argtemp.temp);
free(arg_in.temp);
fclose(yyin);
break;
default:
info();
}
if (right) {
printf("Well done!\n");
}
return (0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -