Merge branch 'josh_bison' into 'main'
Fix bison parser See merge request lustje/language-interpreter-lab!9
This commit is contained in:
commit
ff8119ee56
|
|
@ -16,7 +16,7 @@ UTEST_MAIN();
|
|||
|
||||
UTEST(parser, math) {
|
||||
// Must include the null character to terminate input
|
||||
char string[] = "1+8/4-3;\0";
|
||||
char string[] = "COMPUTE A = (b ** 2) - (4 * a * c)\0";
|
||||
YY_BUFFER_STATE buffer = yy_scan_buffer(string, sizeof(string));
|
||||
|
||||
yylineno = 1;
|
||||
|
|
@ -28,20 +28,6 @@ UTEST(parser, math) {
|
|||
ASSERT_EQ(result, 0);
|
||||
}
|
||||
|
||||
UTEST(parser, missing_semi_colon) {
|
||||
// Must include the null character to terminate input
|
||||
char string[] = "1+8/4-3\0";
|
||||
YY_BUFFER_STATE buffer = yy_scan_buffer(string, sizeof(string));
|
||||
|
||||
yylineno = 1;
|
||||
int result = yyparse();
|
||||
|
||||
yy_delete_buffer(buffer);
|
||||
|
||||
// Assert the result to test correctness
|
||||
ASSERT_EQ(result, 1);
|
||||
}
|
||||
|
||||
UTEST(parser, hello) {
|
||||
// Read sample file as input
|
||||
yyin = fopen("samples/hello-world.cbl", "r");
|
||||
|
|
@ -71,7 +57,7 @@ UTEST(parser, print) {
|
|||
|
||||
UTEST(parser, branching) {
|
||||
// Must include the null character to terminate input
|
||||
char string[] = "IF A > B THEN DISPLAY 'A is greater than B' ELSE DISPLAY 'B is greater than A'\0";
|
||||
char string[] = "IF A > B DISPLAY 'A is greater than B' ELSE DISPLAY 'B is greater than A'\0";
|
||||
YY_BUFFER_STATE buffer = yy_scan_buffer(string, sizeof(string));
|
||||
|
||||
yylineno = 1;
|
||||
|
|
@ -81,10 +67,23 @@ UTEST(parser, branching) {
|
|||
|
||||
// Assert the result to test correctness
|
||||
ASSERT_EQ(result, 0);
|
||||
}
|
||||
}
|
||||
|
||||
UTEST(parser, looping) {
|
||||
char string[] = "PERFORM VARYING I FROM 1 BY 1 UNTIL I > 10 MOVE I TO A(I)\0";
|
||||
char string[] = "PERFORM VARYING I FROM 1 BY 1 UNTIL I > 10\0";
|
||||
YY_BUFFER_STATE buffer = yy_scan_buffer(string, sizeof(string));
|
||||
|
||||
yylineno = 1;
|
||||
int result = yyparse();
|
||||
|
||||
yy_delete_buffer(buffer);
|
||||
|
||||
// Assert the result to test correctness
|
||||
ASSERT_EQ(result, 0);
|
||||
}
|
||||
|
||||
UTEST(parser, assignment) {
|
||||
char string[] = "MOVE I TO A(I) MOVE 1 TO I COMPUTE discriminant = (b ** 2) - (4 * a * c)\0";
|
||||
YY_BUFFER_STATE buffer = yy_scan_buffer(string, sizeof(string));
|
||||
|
||||
yylineno = 1;
|
||||
|
|
@ -121,17 +120,3 @@ UTEST(parser, quadratic) {
|
|||
// Assert the result to test correctness
|
||||
ASSERT_EQ(result, 0);
|
||||
}
|
||||
|
||||
UTEST(parser, boolean) {
|
||||
// Must include the null character to terminate input
|
||||
char string[] = "IF A > B THEN Var = TRUE ELSE Var = FALSE\0";
|
||||
YY_BUFFER_STATE buffer = yy_scan_buffer(string, sizeof(string));
|
||||
|
||||
yylineno = 1;
|
||||
int result = yyparse();
|
||||
|
||||
yy_delete_buffer(buffer);
|
||||
|
||||
// Assert the result to test correctness
|
||||
ASSERT_EQ(result, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ int yylex();
|
|||
%define parse.error detailed
|
||||
|
||||
%token TOKEN_EOF
|
||||
%token TOKEN_IDENTIFICATION
|
||||
%token TOKEN_KEYWORD_IDENTIFICATION
|
||||
%token TOKEN_KEYWORD_DIVISION
|
||||
%token TOKEN_KEYWORD_DATA
|
||||
%token TOKEN_KEYWORD_SECTION
|
||||
|
|
@ -28,6 +28,8 @@ int yylex();
|
|||
%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
|
||||
|
|
@ -60,6 +62,7 @@ int yylex();
|
|||
%token TOKEN_EXPONENTIAL
|
||||
%token TOKEN_DISPLAY
|
||||
|
||||
|
||||
%%
|
||||
file : statements
|
||||
statements : statements statement
|
||||
|
|
@ -68,22 +71,98 @@ statements : statements statement
|
|||
statement : section
|
||||
| sect_data
|
||||
| simple_stmt
|
||||
| data_space
|
||||
| data_declaration
|
||||
;
|
||||
|
||||
section : type TOKEN_KEYWORD_DIVISION TOKEN_DOT
|
||||
| type TOKEN_RUN TOKEN_DOT
|
||||
;
|
||||
sect_data : TOKEN_PROGRAM_ID TOKEN_DOT TOKEN_IDENT TOKEN_DOT
|
||||
sect_data : TOKEN_PROGRAM_ID TOKEN_DOT TOKEN_IDENT TOKEN_DOT
|
||||
;
|
||||
type : TOKEN_IDENTIFICATION
|
||||
type : TOKEN_KEYWORD_IDENTIFICATION
|
||||
| TOKEN_PROCEDURE
|
||||
| TOKEN_STOP
|
||||
| TOKEN_KEYWORD_DATA
|
||||
;
|
||||
simple_stmt : function
|
||||
simple_stmt : cbl_function
|
||||
| cbl_function op_parms
|
||||
| cbl_function assignment_stmt
|
||||
| cbl_function op_parms assignment_stmt
|
||||
| if_branch
|
||||
| perform_stmt
|
||||
;
|
||||
function : TOKEN_DISPLAY parms
|
||||
;
|
||||
parms : TOKEN_STRING
|
||||
assignment_stmt : TOKEN_EQUAL ext_function
|
||||
| TOKEN_EQUAL function
|
||||
| TOKEN_KEYWORD_TO op_parms
|
||||
;
|
||||
op_parms : op_parms TOKEN_ADD op_parms
|
||||
| op_parms TOKEN_SUB op_parms
|
||||
| op_parms TOKEN_MULTIPLY op_parms
|
||||
| op_parms TOKEN_DIVIDE op_parms
|
||||
| op_parms TOKEN_EXPONENTIAL op_parms
|
||||
| op_parms TOKEN_LESS_THAN op_parms
|
||||
| op_parms TOKEN_GREATER_THAN op_parms
|
||||
| op_parms TOKEN_EQUAL op_parms
|
||||
| TOKEN_SUB op_parms
|
||||
| TOKEN_LEFT_PARENTHESIS op_parms TOKEN_RIGHT_PARENTHESIS
|
||||
| TOKEN_IDENT
|
||||
| TOKEN_INTEGER
|
||||
| TOKEN_STRING
|
||||
| TOKEN_SPACE
|
||||
| op_parms op_parms
|
||||
;
|
||||
function : op_parms
|
||||
;
|
||||
ext_function : TOKEN_KEYWORD_FUNCTION TOKEN_IDENT TOKEN_LEFT_PARENTHESIS TOKEN_IDENT TOKEN_RIGHT_PARENTHESIS
|
||||
;
|
||||
cbl_function : TOKEN_DISPLAY
|
||||
| TOKEN_MOVE
|
||||
| TOKEN_KEYWORD_COMPUTE
|
||||
| TOKEN_PERFORM
|
||||
;
|
||||
if_branch : TOKEN_IF op_parms
|
||||
| TOKEN_ELSE_IF op_parms
|
||||
| TOKEN_ELSE statement
|
||||
| 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: complete_category complete_category
|
||||
| data_category categry_contain
|
||||
;
|
||||
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
|
||||
;
|
||||
full_decl : TOKEN_INTEGER TOKEN_IDENT TOKEN_PICTURE complete_category TOKEN_DOT
|
||||
| TOKEN_INTEGER TOKEN_IDENT TOKEN_PICTURE complete_category full_data_clause TOKEN_DOT
|
||||
| TOKEN_INTEGER TOKEN_IDENT TOKEN_PICTURE complete_category full_data_clause TOKEN_INTEGER TOKEN_DOT
|
||||
;
|
||||
data_declaration: simple_decl
|
||||
| full_decl
|
||||
;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
IDENTIFICATION DIVISION.
|
||||
PROGRAM-ID. variables.
|
||||
DATA DIVISION.
|
||||
WORKING-STORAGE SECTION.
|
||||
01 WS-SORT-AREA.
|
||||
05 WS-SORT-TABLE.
|
||||
10 WS-SORT-ROW PIC X(10) OCCURS 100.
|
||||
05 WS-TEMP-ROW PIC X(10).
|
||||
05 WS-ROW-MAX PIC S9(4) COMP VALUE 100.
|
||||
05 WS-SORT-MAX PIC S9(4) COMP.
|
||||
05 WS-I PIC S9(4) COMP.
|
||||
05 WS-J PIC S9(4) COMP.
|
||||
05 WS-INDEX PIC S9(4) COMP.
|
||||
77 a PIC S9(5)V9(5) COMP-3 VALUE 1.
|
||||
77 b PIC S9(5)V9(5) COMP-3 VALUE 5.
|
||||
77 c PIC S9(5)V9(5) COMP-3 VALUE 6.
|
||||
77 discriminant PIC S9(5)V9(5) COMP-3.
|
||||
77 root1 PIC S9(5)V9(5) COMP-3.
|
||||
77 root2 PIC S9(5)V9(5) COMP-3.
|
||||
77 square-root-discriminant PIC S9(5)V9(5) COMP-3.
|
||||
|
||||
PROCEDURE DIVISION.
|
||||
DISPLAY 'Hello World!'
|
||||
STOP RUN.
|
||||
|
|
@ -6,8 +6,8 @@ DIGIT [0-9]+
|
|||
%%
|
||||
|
||||
(" "|\t|\n) /* skip whitespace */
|
||||
\*>\ ?.* { return TOKEN_COMMENT; }
|
||||
IDENTIFICATION { return TOKEN_IDENTIFICATION; }
|
||||
\*>\ ?.*
|
||||
IDENTIFICATION { return TOKEN_KEYWORD_IDENTIFICATION; }
|
||||
DIVISION { return TOKEN_KEYWORD_DIVISION; }
|
||||
PROGRAM-ID { return TOKEN_PROGRAM_ID; }
|
||||
PROCEDURE { return TOKEN_PROCEDURE; }
|
||||
|
|
|
|||
125
lab-4/token.h
125
lab-4/token.h
|
|
@ -1,125 +0,0 @@
|
|||
/* A Bison parser, made by GNU Bison 3.8.2. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
|
||||
especially those whose name start with YY_ or yy_. They are
|
||||
private implementation details that can be changed or removed. */
|
||||
|
||||
#ifndef YY_YY_TOKEN_H_INCLUDED
|
||||
# define YY_YY_TOKEN_H_INCLUDED
|
||||
/* Debug traces. */
|
||||
#ifndef YYDEBUG
|
||||
# define YYDEBUG 1
|
||||
#endif
|
||||
#if YYDEBUG
|
||||
extern int yydebug;
|
||||
#endif
|
||||
|
||||
/* Token kinds. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
enum yytokentype
|
||||
{
|
||||
YYEMPTY = -2,
|
||||
YYEOF = 0, /* "end of file" */
|
||||
YYerror = 256, /* error */
|
||||
YYUNDEF = 257, /* "invalid token" */
|
||||
TOKEN_EOF = 258, /* TOKEN_EOF */
|
||||
TOKEN_IDENTIFICATION = 259, /* TOKEN_IDENTIFICATION */
|
||||
TOKEN_KEYWORD_DIVISION = 260, /* TOKEN_KEYWORD_DIVISION */
|
||||
TOKEN_KEYWORD_DATA = 261, /* TOKEN_KEYWORD_DATA */
|
||||
TOKEN_KEYWORD_SECTION = 262, /* TOKEN_KEYWORD_SECTION */
|
||||
TOKEN_PROGRAM_ID = 263, /* TOKEN_PROGRAM_ID */
|
||||
TOKEN_WORKING_STORAGE = 264, /* TOKEN_WORKING_STORAGE */
|
||||
TOKEN_PROCEDURE = 265, /* TOKEN_PROCEDURE */
|
||||
TOKEN_STOP = 266, /* TOKEN_STOP */
|
||||
TOKEN_RUN = 267, /* TOKEN_RUN */
|
||||
TOKEN_MOVE = 268, /* TOKEN_MOVE */
|
||||
TOKEN_KEYWORD_TO = 269, /* TOKEN_KEYWORD_TO */
|
||||
TOKEN_PERFORM = 270, /* TOKEN_PERFORM */
|
||||
TOKEN_VARYING = 271, /* TOKEN_VARYING */
|
||||
TOKEN_KEYWORD_FROM = 272, /* TOKEN_KEYWORD_FROM */
|
||||
TOKEN_KEYWORD_BY = 273, /* TOKEN_KEYWORD_BY */
|
||||
TOKEN_UNTIL = 274, /* TOKEN_UNTIL */
|
||||
TOKEN_END_PERFORM = 275, /* TOKEN_END_PERFORM */
|
||||
TOKEN_IF = 276, /* TOKEN_IF */
|
||||
TOKEN_END_IF = 277, /* TOKEN_END_IF */
|
||||
TOKEN_SPACE = 278, /* TOKEN_SPACE */
|
||||
TOKEN_KEYWORD_OCCURS = 279, /* TOKEN_KEYWORD_OCCURS */
|
||||
TOKEN_KEYWORD_VALUE = 280, /* TOKEN_KEYWORD_VALUE */
|
||||
TOKEN_KEYWORD_COMPUTE = 281, /* TOKEN_KEYWORD_COMPUTE */
|
||||
TOKEN_KEYWORD_FUNCTION = 282, /* TOKEN_KEYWORD_FUNCTION */
|
||||
TOKEN_IDENT = 283, /* TOKEN_IDENT */
|
||||
TOKEN_STRING = 284, /* TOKEN_STRING */
|
||||
TOKEN_INTEGER = 285, /* TOKEN_INTEGER */
|
||||
TOKEN_PICTURE = 286, /* TOKEN_PICTURE */
|
||||
TOKEN_ALPHANUMERIC = 287, /* TOKEN_ALPHANUMERIC */
|
||||
TOKEN_NUMERIC = 288, /* TOKEN_NUMERIC */
|
||||
TOKEN_SIGNED_NUMERIC = 289, /* TOKEN_SIGNED_NUMERIC */
|
||||
TOKEN_IMPLIED_DECIMAL = 290, /* TOKEN_IMPLIED_DECIMAL */
|
||||
TOKEN_COMPUTATION_LEVEL_0 = 291, /* TOKEN_COMPUTATION_LEVEL_0 */
|
||||
TOKEN_COMPUTATION_LEVEL_1 = 292, /* TOKEN_COMPUTATION_LEVEL_1 */
|
||||
TOKEN_COMPUTATION_LEVEL_2 = 293, /* TOKEN_COMPUTATION_LEVEL_2 */
|
||||
TOKEN_COMPUTATION_LEVEL_3 = 294, /* TOKEN_COMPUTATION_LEVEL_3 */
|
||||
TOKEN_LEFT_PARENTHESIS = 295, /* TOKEN_LEFT_PARENTHESIS */
|
||||
TOKEN_RIGHT_PARENTHESIS = 296, /* TOKEN_RIGHT_PARENTHESIS */
|
||||
TOKEN_DOT = 297, /* TOKEN_DOT */
|
||||
TOKEN_COMMENT = 298, /* TOKEN_COMMENT */
|
||||
TOKEN_ADD = 299, /* TOKEN_ADD */
|
||||
TOKEN_SUB = 300, /* TOKEN_SUB */
|
||||
TOKEN_MULTIPLY = 301, /* TOKEN_MULTIPLY */
|
||||
TOKEN_DIVIDE = 302, /* TOKEN_DIVIDE */
|
||||
TOKEN_EQUAL = 303, /* TOKEN_EQUAL */
|
||||
TOKEN_GREATER_THAN = 304, /* TOKEN_GREATER_THAN */
|
||||
TOKEN_LESS_THAN = 305, /* TOKEN_LESS_THAN */
|
||||
TOKEN_EXPONENTIAL = 306, /* TOKEN_EXPONENTIAL */
|
||||
TOKEN_DISPLAY = 307 /* TOKEN_DISPLAY */
|
||||
};
|
||||
typedef enum yytokentype yytoken_kind_t;
|
||||
#endif
|
||||
|
||||
/* Value type. */
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef int YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
|
||||
int yyparse (void);
|
||||
|
||||
|
||||
#endif /* !YY_YY_TOKEN_H_INCLUDED */
|
||||
Loading…
Reference in New Issue