245 lines
8.1 KiB
Plaintext
245 lines
8.1 KiB
Plaintext
%{
|
|
#define YYDEBUG 1
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "expr.h"
|
|
|
|
/*
|
|
YYSTYPE is the lexical value returned by each rule in a bison grammar.
|
|
By default, it is an integer. In this example, we are returning a pointer to an expression.
|
|
*/
|
|
|
|
#define YYSTYPE struct stmt *
|
|
|
|
/*
|
|
Clunky: Manually declare the interface to the scanner generated by flex.
|
|
*/
|
|
|
|
extern char *yytext;
|
|
extern int yylex();
|
|
void yyerror(const char*);
|
|
|
|
extern int yylineno;
|
|
|
|
struct stmt *parser_result = 0;
|
|
|
|
%}
|
|
|
|
%debug
|
|
%define parse.error detailed
|
|
|
|
%token TOKEN_EOF
|
|
%token TOKEN_KEYWORD_IDENTIFICATION
|
|
%token TOKEN_KEYWORD_DIVISION
|
|
%token TOKEN_KEYWORD_DATA
|
|
%token TOKEN_KEYWORD_SECTION
|
|
%token TOKEN_PROGRAM_ID
|
|
%token TOKEN_WORKING_STORAGE
|
|
%token TOKEN_PROCEDURE
|
|
%token TOKEN_STOP
|
|
%token TOKEN_RUN
|
|
%token TOKEN_MOVE
|
|
%token TOKEN_KEYWORD_TO
|
|
%token TOKEN_PERFORM
|
|
%token TOKEN_VARYING
|
|
%token TOKEN_KEYWORD_FROM
|
|
%token TOKEN_KEYWORD_BY
|
|
%token TOKEN_UNTIL
|
|
%token TOKEN_END_PERFORM
|
|
%token TOKEN_IF
|
|
%token TOKEN_ELSE_IF
|
|
%token TOKEN_ELSE
|
|
%token TOKEN_END_IF
|
|
%token TOKEN_SPACE
|
|
%token TOKEN_KEYWORD_OCCURS
|
|
%token TOKEN_KEYWORD_VALUE
|
|
%token TOKEN_KEYWORD_COMPUTE
|
|
%token TOKEN_KEYWORD_FUNCTION
|
|
%token TOKEN_IDENT
|
|
%token TOKEN_STRING
|
|
%token TOKEN_INTEGER
|
|
%token TOKEN_PICTURE
|
|
%token TOKEN_ALPHANUMERIC
|
|
%token TOKEN_NUMERIC
|
|
%token TOKEN_SIGNED_NUMERIC
|
|
%token TOKEN_IMPLIED_DECIMAL
|
|
%token TOKEN_COMPUTATION_LEVEL_0
|
|
%token TOKEN_COMPUTATION_LEVEL_1
|
|
%token TOKEN_COMPUTATION_LEVEL_2
|
|
%token TOKEN_COMPUTATION_LEVEL_3
|
|
%token TOKEN_LEFT_PARENTHESIS
|
|
%token TOKEN_RIGHT_PARENTHESIS
|
|
%token TOKEN_DOT
|
|
%token TOKEN_ADD
|
|
%token TOKEN_SUB
|
|
%token TOKEN_MULTIPLY
|
|
%token TOKEN_DIVIDE
|
|
%token TOKEN_EQUAL
|
|
%token TOKEN_GREATER_THAN
|
|
%token TOKEN_LESS_THAN
|
|
%token TOKEN_EXPONENTIAL
|
|
%token TOKEN_DISPLAY
|
|
|
|
%%
|
|
file : statement_list stop_run
|
|
{parser_result = $1; return 0;}
|
|
;
|
|
statement_list : statement statement_list
|
|
{ $$ = $1; $1->next = $2;}
|
|
| statement
|
|
{ $$ = $1; }
|
|
;
|
|
statement : section
|
|
{$$ = $1;}
|
|
| sect_data
|
|
{$$ = $1;}
|
|
| simple_stmt
|
|
{$$ = stmt_create(STMT_BLOCK, NULL, NULL, NULL, NULL, $1, NULL, NULL);}
|
|
| data_space
|
|
{$$ = stmt_create(STMT_SECTION, NULL, NULL, NULL, NULL, NULL, NULL, NULL);}
|
|
| data_declaration
|
|
{$$ = stmt_create(STMT_BLOCK, NULL, NULL, NULL, NULL, $1, NULL, NULL);}
|
|
;
|
|
section : type TOKEN_KEYWORD_DIVISION TOKEN_DOT
|
|
{$$ = stmt_create(STMT_SECTION, NULL, NULL, NULL, NULL, NULL, NULL, NULL);}
|
|
;
|
|
stop_run : TOKEN_STOP TOKEN_RUN TOKEN_DOT
|
|
{$$ = stmt_create(STMT_SECTION, NULL, NULL, NULL, NULL, NULL, NULL, NULL);}
|
|
;
|
|
sect_data : TOKEN_PROGRAM_ID TOKEN_DOT TOKEN_IDENT TOKEN_DOT
|
|
{$$ = stmt_create(STMT_SECTION, NULL, NULL, NULL, NULL, NULL, NULL, NULL);}
|
|
;
|
|
type : TOKEN_KEYWORD_IDENTIFICATION
|
|
| TOKEN_PROCEDURE
|
|
| TOKEN_KEYWORD_DATA
|
|
;
|
|
simple_stmt : cbl_func_stmt
|
|
{$$ = $1;}
|
|
| if_branch
|
|
| else_parts
|
|
| perform_stmt
|
|
;
|
|
cbl_func_stmt : cbl_function
|
|
| cbl_function op_parms
|
|
{$$ = stmt_create($1->kind, NULL, NULL, $2, NULL, NULL, NULL, NULL);}
|
|
| cbl_function assignment_stmt
|
|
| cbl_function op_parm assignment_stmt
|
|
;
|
|
assignment_stmt : TOKEN_EQUAL op_parms
|
|
| TOKEN_KEYWORD_TO op_parms
|
|
;
|
|
op_parms : op_parm
|
|
{$$ = $1;}
|
|
| op_parm op_parms
|
|
{$$ = $1; $1->next_expr = $2;}
|
|
;
|
|
op_parm : mathmaticalexpr
|
|
{$$ = $1;}
|
|
| booleanexpr
|
|
{$$ = $1;}
|
|
;
|
|
term : mathmaticalexpr
|
|
{$$ = $1;}
|
|
;
|
|
math_op : TOKEN_ADD
|
|
{$$ = expr_create(EXPR_ADD, NULL, NULL);}
|
|
| TOKEN_SUB
|
|
{$$ = expr_create(EXPR_SUBTRACT, NULL, NULL);}
|
|
| TOKEN_MULTIPLY
|
|
{$$ = expr_create(EXPR_MULTIPLY, NULL, NULL);}
|
|
| TOKEN_DIVIDE
|
|
{$$ = expr_create(EXPR_DIVIDE, NULL, NULL);}
|
|
| TOKEN_EXPONENTIAL
|
|
{$$ = expr_create(EXPR_EXPONENTIAL, NULL, NULL);}
|
|
;
|
|
mathmaticalexpr : type_expr
|
|
{$$ = $1;}
|
|
| mathmaticalexpr math_op term
|
|
|
|
| container_expr
|
|
{$$ = $1;}
|
|
| type_expr container_expr
|
|
{$$ = $1; $1->next_expr = $2;}
|
|
;
|
|
container_expr : TOKEN_LEFT_PARENTHESIS mathmaticalexpr TOKEN_RIGHT_PARENTHESIS
|
|
;
|
|
booleanexpr : mathmaticalexpr TOKEN_LESS_THAN term
|
|
{$$ = expr_create(EXPR_LESS_THAN, $1, $3);}
|
|
| mathmaticalexpr TOKEN_GREATER_THAN term
|
|
{$$ = expr_create(EXPR_GREATER_THAN, $1, $3);}
|
|
| mathmaticalexpr TOKEN_EQUAL term
|
|
{$$ = expr_create(EXPR_EQUAL_EQUAL, $1, $3);}
|
|
;
|
|
type_expr : TOKEN_IDENT
|
|
{$$ = expr_create_name(yytext);}
|
|
| TOKEN_INTEGER
|
|
{$$ = expr_create_integer_literal(atoi(yytext));}
|
|
| TOKEN_STRING
|
|
{$$ = expr_create_string_literal(yytext);}
|
|
| TOKEN_SPACE
|
|
{$$ = expr_create_integer_literal(0);}
|
|
| TOKEN_SUB TOKEN_IDENT
|
|
| ext_function
|
|
;
|
|
ext_function : TOKEN_KEYWORD_FUNCTION TOKEN_IDENT TOKEN_LEFT_PARENTHESIS TOKEN_IDENT TOKEN_RIGHT_PARENTHESIS
|
|
|
|
;
|
|
cbl_function : TOKEN_DISPLAY
|
|
{$$ = stmt_create(STMT_PRINT, NULL, NULL, NULL, NULL, NULL, NULL, NULL);}
|
|
| TOKEN_MOVE
|
|
{$$ = stmt_create(STMT_MOVE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);}
|
|
| TOKEN_KEYWORD_COMPUTE
|
|
{$$ = stmt_create(STMT_COMPUTE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);}
|
|
;
|
|
if_branch : TOKEN_IF booleanexpr
|
|
;
|
|
else_parts : TOKEN_ELSE_IF booleanexpr simple_stmt
|
|
| TOKEN_ELSE simple_stmt
|
|
| TOKEN_END_IF
|
|
;
|
|
perform_stmt : TOKEN_PERFORM TOKEN_VARYING TOKEN_IDENT TOKEN_KEYWORD_FROM TOKEN_INTEGER TOKEN_KEYWORD_BY TOKEN_INTEGER TOKEN_UNTIL op_parms
|
|
| TOKEN_END_PERFORM
|
|
;
|
|
data_space : TOKEN_WORKING_STORAGE TOKEN_KEYWORD_SECTION TOKEN_DOT
|
|
;
|
|
data_category : TOKEN_ALPHANUMERIC
|
|
| TOKEN_NUMERIC
|
|
| TOKEN_SIGNED_NUMERIC
|
|
| TOKEN_IMPLIED_DECIMAL
|
|
;
|
|
categry_contain : TOKEN_LEFT_PARENTHESIS TOKEN_INTEGER TOKEN_RIGHT_PARENTHESIS
|
|
| TOKEN_LEFT_PARENTHESIS TOKEN_IDENT TOKEN_RIGHT_PARENTHESIS
|
|
;
|
|
complete_category: data_category categry_contain
|
|
| data_category categry_contain complete_category
|
|
;
|
|
data_clause : TOKEN_COMPUTATION_LEVEL_0
|
|
| TOKEN_COMPUTATION_LEVEL_1
|
|
| TOKEN_COMPUTATION_LEVEL_2
|
|
| TOKEN_COMPUTATION_LEVEL_3
|
|
| TOKEN_KEYWORD_VALUE
|
|
| TOKEN_KEYWORD_OCCURS
|
|
;
|
|
full_data_clause: data_clause data_clause
|
|
| data_clause
|
|
;
|
|
simple_decl : TOKEN_INTEGER TOKEN_IDENT TOKEN_DOT
|
|
;
|
|
complex_decl : TOKEN_INTEGER TOKEN_IDENT TOKEN_PICTURE category_spec TOKEN_DOT
|
|
;
|
|
category_spec : complete_category
|
|
| complete_category data_clauses
|
|
;
|
|
data_clauses : full_data_clause
|
|
| full_data_clause TOKEN_INTEGER
|
|
;
|
|
data_declaration: simple_decl
|
|
| complex_decl
|
|
;
|
|
%%
|
|
void yyerror(const char* msg) {
|
|
fprintf(stderr, "Error | Line: %d\n%s\n",yylineno,msg);
|
|
} |