compilers-lab1/parser.y

311 lines
7.5 KiB
Text

%{
#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 };
$$ = newNode(Program, yylineno, 1, children, nullValue());
root = $$;
}
;
ExtDefList:
ExtDef ExtDefList {
pNode children[2] = { $1, $2 };
$$ = newNode(ExtDefList, yylineno, 2, children, nullValue());
}
| {
$$ = newNode(ExtDefList, -1, 0, NULL, nullValue());
}
;
ExtDef:
Specifier ExtDecList SEMI {
pNode children[3] = { $1, $2, $3 };
$$ = newNode(ExtDef, yylineno, 3, children, nullValue());
}
| Specifier SEMI {
pNode children[2] = { $1, $2 };
$$ = newNode(ExtDef, yylineno, 2, children, nullValue());
}
| Specifier FunDec CompSt {
pNode children[3] = { $1, $2, $3 };
$$ = newNode(ExtDef, yylineno, 3, children, nullValue());
}
;
ExtDecList:
VarDec {
pNode children[1] = { $1 };
$$ = newNode(ExtDecList, yylineno, 1, children, nullValue());
}
| VarDec COMMA ExtDecList {
pNode children[3] = { $1, $2, $3 };
$$ = newNode(ExtDecList, yylineno, 3, children, nullValue());
}
;
// Specifiers
Specifier:
TYPE_INT {
pNode children[1] = { $1 };
$$ = newNode(Specifier, yylineno, 1, children, nullValue());
}
| TYPE_FLOAT {
pNode children[1] = { $1 };
$$ = newNode(Specifier, yylineno, 1, children, nullValue());
}
| StructSpecifier {
pNode children[1] = { $1 };
$$ = newNode(Specifier, yylineno, 1, children, nullValue());
}
;
StructSpecifier:
STRUCT OptTag LC DefList RC {
pNode children[5] = { $1, $2, $3, $4, $5 };
$$ = newNode(StructSpecifier, yylineno, 5, children, nullValue());
}
| STRUCT Tag {
pNode children[2] = { $1, $2 };
$$ = newNode(StructSpecifier, yylineno, 2, children, nullValue());
}
;
OptTag:
ID {
pNode children[1] = { $1 };
$$ = newNode(OptTag, yylineno, 1, children, nullValue());
}
| {
$$ = newNode(OptTag, -1, 0, NULL, nullValue());
}
;
Tag:
ID {
pNode children[1] = { $1 };
$$ = newNode(Tag, yylineno, 1, children, nullValue());
}
;
// Declarators
VarDec:
ID {
pNode children[1] = { $1 };
$$ = newNode(VarDec, yylineno, 1, children, nullValue());
}
| VarDec LB INTEGER RB {
pNode children[4] = { $1, $2, $3, $4 };
$$ = newNode(VarDec, yylineno, 4, children, nullValue());
}
;
FunDec:
ID LP VarList RP {
pNode children[4] = { $1, $2, $3, $4 };
$$ = newNode(FunDec, yylineno, 4, children, nullValue());
}
| ID LP RP {
pNode children[3] = { $1, $2, $3 };
$$ = newNode(FunDec, yylineno, 3, children, nullValue());
}
;
VarList:
ParamDec COMMA VarList {
pNode children[3] = { $1, $2, $3 };
$$ = newNode(VarList, yylineno, 3, children, nullValue());
}
| ParamDec {
pNode children[1] = { $1 };
$$ = newNode(VarList, yylineno, 1, children, nullValue());
}
;
ParamDec:
Specifier VarDec {
pNode children[1] = { $1 };
$$ = newNode(ParamDec, yylineno, 1, children, nullValue());
}
;
// Statements
CompSt:
LC DefList StmtList RC {
pNode children[4] = { $1, $2, $3, $4 };
$$ = newNode(CompSt, yylineno, 4, children, nullValue());
}
;
StmtList:
Stmt StmtList {
pNode children[2] = { $1, $2 };
$$ = newNode(StmtList, yylineno, 2, children, nullValue());
}
| {
$$ = newNode(StmtList, -1, 0, NULL, nullValue());
}
;
Stmt:
Exp SEMI {
pNode children[2] = { $1, $2 };
$$ = newNode(Stmt, yylineno, 2, children, nullValue());
}
| CompSt {
pNode children[1] = { $1 };
$$ = newNode(Stmt, yylineno, 1, children, nullValue());
}
| RETURN Exp SEMI {
pNode children[3] = { $1, $2, $3 };
$$ = newNode(Stmt, yylineno, 3, children, nullValue());
}
| IF LP Exp RP Stmt {
pNode children[5] = { $1, $2, $3, $4, $5 };
$$ = newNode(Stmt, yylineno, 5, children, nullValue());
}
| IF LP Exp RP Stmt ELSE Stmt {
pNode children[7] = { $1, $2, $3, $4, $5, $6, $7 };
$$ = newNode(Stmt, yylineno, 7, children, nullValue());
}
| WHILE LP Exp RP Stmt {
pNode children[5] = { $1, $2, $3, $4, $5 };
$$ = newNode(Stmt, yylineno, 5, children, nullValue());
}
| error SEMI
;
// Local Definitions
DefList:
Def DefList {
pNode children[2] = { $1, $2 };
$$ = newNode(DefList, yylineno, 2, children, nullValue());
}
| {
$$ = newNode(DefList, -1, 0, NULL, nullValue());
}
;
Def:
Specifier DecList SEMI {
pNode children[3] = { $1, $2, $3 };
$$ = newNode(Def, yylineno, 3, children, nullValue());
}
;
DecList:
Dec {
pNode children[1] = { $1 };
$$ = newNode(DecList, yylineno, 1, children, nullValue());
}
| Dec COMMA DecList {
pNode children[3] = { $1, $2, $3 };
$$ = newNode(DecList, yylineno, 3, children, nullValue());
}
;
Dec:
VarDec {
pNode children[1] = { $1 };
$$ = newNode(Dec, yylineno, 1, children, nullValue());
}
| VarDec ASSIGNOP Exp {
pNode children[3] = { $1, $2, $3 };
$$ = newNode(Dec, yylineno, 3, children, nullValue());
}
;
// Expressions
Exp:
Exp ASSIGNOP Exp {
pNode children[3] = { $1, $2, $3 };
$$ = newNode(Exp, yylineno, 3, children, nullValue());
}
| Exp AND Exp {
pNode children[3] = { $1, $2, $3 };
$$ = newNode(Exp, yylineno, 3, children, nullValue());
}
| Exp OR Exp {
pNode children[3] = { $1, $2, $3 };
$$ = newNode(Exp, yylineno, 3, children, nullValue());
}
| Exp PLUS Exp {
pNode children[3] = { $1, $2, $3 };
$$ = newNode(Exp, yylineno, 3, children, nullValue());
}
| Exp MINUS Exp {
pNode children[3] = { $1, $2, $3 };
$$ = newNode(Exp, yylineno, 3, children, nullValue());
}
| Exp TIMES Exp {
pNode children[3] = { $1, $2, $3 };
$$ = newNode(Exp, yylineno, 3, children, nullValue());
}
| Exp DIV Exp {
pNode children[3] = { $1, $2, $3 };
$$ = newNode(Exp, yylineno, 3, children, nullValue());
}
| LP Exp RP {
pNode children[3] = { $1, $2, $3 };
$$ = newNode(Exp, yylineno, 3, children, nullValue());
}
| MINUS Exp {
pNode children[2] = { $1, $2 };
$$ = newNode(Exp, yylineno, 2, children, nullValue());
}
| NOT Exp {
pNode children[2] = { $1, $2 };
$$ = newNode(Exp, yylineno, 2, children, nullValue());
}
| ID LP Args RP {
pNode children[4] = { $1, $2, $3, $4 };
$$ = newNode(Exp, yylineno, 4, children, nullValue());
}
| ID LP RP {
pNode children[3] = { $1, $2, $3 };
$$ = newNode(Exp, yylineno, 3, children, nullValue());
}
| Exp LB Exp RB {
pNode children[4] = { $1, $2, $3, $4 };
$$ = newNode(Exp, yylineno, 4, children, nullValue());
}
| Exp DOT ID {
pNode children[3] = { $1, $2, $3 };
$$ = newNode(Exp, yylineno, 3, children, nullValue());
}
| ID {
pNode children[1] = { $1 };
$$ = newNode(Exp, yylineno, 1, children, nullValue());
}
| INTEGER {
pNode children[1] = { $1 };
$$ = newNode(Exp, yylineno, 1, children, nullValue());
}
| FLOAT {
pNode children[1] = { $1 };
$$ = newNode(Exp, yylineno, 1, children, nullValue());
}
;
Args:
Exp COMMA Args {
pNode children[3] = { $1, $2, $3 };
$$ = newNode(Args, yylineno, 3, children, nullValue());
}
| Exp {
pNode children[1] = { $1 };
$$ = newNode(Exp, yylineno, 1, children, nullValue());
}
;
%%
void yyerror(char const *s) {
errors += 1;
fprintf(stderr, "Error type B at Line %d: \"%s\".\n", yylineno, s);
}