Untitled
user_2381398
plain_text
2 years ago
16 kB
7
Indexable
%{ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <stdbool.h> #include <iostream> using namespace std; #define Trace(t) printf(t) #define MAX 256 int yylex(void); void yyerror(const char *s); #define MAX 256 #define MAX_TABLE 1024 struct content { char id[50]; char type[10]; char bigtype[MAX]; union { int ival; float fval; char sval[50]; int bval; } value; }; struct content symbolTable[MAX_TABLE][MAX_TABLE]; int id_total = 0; int scope = 0; void copyContent(struct content *dest, struct content src) { strcpy(dest->id, src.id); strcpy(dest->type, src.type); strcpy(dest->bigtype, src.bigtype); if (strcmp(src.type, "int") == 0 && strcmp(src.bigtype, "arrays") != 0) { dest->value.ival = src.value.ival; } else if (strcmp(src.type, "real") == 0 && strcmp(src.bigtype, "arrays") != 0) { dest->value.fval = src.value.fval; } else if (strcmp(src.type, "str") == 0 && strcmp(src.bigtype, "arrays") != 0) { strcpy(dest->value.sval, src.value.sval); } else if (strcmp(src.type, "bool") == 0 && strcmp(src.bigtype, "arrays") != 0) { dest->value.bval = src.value.bval; } else { dest->value.ival = src.value.ival; } } int insert(struct content a){ bool inSymbolTable = false ; for(int i = 0 ; i < id_total; i++){ if(strcmp(a.id, symbolTable[scope][i].id)==0){ inSymbolTable = true ; } } /* test output */ if(strcmp(a.type,"int")==0){ printf("bigtype:%s id:%s type:%s value:%d\n",a.bigtype,a.id,a.type,a.value.ival); }else if(strcmp(a.type,"real")==0){ printf("bigtype:%s id:%s type:%s value:%f\n",a.bigtype,a.id,a.type,a.value.fval); }else if(strcmp(a.type,"str")==0){ printf("bigtype:%s id:%s type:%s value:%s\n",a.bigtype,a.id,a.type,a.value.sval); }else if(strcmp(a.type,"bool")==0){ printf("bigtype:%s id:%s type:%s value:%d\n",a.bigtype,a.id,a.type,a.value.bval); }else if(strcmp(a.type,"bool")==0){ printf("bigtype:%s id:%s type:%s value:%d\n",a.bigtype,a.id,a.type,a.value.bval); } printf("--insert--\n"); if (!inSymbolTable){ copyContent(&symbolTable[scope][id_total], a); id_total++; } return 0; } struct content* lookup(char *c){ for (int i = 0; i <= scope; i++) { for(int j=0;j<=id_total;j++){ if (strcmp(c , symbolTable[i][j].id)==0) { return &symbolTable[i][j]; } } } return NULL; } int dump() { char val[32]; // assuming the string representation won't exceed 32 characters for (int i = 0; i <= scope; i++) { for (int j = 0; j <= id_total; j++) { char* type = symbolTable[i][j].type; char* bigtype = symbolTable[i][j].bigtype; char* id = symbolTable[i][j].id; if (strcmp("arrays", bigtype) == 0) { strcpy(val, " "); } else { if (strcmp("int", type) == 0) { sprintf(val, "%d", symbolTable[i][j].value.ival); } else if (strcmp("float", type) == 0) { sprintf(val, "%f", symbolTable[i][j].value.fval); } else if (strcmp("str", type) == 0) { strcpy(val, symbolTable[i][j].value.sval); } else if (strcmp("bool", type) == 0) { strcpy(val, symbolTable[i][j].value.bval == 0 ? "False" : "True"); } else if (strcmp("null", type) == 0) { strcpy(val, " "); } } printf("%-*s\t%-*s\t%-*s\t%-*s\t%-*d\n", 10, id, 10, type, 10, bigtype, 10, val, 10, i); } } return 0; } %} %union { char* idString; int integerValue; float floatValue; char* strValue; bool boolValue; char type[MAX]; char bigtype[MAX]; int intValue; struct content sdec; struct content contentValue; } /* tokens */ %token DOT COMMA COLON SEMICOLON LP RP LSB RSB LCB RCB PLUS MINUS MULTIPLY DIVIDE MOD COLONEQUALS LT LE GT GE EQ EQUALS NOTEQUALS AND OR NOT %token ARRAY BOOL CHAR CONST DECREASING DEFAULT TO DO ELSE BEGIN_KEYWORD END EXIT FALSE FOR FUNCTION GET IF ENDIF ENDFOR ENDLOOP INT LOOP OF PUT PROCEDURE REAL RESULT RETURN SKIP STRING THEN TRUE VAR WHEN %token <idString> IDENTIFIER %token <floatValue> FLOATVAL %token <integerValue> INTEGERVAL %token <strValue> STRINGVAL %token <integerValue> TRUEVAL %token <integerValue> FALSEVAL %token <integerValue> INT_RANGE %type<sdec> constant_exp %type<type> type %type<integerValue> function_invocation expression bool_expression %nonassoc LT LE GT EG NE %nonassoc EQ %left AND %left OR %right NOT %left PLUS MINUS %left MULTIPLY DIVIDE MOD %nonassoc UMINUS //%type<integerValue> unary_expression %start program %% program: program_units {Trace("Reducing to [program]\n");} ; constant_declaration: CONST IDENTIFIER COLON type COLONEQUALS constant_exp { struct content a; strcpy(a.id,$2); strcpy(a.bigtype,"conts"); if(strcmp($6.type,"int")==0){ strcpy(a.type,"int"); a.value.ival = $6.value.ival; }else if(strcmp($6.type,"real")==0){ strcpy(a.type,"real"); a.value.fval = $6.value.fval; }else if(strcmp($6.type,"str")==0){ strcpy(a.type,"str"); strcpy(a.value.sval,$6.value.sval); }else if(strcmp($6.type,"bool")==0){ strcpy(a.type,"bool"); a.value.bval = $6.value.bval; }else if(strcmp($6.type,"bool")==0){ strcpy(a.type,"bool"); a.value.bval = $6.value.bval; } insert(a); Trace("Reducing to [constant_declaration]\n"); } | CONST IDENTIFIER COLONEQUALS constant_exp { struct content a; strcpy(a.id,$2); strcpy(a.bigtype,"conts"); if(strcmp($4.type, "int")==0){ strcpy(a.type,"int"); a.value.ival = $4.value.ival; }else if(strcmp($4.type, "real")==0){ strcpy(a.type,"real"); a.value.fval = $4.value.fval; }else if(strcmp($4.type, "str")==0){ strcpy(a.type,"str"); strcpy(a.value.sval,$4.value.sval); }else if(strcmp($4.type, "bool")==0){ strcpy(a.type,"bool"); a.value.bval = $4.value.bval; }else if(strcmp($4.type, "bool")==0){ strcpy(a.type,"bool"); a.value.bval = $4.value.bval; } insert(a); Trace("Reducing to [constant_declaration]\n"); } | CONST IDENTIFIER COLON type COLONEQUALS MINUS constant_exp { struct content a; strcpy(a.id,$2); strcpy(a.bigtype,"conts"); if(strcmp($7.type, "int")==0){ strcpy(a.type,"int"); a.value.ival = -$7.value.ival; }else if(strcmp($7.type, "real")==0){ strcpy(a.type,"real"); a.value.fval = -$7.value.fval; }else{ // Add error handling for non-numeric types. printf("Error: Cannot apply unary minus to non-numeric type.\n"); YYERROR; } insert(a); Trace("Reducing to [constant_declaration]\n"); } | CONST IDENTIFIER COLONEQUALS MINUS constant_exp { struct content a; strcpy(a.id,$2); strcpy(a.bigtype,"conts"); if(strcmp($5.type, "int")==0){ strcpy(a.type,"int"); a.value.ival = -$5.value.ival; }else if(strcmp($5.type, "real")==0){ strcpy(a.type,"real"); a.value.fval = -$5.value.fval; }else{ // Add error handling for non-numeric types. printf("Error: Cannot apply unary minus to non-numeric type.\n"); YYERROR; } insert(a); Trace("Reducing to [constant_declaration]\n"); } ; variables_declaration: VAR IDENTIFIER COLON type COLONEQUALS constant_exp { struct content a; strcpy(a.id,$2); strcpy(a.bigtype,"var"); if(strcmp($6.type, "int")==0){ strcpy(a.type,"int"); a.value.ival = $6.value.ival; }else if(strcmp($6.type, "real")==0){ strcpy(a.type,"real"); a.value.fval = $6.value.fval; }else if(strcmp($6.type, "str")==0){ strcpy(a.type,"str"); strcpy(a.value.sval,$6.value.sval); }else if(strcmp($6.type, "bool")==0){ strcpy(a.type,"bool"); a.value.bval = $6.value.bval; }else if(strcmp($6.type, "bool")==0){ strcpy(a.type,"bool"); a.value.bval = $6.value.bval; } insert(a); Trace("Reducing to [constant_declaration]\n"); } | VAR IDENTIFIER COLONEQUALS constant_exp { struct content a; strcpy(a.id,$2); strcpy(a.bigtype,"var"); if(strcmp($4.type, "int")==0){ strcpy(a.type,"int"); a.value.ival = $4.value.ival; }else if(strcmp($4.type, "real")==0){ strcpy(a.type,"real"); a.value.fval = $4.value.fval; }else if(strcmp($4.type, "str")==0){ strcpy(a.type,"str"); strcpy(a.value.sval,$4.value.sval); }else if(strcmp($4.type, "bool")==0){ strcpy(a.type,"bool"); a.value.bval = $4.value.bval; }else if(strcmp($4.type, "bool")==0){ strcpy(a.type,"bool"); a.value.bval = $4.value.bval; } insert(a); Trace("Reducing to [constant_declaration]\n"); } | VAR IDENTIFIER COLON type { struct content a; strcpy(a.id,$2); strcpy(a.bigtype,"var"); if(strcmp($4, "int")==0){ strcpy(a.type,"int"); a.value.ival = 0; }else if(strcmp($4, "real")==0){ strcpy(a.type,"real"); a.value.fval = 0; }else if(strcmp($4, "str")==0){ strcpy(a.type,"str"); strcpy(a.value.sval,"NULL"); }else if(strcmp($4, "bool")==0){ strcpy(a.type,"bool"); a.value.bval = 0; }else if(strcmp($4, "bool")==0){ strcpy(a.type,"bool"); a.value.bval = 0; } insert(a); Trace("Reducing to [constant_declaration]\n"); } ; arrays_declaration: VAR IDENTIFIER COLON ARRAY INT_RANGE OF type { struct content a; strcpy(a.id,$2); strcpy(a.bigtype,"array"); if(strcmp($7,"int")==0){ strcpy(a.type,"int"); }else if(strcmp($7,"real")==0){ strcpy(a.type,"real"); }else if(strcmp($7,"str")==0){ strcpy(a.type,"str"); }else if(strcmp($7,"bool")==0){ strcpy(a.type,"bool"); } insert(a); Trace("Reducing to [arrays_declaration]\n"); } ; program_units: program_unit | program_units program_unit ; program_unit: constant_declaration | variables_declaration | arrays_declaration | function_expression | procedure_expression | statements | loop ; statements: blocks | simple | if_statement ; blocks: BEGIN_KEYWORD program_units END ; simple: IDENTIFIER COLONEQUALS INTEGERVAL | IDENTIFIER COLONEQUALS function_invocation | IDENTIFIER COLONEQUALS IDENTIFIER PLUS INTEGERVAL | IDENTIFIER COLONEQUALS IDENTIFIER PLUS IDENTIFIER | PUT signed_expression | GET IDENTIFIER | RESULT expression | EXIT | EXIT WHEN bool_expression | SKIP | EXIT WHEN IDENTIFIER EQUALS IDENTIFIER ; signed_expression: MINUS IDENTIFIER | IDENTIFIER | STRINGVAL | INTEGERVAL | FLOATVAL | bool_expression | parenthesized_stringval ; parenthesized_stringval: LP STRINGVAL RP ; expression: INTEGERVAL{ struct content a; strcpy(a.type,"int"); a.value.ival = $1; } | IDENTIFIER{ /*struct content a; a.value.ival = *lookup($1); strcpy(a.id,$1); a.value.ival = $$; insert(a);*/ } | MINUS INTEGERVAL{ $$=-$2; } | function_invocation | expression PLUS expression{ $$ = $1 + $3; } | expression MINUS expression{ $$ = $1 - $3; } | expression MULTIPLY expression{ $$ = $1 * $3; } | expression DIVIDE expression{ $$ = $1 / $3; } | expression MOD expression{ $$ = $1 % $3; } | expression LT expression | expression LE expression | expression EQUALS expression | expression EG expression | expression GT expression | expression NOTEQUALS expression | expression NOT expression | expression AND expression | expression OR expression ; function_expression: FUNCTION IDENTIFIER LP formal_arguments RP COLON type program_units END{scope--;} IDENTIFIER { struct content a; strcpy(a.id,$2); strcpy(a.bigtype,"func"); strcpy(a.type,$7); a.value.ival = 0; insert(a); scope++; Trace("Reducing to [function_expression]\n"); } ; procedure_expression: PROCEDURE IDENTIFIER LP formal_arguments RP program_units END{scope--;} IDENTIFIER { struct content a; strcpy(a.id,$2); strcpy(a.bigtype,"func"); a.value.ival = 0; insert(a); scope++; Trace("Redcing to [procedure_exprssion]\n"); } ; formal_arguments: formal_arguments COMMA formal_argument | formal_argument | ; formal_argument: IDENTIFIER COLON type{ struct content b; strcpy(b.id, $1); strcpy(b.bigtype,"func"); strcpy(b.type,$3); b.value.ival = 0; insert(b); Trace("Reducing to [formal_argument]\n"); }; if_statement: IF bool_expression THEN program_units ENDIF {Trace("Reducing to [if_statement]\n");} | IF bool_expression THEN program_units ELSE program_units ENDIF {Trace("Reducing to [if_statement]\n");} ; bool_expression: TRUEVAL{ /*strcpy($$.type, "bool"); $$.value.bval = 1;*/ } | FALSEVAL{ /* strcpy($$.type, "bool"); $$.value.bval = 0;*/ } | expression LT expression | expression LE expression | expression EQ expression | expression GE expression | expression GT expression | expression NE expression | NOT bool_expression{ /*strcpy($$.type, "bool"); $$.value.bval = !$2.value.bval;*/ } | bool_expression AND bool_expression | bool_expression OR bool_expression | LP bool_expression RP{$$ = $2;} ; function_invocation: IDENTIFIER LP expressions RP { struct content *result = lookup($1); if(result != NULL){ struct content a; strcpy(a.id,$1); a.value.ival = result->value.ival; // Assume that ival is what you want insert(a); } Trace("Reducing to [function_invocation]\n"); } |IDENTIFIER LP RP { struct content *result = lookup($1); if(result != NULL){ struct content a; strcpy(a.id,$1); a.value.ival = result->value.ival; // Assume that ival is what you want insert(a); } Trace("Reducing to [function_invocation]\n"); } ; expressions: expression | expressions COMMA expression ; loop: LOOP program_units ENDLOOP {Trace("Reducing to [loop]\n");} |LOOP ENDLOOP {Trace("Reducing to [loop]\n");} |FOR opt_decreasing IDENTIFIER COLON constant_exp DOT DOT constant_exp program_units_or_empty ENDFOR {Trace("Reducing to [loop]\n");} ; program_units_or_empty: program_units | ; opt_decreasing: DECREASING | ; constant_exp: INTEGERVAL { strcpy($$.type, "int"); $$.value.ival = $1; } | STRINGVAL { strcpy($$.type, "str"); strcpy($$.value.sval, $1); } | FLOATVAL { strcpy($$.type, "real"); $$.value.fval = $1; } | TRUEVAL { strcpy($$.type, "bool"); $$.value.bval = 1; } | FALSEVAL { strcpy($$.type, "bool"); $$.value.bval = 0; } | IDENTIFIER { struct content *content_ptr = lookup($1); if(content_ptr != NULL){ $$ = *content_ptr; struct content a; strcpy(a.id,$1); a.value.ival = content_ptr->value.ival; // If ival is the value you want insert(a); } } ; type: STRING { strcpy($$,"str"); } | BOOL { strcpy($$,"bool"); } | REAL { strcpy($$,"real"); } | INT { strcpy($$,"int"); } ; %% #include "lex.yy.c" void yyerror(const char *msg) { fprintf(stderr, "%s\n", msg); } int main(int argc, char *argv[]) { if(yyparse()){ yyerror("Parsing error !"); } return 0; }
Editor is loading...