⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lab3.y

📁 c—语言的句法分析器。读入一个C--语言程序
💻 Y
📖 第 1 页 / 共 2 页
字号:
           }
       }
    ;
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 + -