compilers-lab1/parser.y

312 lines
7.5 KiB
Text
Raw Normal View History

2025-03-24 18:40:16 +08:00
%{
#include <stdio.h>
#include "node.h"
extern int yylex(void);
extern int yylineno;
int errors = 0;
struct node;
void yyerror(char const *);
pNode root;
%}
%define api.value.type {struct node*}
%token INTEGER FLOAT
%token SEMI COMMA ASSIGNOP PLUS MINUS TIMES DIV AND OR DOT NOT LP RP LB RB LC RC STRUCT RETURN IF ELSE WHILE
%token TYPE_INT TYPE_FLOAT ID
%token LINE_COMMENT BLOCK_COMMENT
%%
// High-level Definitions
Program:
ExtDefList {
pNode children[1] = { $1 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Program, $1->line, 1, children, nullValue());
2025-03-24 18:40:16 +08:00
root = $$;
}
;
ExtDefList:
ExtDef ExtDefList {
pNode children[2] = { $1, $2 };
2025-03-26 10:38:10 +08:00
$$ = newNode(ExtDefList, $1->line, 2, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| {
$$ = newNode(ExtDefList, -1, 0, NULL, nullValue());
}
;
ExtDef:
Specifier ExtDecList SEMI {
pNode children[3] = { $1, $2, $3 };
2025-03-26 10:38:10 +08:00
$$ = newNode(ExtDef, $1->line, 3, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| Specifier SEMI {
pNode children[2] = { $1, $2 };
2025-03-26 10:38:10 +08:00
$$ = newNode(ExtDef, $1->line, 2, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| Specifier FunDec CompSt {
pNode children[3] = { $1, $2, $3 };
2025-03-26 10:38:10 +08:00
$$ = newNode(ExtDef, $1->line, 3, children, nullValue());
2025-03-24 18:40:16 +08:00
}
;
ExtDecList:
VarDec {
pNode children[1] = { $1 };
2025-03-26 10:38:10 +08:00
$$ = newNode(ExtDecList, $1->line, 1, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| VarDec COMMA ExtDecList {
pNode children[3] = { $1, $2, $3 };
2025-03-26 10:38:10 +08:00
$$ = newNode(ExtDecList, $1->line, 3, children, nullValue());
2025-03-24 18:40:16 +08:00
}
;
// Specifiers
Specifier:
TYPE_INT {
pNode children[1] = { $1 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Specifier, $1->line, 1, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| TYPE_FLOAT {
pNode children[1] = { $1 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Specifier, $1->line, 1, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| StructSpecifier {
pNode children[1] = { $1 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Specifier, $1->line, 1, children, nullValue());
2025-03-24 18:40:16 +08:00
}
;
StructSpecifier:
STRUCT OptTag LC DefList RC {
pNode children[5] = { $1, $2, $3, $4, $5 };
2025-03-26 10:38:10 +08:00
$$ = newNode(StructSpecifier, $1->line, 5, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| STRUCT Tag {
pNode children[2] = { $1, $2 };
2025-03-26 10:38:10 +08:00
$$ = newNode(StructSpecifier, $1->line, 2, children, nullValue());
2025-03-24 18:40:16 +08:00
}
;
OptTag:
ID {
pNode children[1] = { $1 };
2025-03-26 10:38:10 +08:00
$$ = newNode(OptTag, $1->line, 1, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| {
$$ = newNode(OptTag, -1, 0, NULL, nullValue());
}
;
Tag:
ID {
pNode children[1] = { $1 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Tag, $1->line, 1, children, nullValue());
2025-03-24 18:40:16 +08:00
}
;
// Declarators
VarDec:
ID {
pNode children[1] = { $1 };
2025-03-26 10:38:10 +08:00
$$ = newNode(VarDec, $1->line, 1, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| VarDec LB INTEGER RB {
pNode children[4] = { $1, $2, $3, $4 };
2025-03-26 10:38:10 +08:00
$$ = newNode(VarDec, $1->line, 4, children, nullValue());
2025-03-24 18:40:16 +08:00
}
;
FunDec:
ID LP VarList RP {
pNode children[4] = { $1, $2, $3, $4 };
2025-03-26 10:38:10 +08:00
$$ = newNode(FunDec, $1->line, 4, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| ID LP RP {
pNode children[3] = { $1, $2, $3 };
2025-03-26 10:38:10 +08:00
$$ = newNode(FunDec, $1->line, 3, children, nullValue());
2025-03-24 18:40:16 +08:00
}
;
VarList:
ParamDec COMMA VarList {
pNode children[3] = { $1, $2, $3 };
2025-03-26 10:38:10 +08:00
$$ = newNode(VarList, $1->line, 3, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| ParamDec {
pNode children[1] = { $1 };
2025-03-26 10:38:10 +08:00
$$ = newNode(VarList, $1->line, 1, children, nullValue());
2025-03-24 18:40:16 +08:00
}
;
ParamDec:
Specifier VarDec {
pNode children[1] = { $1 };
2025-03-26 10:38:10 +08:00
$$ = newNode(ParamDec, $1->line, 1, children, nullValue());
2025-03-24 18:40:16 +08:00
}
;
// Statements
CompSt:
LC DefList StmtList RC {
pNode children[4] = { $1, $2, $3, $4 };
2025-03-26 10:38:10 +08:00
$$ = newNode(CompSt, $1->line, 4, children, nullValue());
2025-03-24 18:40:16 +08:00
}
;
StmtList:
Stmt StmtList {
pNode children[2] = { $1, $2 };
2025-03-26 10:38:10 +08:00
$$ = newNode(StmtList, $1->line, 2, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| {
$$ = newNode(StmtList, -1, 0, NULL, nullValue());
}
;
Stmt:
Exp SEMI {
pNode children[2] = { $1, $2 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Stmt, $1->line, 2, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| CompSt {
pNode children[1] = { $1 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Stmt, $1->line, 1, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| RETURN Exp SEMI {
pNode children[3] = { $1, $2, $3 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Stmt, $1->line, 3, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| IF LP Exp RP Stmt {
pNode children[5] = { $1, $2, $3, $4, $5 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Stmt, $1->line, 5, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| IF LP Exp RP Stmt ELSE Stmt {
pNode children[7] = { $1, $2, $3, $4, $5, $6, $7 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Stmt, $1->line, 7, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| WHILE LP Exp RP Stmt {
pNode children[5] = { $1, $2, $3, $4, $5 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Stmt, $1->line, 5, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| error SEMI
;
// Local Definitions
DefList:
Def DefList {
pNode children[2] = { $1, $2 };
2025-03-26 10:38:10 +08:00
$$ = newNode(DefList, $1->line, 2, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| {
$$ = newNode(DefList, -1, 0, NULL, nullValue());
}
;
Def:
Specifier DecList SEMI {
pNode children[3] = { $1, $2, $3 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Def, $1->line, 3, children, nullValue());
2025-03-24 18:40:16 +08:00
}
;
DecList:
Dec {
pNode children[1] = { $1 };
2025-03-26 10:38:10 +08:00
$$ = newNode(DecList, $1->line, 1, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| Dec COMMA DecList {
pNode children[3] = { $1, $2, $3 };
2025-03-26 10:38:10 +08:00
$$ = newNode(DecList, $1->line, 3, children, nullValue());
2025-03-24 18:40:16 +08:00
}
;
Dec:
VarDec {
pNode children[1] = { $1 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Dec, $1->line, 1, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| VarDec ASSIGNOP Exp {
pNode children[3] = { $1, $2, $3 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Dec, $1->line, 3, children, nullValue());
2025-03-24 18:40:16 +08:00
}
;
// Expressions
Exp:
Exp ASSIGNOP Exp {
pNode children[3] = { $1, $2, $3 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Exp, $1->line, 3, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| Exp AND Exp {
pNode children[3] = { $1, $2, $3 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Exp, $1->line, 3, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| Exp OR Exp {
pNode children[3] = { $1, $2, $3 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Exp, $1->line, 3, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| Exp PLUS Exp {
pNode children[3] = { $1, $2, $3 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Exp, $1->line, 3, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| Exp MINUS Exp {
pNode children[3] = { $1, $2, $3 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Exp, $1->line, 3, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| Exp TIMES Exp {
pNode children[3] = { $1, $2, $3 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Exp, $1->line, 3, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| Exp DIV Exp {
pNode children[3] = { $1, $2, $3 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Exp, $1->line, 3, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| LP Exp RP {
pNode children[3] = { $1, $2, $3 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Exp, $1->line, 3, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| MINUS Exp {
pNode children[2] = { $1, $2 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Exp, $1->line, 2, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| NOT Exp {
pNode children[2] = { $1, $2 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Exp, $1->line, 2, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| ID LP Args RP {
pNode children[4] = { $1, $2, $3, $4 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Exp, $1->line, 4, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| ID LP RP {
pNode children[3] = { $1, $2, $3 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Exp, $1->line, 3, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| Exp LB Exp RB {
pNode children[4] = { $1, $2, $3, $4 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Exp, $1->line, 4, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| Exp DOT ID {
pNode children[3] = { $1, $2, $3 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Exp, $1->line, 3, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| ID {
pNode children[1] = { $1 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Exp, $1->line, 1, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| INTEGER {
pNode children[1] = { $1 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Exp, $1->line, 1, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| FLOAT {
pNode children[1] = { $1 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Exp, $1->line, 1, children, nullValue());
2025-03-24 18:40:16 +08:00
}
;
Args:
Exp COMMA Args {
pNode children[3] = { $1, $2, $3 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Args, $1->line, 3, children, nullValue());
2025-03-24 18:40:16 +08:00
}
| Exp {
pNode children[1] = { $1 };
2025-03-26 10:38:10 +08:00
$$ = newNode(Exp, $1->line, 1, children, nullValue());
2025-03-24 18:40:16 +08:00
}
;
%%
void yyerror(char const *s) {
errors += 1;
fprintf(stderr, "Error type B at Line %d: \"%s\".\n", yylineno, s);
}