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