ast for quadratic is correct
This commit is contained in:
parent
8ee2bb29a7
commit
3479042b85
28
lab-5/expr.c
28
lab-5/expr.c
|
|
@ -34,6 +34,12 @@ struct stmt *stmt_create(stmt_t kind, struct decl *decl, struct expr *init_expr,
|
||||||
struct stmt *body, struct stmt *else_body,
|
struct stmt *body, struct stmt *else_body,
|
||||||
struct stmt *next) {
|
struct stmt *next) {
|
||||||
struct stmt *s = malloc(sizeof(*s));
|
struct stmt *s = malloc(sizeof(*s));
|
||||||
|
if (kind == STMT_COMPUTE) {
|
||||||
|
if (decl) {
|
||||||
|
printf("name: %s\n", decl->name->name);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
s->kind = kind;
|
s->kind = kind;
|
||||||
s->decl = decl;
|
s->decl = decl;
|
||||||
s->init_expr = init_expr;
|
s->init_expr = init_expr;
|
||||||
|
|
@ -137,6 +143,9 @@ void stmt_print(struct stmt *s) {
|
||||||
printf(" then\n");
|
printf(" then\n");
|
||||||
stmt_print(s->body);
|
stmt_print(s->body);
|
||||||
printf("endif\n");
|
printf("endif\n");
|
||||||
|
if (!s->else_body) { printf("\n"); break;}
|
||||||
|
printf("else ");
|
||||||
|
stmt_print(s->else_body);
|
||||||
break;
|
break;
|
||||||
case STMT_PRINT:
|
case STMT_PRINT:
|
||||||
printf("print ");
|
printf("print ");
|
||||||
|
|
@ -150,6 +159,11 @@ void stmt_print(struct stmt *s) {
|
||||||
case STMT_SECTION:
|
case STMT_SECTION:
|
||||||
printf("section\n");
|
printf("section\n");
|
||||||
break;
|
break;
|
||||||
|
case STMT_COMPUTE:
|
||||||
|
printf("compute ");
|
||||||
|
decl_print(s->decl);
|
||||||
|
printf(";\n");
|
||||||
|
break;
|
||||||
case STMT_END_EXECUTION:
|
case STMT_END_EXECUTION:
|
||||||
printf("stop run\n");
|
printf("stop run\n");
|
||||||
break;
|
break;
|
||||||
|
|
@ -175,15 +189,20 @@ void expr_print(struct expr *e) {
|
||||||
close = "]";
|
close = "]";
|
||||||
} else if (e->kind != EXPR_NAME && e->kind != EXPR_SUBSCRIPT &&
|
} else if (e->kind != EXPR_NAME && e->kind != EXPR_SUBSCRIPT &&
|
||||||
e->kind != EXPR_INTEGER_LITERAL && e->kind != EXPR_FLOAT_LITERAL &&
|
e->kind != EXPR_INTEGER_LITERAL && e->kind != EXPR_FLOAT_LITERAL &&
|
||||||
e->kind != EXPR_STRING_LITERAL) {
|
e->kind != EXPR_STRING_LITERAL && e->kind != EXPR_CUSTOM_FUNCTION) {
|
||||||
printf("(");
|
printf("(");
|
||||||
close = ")";
|
close = ")";
|
||||||
|
} else if (e->kind == EXPR_CUSTOM_FUNCTION) {
|
||||||
|
printf("FUNCTION ");
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_print(e->left);
|
expr_print(e->left);
|
||||||
|
|
||||||
switch (e->kind) {
|
switch (e->kind) {
|
||||||
case EXPR_NAME:
|
case EXPR_NAME:
|
||||||
|
if (e->negative) {
|
||||||
|
printf("-");
|
||||||
|
}
|
||||||
printf("%s", e->name);
|
printf("%s", e->name);
|
||||||
break;
|
break;
|
||||||
case EXPR_ARRAY:
|
case EXPR_ARRAY:
|
||||||
|
|
@ -234,6 +253,12 @@ void expr_print(struct expr *e) {
|
||||||
case EXPR_STRING_LITERAL:
|
case EXPR_STRING_LITERAL:
|
||||||
printf("%s", e->string_literal);
|
printf("%s", e->string_literal);
|
||||||
break;
|
break;
|
||||||
|
case EXPR_EXPONENTIAL:
|
||||||
|
printf("**");
|
||||||
|
break;
|
||||||
|
case EXPR_CUSTOM_FUNCTION:
|
||||||
|
printf(" ");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_print(e->right);
|
expr_print(e->right);
|
||||||
|
|
@ -265,6 +290,7 @@ void stmt_evaluate(struct stmt *s) {
|
||||||
break;
|
break;
|
||||||
case STMT_PRINT:
|
case STMT_PRINT:
|
||||||
stmt_evaluate_print(s->expr);
|
stmt_evaluate_print(s->expr);
|
||||||
|
printf("\n");
|
||||||
break;
|
break;
|
||||||
case STMT_BLOCK:
|
case STMT_BLOCK:
|
||||||
stmt_evaluate(s->body);
|
stmt_evaluate(s->body);
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,8 @@ typedef enum {
|
||||||
EXPR_STRING_LITERAL,
|
EXPR_STRING_LITERAL,
|
||||||
EXPR_SUBSCRIPT,
|
EXPR_SUBSCRIPT,
|
||||||
EXPR_SUBTRACT,
|
EXPR_SUBTRACT,
|
||||||
|
EXPR_NULL,
|
||||||
|
EXPR_CUSTOM_FUNCTION
|
||||||
} expr_t;
|
} expr_t;
|
||||||
|
|
||||||
struct expr {
|
struct expr {
|
||||||
|
|
@ -44,6 +46,7 @@ struct expr {
|
||||||
int integer_value;
|
int integer_value;
|
||||||
float float_value;
|
float float_value;
|
||||||
const char *string_literal;
|
const char *string_literal;
|
||||||
|
int negative;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
||||||
|
|
@ -95,8 +95,8 @@ extern struct stmt *parser_result = 0;
|
||||||
struct type *type;
|
struct type *type;
|
||||||
}
|
}
|
||||||
|
|
||||||
%type <stmt> statement_list statement section stop_run sect_data simple_stmt cbl_func_stmt cbl_function if_branch else_parts perform_stmt data_space
|
%type <stmt> statement_list statement section stop_run sect_data simple_stmt cbl_func_stmt cbl_function if_branch else_parts else_branch perform_stmt data_space
|
||||||
%type <expr> mathmaticalexpr booleanexpr term op_parm container_expr type_expr op_parms math_op categry_contain category_value ident
|
%type <expr> mathmaticalexpr booleanexpr term op_parm container_expr type_expr op_parms math_op categry_contain category_value ident ext_function
|
||||||
%type <decl> assignment_stmt simple_decl complex_decl data_declaration category_spec
|
%type <decl> assignment_stmt simple_decl complex_decl data_declaration category_spec
|
||||||
%type <type> data_category complete_category data_clause
|
%type <type> data_category complete_category data_clause
|
||||||
%%
|
%%
|
||||||
|
|
@ -139,12 +139,10 @@ simple_stmt : cbl_func_stmt
|
||||||
| if_branch
|
| if_branch
|
||||||
| perform_stmt
|
| perform_stmt
|
||||||
;
|
;
|
||||||
cbl_func_stmt : cbl_function op_parms
|
cbl_func_stmt : cbl_function ident assignment_stmt
|
||||||
{$$ = stmt_create($1->kind, NULL, NULL, $2, NULL, NULL, NULL, NULL); }
|
{ $3->name = $2; $$= stmt_create($1->kind, $3, NULL, NULL, NULL, NULL, NULL, NULL);}
|
||||||
| cbl_function assignment_stmt
|
| cbl_function op_parms
|
||||||
{$$ = stmt_create($1->kind, NULL, NULL, NULL, NULL, $2, NULL, NULL);}
|
{$$ = stmt_create($1->kind, NULL, NULL, $2, NULL, NULL, NULL, NULL);}
|
||||||
| cbl_function op_parm assignment_stmt
|
|
||||||
{$$ = stmt_create($1->kind, NULL, NULL, $2, NULL, $3, NULL, NULL);}
|
|
||||||
;
|
;
|
||||||
assignment_stmt : TOKEN_EQUAL op_parms
|
assignment_stmt : TOKEN_EQUAL op_parms
|
||||||
{$$ = decl_create(NULL, NULL, $2, NULL, NULL);}
|
{$$ = decl_create(NULL, NULL, $2, NULL, NULL);}
|
||||||
|
|
@ -204,10 +202,12 @@ type_expr : ident
|
||||||
{$$ = expr_create_integer_literal(0);}
|
{$$ = expr_create_integer_literal(0);}
|
||||||
// TODO: implment negative numbers
|
// TODO: implment negative numbers
|
||||||
| TOKEN_SUB ident
|
| TOKEN_SUB ident
|
||||||
|
{ $2->negative = 1; $$ = $2;}
|
||||||
| ext_function
|
| ext_function
|
||||||
|
{$$ = $1;}
|
||||||
;
|
;
|
||||||
ext_function : TOKEN_KEYWORD_FUNCTION ident TOKEN_LEFT_PARENTHESIS ident TOKEN_RIGHT_PARENTHESIS
|
ext_function : TOKEN_KEYWORD_FUNCTION ident TOKEN_LEFT_PARENTHESIS ident TOKEN_RIGHT_PARENTHESIS
|
||||||
|
{$$ = expr_create(EXPR_CUSTOM_FUNCTION, $2, $4);}
|
||||||
;
|
;
|
||||||
cbl_function : TOKEN_DISPLAY
|
cbl_function : TOKEN_DISPLAY
|
||||||
{$$ = stmt_create(STMT_PRINT, NULL, NULL, NULL, NULL, NULL, NULL, NULL);}
|
{$$ = stmt_create(STMT_PRINT, NULL, NULL, NULL, NULL, NULL, NULL, NULL);}
|
||||||
|
|
@ -217,14 +217,18 @@ cbl_function : TOKEN_DISPLAY
|
||||||
{$$ = stmt_create(STMT_COMPUTE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);}
|
{$$ = stmt_create(STMT_COMPUTE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);}
|
||||||
;
|
;
|
||||||
if_branch : TOKEN_IF booleanexpr statement_list else_parts
|
if_branch : TOKEN_IF booleanexpr statement_list else_parts
|
||||||
{$$ = stmt_create(STMT_IF, NULL, NULL, $2, $4, $3, NULL, NULL);}
|
{$$ = stmt_create(STMT_IF, NULL, NULL, $2, NULL, $3, $4, NULL);}
|
||||||
;
|
;
|
||||||
else_parts : TOKEN_ELSE_IF booleanexpr statement_list
|
else_parts : else_branch
|
||||||
{$$ = stmt_create(STMT_IF, NULL, NULL, $2, $3, NULL, NULL, NULL);}
|
{$$ = $1;}
|
||||||
|
| else_parts else_branch
|
||||||
|
{$$ = $1; $1->else_body = $2;}
|
||||||
|
else_branch : TOKEN_ELSE_IF booleanexpr simple_stmt
|
||||||
|
{$$ = stmt_create(STMT_IF, NULL, NULL, $2, NULL, $3, NULL, NULL);}
|
||||||
| TOKEN_ELSE simple_stmt
|
| TOKEN_ELSE simple_stmt
|
||||||
{$$ = stmt_create(STMT_IF, NULL, NULL, NULL, NULL, $2, NULL, NULL);}
|
{$$ = stmt_create(STMT_IF, NULL, NULL, NULL, NULL, $2, NULL, NULL);}
|
||||||
| TOKEN_END_IF
|
| TOKEN_END_IF
|
||||||
;
|
{$$ = NULL;}
|
||||||
perform_stmt : TOKEN_PERFORM TOKEN_VARYING ident TOKEN_KEYWORD_FROM TOKEN_INTEGER TOKEN_KEYWORD_BY TOKEN_INTEGER TOKEN_UNTIL op_parms
|
perform_stmt : TOKEN_PERFORM TOKEN_VARYING ident TOKEN_KEYWORD_FROM TOKEN_INTEGER TOKEN_KEYWORD_BY TOKEN_INTEGER TOKEN_UNTIL op_parms
|
||||||
| TOKEN_END_PERFORM
|
| TOKEN_END_PERFORM
|
||||||
;
|
;
|
||||||
|
|
@ -257,6 +261,18 @@ data_clause : TOKEN_COMPUTATION_LEVEL_0
|
||||||
{$$ = type_create(TYPE_ALPHANUMERIC, NULL); $$->level = LEVEL_3;}
|
{$$ = type_create(TYPE_ALPHANUMERIC, NULL); $$->level = LEVEL_3;}
|
||||||
|
|
|
|
||||||
;
|
;
|
||||||
|
category_value : TOKEN_KEYWORD_VALUE TOKEN_INTEGER
|
||||||
|
{$$ = expr_create_integer_literal(atoi(yytext));}
|
||||||
|
| TOKEN_KEYWORD_OCCURS TOKEN_INTEGER
|
||||||
|
{$$ = expr_create_integer_literal(atoi(yytext));}
|
||||||
|
|
|
||||||
|
{$$ = expr_create(EXPR_NULL, NULL, NULL);}
|
||||||
|
;
|
||||||
|
category_spec : complete_category
|
||||||
|
{$$ = decl_create(NULL, $1, NULL, NULL, NULL);}
|
||||||
|
| complete_category data_clause category_value
|
||||||
|
{ $$ = decl_create(NULL, $1, $3, NULL, $2);}
|
||||||
|
;
|
||||||
//TODO: implement levels
|
//TODO: implement levels
|
||||||
simple_decl : TOKEN_INTEGER ident TOKEN_DOT
|
simple_decl : TOKEN_INTEGER ident TOKEN_DOT
|
||||||
{$$ = decl_create($2, NULL, NULL, NULL, NULL);}
|
{$$ = decl_create($2, NULL, NULL, NULL, NULL);}
|
||||||
|
|
@ -264,17 +280,8 @@ simple_decl : TOKEN_INTEGER ident TOKEN_DOT
|
||||||
complex_decl : TOKEN_INTEGER ident TOKEN_PICTURE category_spec TOKEN_DOT
|
complex_decl : TOKEN_INTEGER ident TOKEN_PICTURE category_spec TOKEN_DOT
|
||||||
{$$ = decl_create($2, $4->type, $4->value, NULL, NULL);}
|
{$$ = decl_create($2, $4->type, $4->value, NULL, NULL);}
|
||||||
;
|
;
|
||||||
category_value : TOKEN_KEYWORD_VALUE TOKEN_INTEGER
|
|
||||||
{$$ = expr_create_integer_literal(atoi(yytext));}
|
|
||||||
| TOKEN_KEYWORD_OCCURS TOKEN_INTEGER
|
|
||||||
{$$ = expr_create_integer_literal(atoi(yytext));}
|
|
||||||
|
|
|
||||||
;
|
|
||||||
category_spec : complete_category
|
|
||||||
{$$ = decl_create(NULL, $1, NULL, NULL, NULL);}
|
|
||||||
| complete_category data_clause category_value
|
|
||||||
{ $$ = decl_create(NULL, $1, $3, NULL, $2);}
|
|
||||||
;
|
|
||||||
data_declaration: simple_decl
|
data_declaration: simple_decl
|
||||||
{$$ = $1;}
|
{$$ = $1;}
|
||||||
| complex_decl
|
| complex_decl
|
||||||
|
|
|
||||||
|
|
@ -30,4 +30,5 @@
|
||||||
DISPLAY "Root: " root1
|
DISPLAY "Root: " root1
|
||||||
ELSE
|
ELSE
|
||||||
DISPLAY "The equation has no real roots."
|
DISPLAY "The equation has no real roots."
|
||||||
|
END-IF
|
||||||
STOP RUN.
|
STOP RUN.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue