-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparser.y
156 lines (137 loc) · 3.33 KB
/
parser.y
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
%{
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "error.h"
#define MAX_LINE_LENG 256
extern int line_no, chr_no, opt_list;
extern char buffer[MAX_LINE_LENG];
extern FILE *yyin; /* declared by lex */
extern char *yytext; /* declared by lex */
extern int yyleng;
extern int yylex(void);
static void yyerror(const char *msg);
%}
%token PROGRAM VAR ARRAY OF INTEGER REAL STRING FUNCTION PROCEDURE PBEGIN END IF THEN ELSE WHILE DO NOT AND OR
%token LPAREN RPAREN SEMICOLON DOT COMMA COLON LBRACE RBRACE DOTDOT ASSIGNMENT ADDOP SUBOP MULOP DIVOP LTOP GTOP EQOP GETOP LETOP NEQOP
%token IDENTIFIER REALNUMBER INTEGERNUM SCIENTIFIC LITERALSTR NUMBER
%union {
int val;
char* text;
double dval;
}
%%
prog : PROGRAM IDENTIFIER LPAREN identifier_list RPAREN SEMICOLON
declarations
subprogram_declarations
compound_statement
DOT
;
identifier_list : IDENTIFIER
| identifier_list COMMA IDENTIFIER
;
declarations : declarations VAR identifier_list COLON type SEMICOLON
|
;
type : standard_type
| ARRAY LBRACE NUMBER DOTDOT NUMBER RBRACE OF type
standard_type : INTEGER
| REAL
| STRING
;
subprogram_declarations :
subprogram_declarations subprogram_declaration SEMICOLON
|
;
subprogram_declaration :
subprogram_head
declarations
subprogram_declarations
compound_statement
;
subprogram_head : FUNCTION IDENTIFIER arguments COLON standard_type SEMICOLON
| PROCEDURE IDENTIFIER arguments SEMICOLON
;
arguments : LPAREN parameter_list RPAREN
|
;
parameter_list : optional_var identifier_list COLON type
| optional_var identifier_list COLON type SEMICOLON parameter_list
;
optional_var : VAR
|
;
compound_statement : PBEGIN
optional_statements
END
;
optional_statements : standard_list
|
;
standard_list : statement
| standard_list SEMICOLON statement
statement : variable ASSIGNMENT expression
| procedure_statement
| compound_statement
| IF expression THEN statement ELSE statement
| WHILE expression DO statement
|
;
variable : IDENTIFIER tail
;
tail : LBRACE expression RBRACE tail
|
;
procedure_statement : IDENTIFIER
| IDENTIFIER LPAREN expression_list RPAREN
;
expression_list : expression
| expression_list COMMA expression
expression : boolexpression
| boolexpression AND boolexpression
| boolexpression OR boolexpression
;
boolexpression : simple_expression
| simple_expression relop simple_expression
;
simple_expression : term
| simple_expression addop term
;
term : factor
| term mulop factor
;
factor : IDENTIFIER tail
| IDENTIFIER LPAREN expression_list RPAREN
| NUMBER
| LITERALSTR
| LPAREN expression RPAREN
| NOT factor
| SUBOP factor
;
addop : ADDOP | SUBOP
;
mulop : MULOP | DIVOP
;
relop : LTOP
| GTOP
| EQOP
| LETOP
| GETOP
| NEQOP
;
%%
void yyerror(const char *msg) {
fprintf(stderr,
"[ERROR] line %4d:%3d %s, Unmatched token: %s\n",
line_no, chr_no-(int)yyleng+1, buffer, yytext);
}
int main(int argc, const char *argv[]) {
if(argc > 2)
fprintf( stderr, "Usage: ./parser [filename]\n" ), exit(0);
FILE *fp = argc == 1 ? stdin : fopen(argv[1], "r");
if(fp == NULL)
fprintf( stderr, "Open file error\n" ), exit(-1);
yyin = fp;
yyparse();
return 0;
}