initial commit
This commit is contained in:
120
src/yacc/globals.h
Normal file
120
src/yacc/globals.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/****************************************************/
|
||||
/* File: globals.h */
|
||||
/* Yacc/Bison Version */
|
||||
/* Global types and vars for TINY compiler */
|
||||
/* must come before other include files */
|
||||
/* Compiler Construction: Principles and Practice */
|
||||
/* Kenneth C. Louden */
|
||||
/****************************************************/
|
||||
|
||||
#ifndef _GLOBALS_H_
|
||||
#define _GLOBALS_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Yacc/Bison generates internally its own values
|
||||
* for the tokens. Other files can access these values
|
||||
* by including the tab.h file generated using the
|
||||
* Yacc/Bison option -d ("generate header")
|
||||
*
|
||||
* The YYPARSER flag prevents inclusion of the tab.h
|
||||
* into the Yacc/Bison output itself
|
||||
*/
|
||||
|
||||
#ifndef YYPARSER
|
||||
|
||||
/* the name of the following file may change */
|
||||
#include "y.tab.h"
|
||||
|
||||
/* ENDFILE is implicitly defined by Yacc/Bison,
|
||||
* and not included in the tab.h file
|
||||
*/
|
||||
#define ENDFILE 0
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
/* MAXRESERVED = the number of reserved words */
|
||||
#define MAXRESERVED 8
|
||||
|
||||
/* Yacc/Bison generates its own integer values
|
||||
* for tokens
|
||||
*/
|
||||
typedef int TokenType;
|
||||
|
||||
extern FILE* source; /* source code text file */
|
||||
extern FILE* listing; /* listing output text file */
|
||||
extern FILE* code; /* code text file for TM simulator */
|
||||
|
||||
extern int lineno; /* source line number for listing */
|
||||
|
||||
/**************************************************/
|
||||
/*********** Syntax tree for parsing ************/
|
||||
/**************************************************/
|
||||
|
||||
typedef enum {StmtK,ExpK} NodeKind;
|
||||
typedef enum {IfK,RepeatK,AssignK,ReadK,WriteK} StmtKind;
|
||||
typedef enum {OpK,ConstK,IdK} ExpKind;
|
||||
|
||||
/* ExpType is used for type checking */
|
||||
typedef enum {Void,Integer,Boolean} ExpType;
|
||||
|
||||
#define MAXCHILDREN 3
|
||||
|
||||
typedef struct treeNode
|
||||
{ struct treeNode * child[MAXCHILDREN];
|
||||
struct treeNode * sibling;
|
||||
int lineno;
|
||||
NodeKind nodekind;
|
||||
union { StmtKind stmt; ExpKind exp;} kind;
|
||||
union { TokenType op;
|
||||
int val;
|
||||
char * name; } attr;
|
||||
ExpType type; /* for type checking of exps */
|
||||
} TreeNode;
|
||||
|
||||
/**************************************************/
|
||||
/*********** Flags for tracing ************/
|
||||
/**************************************************/
|
||||
|
||||
/* EchoSource = TRUE causes the source program to
|
||||
* be echoed to the listing file with line numbers
|
||||
* during parsing
|
||||
*/
|
||||
extern int EchoSource;
|
||||
|
||||
/* TraceScan = TRUE causes token information to be
|
||||
* printed to the listing file as each token is
|
||||
* recognized by the scanner
|
||||
*/
|
||||
extern int TraceScan;
|
||||
|
||||
/* TraceParse = TRUE causes the syntax tree to be
|
||||
* printed to the listing file in linearized form
|
||||
* (using indents for children)
|
||||
*/
|
||||
extern int TraceParse;
|
||||
|
||||
/* TraceAnalyze = TRUE causes symbol table inserts
|
||||
* and lookups to be reported to the listing file
|
||||
*/
|
||||
extern int TraceAnalyze;
|
||||
|
||||
/* TraceCode = TRUE causes comments to be written
|
||||
* to the TM code file as code is generated
|
||||
*/
|
||||
extern int TraceCode;
|
||||
|
||||
/* Error = TRUE prevents further passes if an error occurs */
|
||||
extern int Error;
|
||||
#endif
|
||||
164
src/yacc/tiny.y
Normal file
164
src/yacc/tiny.y
Normal file
@@ -0,0 +1,164 @@
|
||||
/****************************************************/
|
||||
/* File: tiny.y */
|
||||
/* The TINY Yacc/Bison specification file */
|
||||
/* Compiler Construction: Principles and Practice */
|
||||
/* Kenneth C. Louden */
|
||||
/****************************************************/
|
||||
%{
|
||||
#define YYPARSER /* distinguishes Yacc output from other code files */
|
||||
|
||||
#include "globals.h"
|
||||
#include "util.h"
|
||||
#include "scan.h"
|
||||
#include "parse.h"
|
||||
|
||||
#define YYSTYPE TreeNode *
|
||||
static char * savedName; /* for use in assignments */
|
||||
static int savedLineNo; /* ditto */
|
||||
static TreeNode * savedTree; /* stores syntax tree for later return */
|
||||
static int yylex(void); // added 11/2/11 to ensure no conflict with lex
|
||||
|
||||
%}
|
||||
|
||||
%token IF THEN ELSE END REPEAT UNTIL READ WRITE
|
||||
%token ID NUM
|
||||
%token ASSIGN EQ LT PLUS MINUS TIMES OVER LPAREN RPAREN SEMI
|
||||
%token ERROR
|
||||
|
||||
%% /* Grammar for TINY */
|
||||
|
||||
program : stmt_seq
|
||||
{ savedTree = $1;}
|
||||
;
|
||||
stmt_seq : stmt_seq SEMI stmt
|
||||
{ YYSTYPE t = $1;
|
||||
if (t != NULL)
|
||||
{ while (t->sibling != NULL)
|
||||
t = t->sibling;
|
||||
t->sibling = $3;
|
||||
$$ = $1; }
|
||||
else $$ = $3;
|
||||
}
|
||||
| stmt { $$ = $1; }
|
||||
;
|
||||
stmt : if_stmt { $$ = $1; }
|
||||
| repeat_stmt { $$ = $1; }
|
||||
| assign_stmt { $$ = $1; }
|
||||
| read_stmt { $$ = $1; }
|
||||
| write_stmt { $$ = $1; }
|
||||
| error { $$ = NULL; }
|
||||
;
|
||||
if_stmt : IF exp THEN stmt_seq END
|
||||
{ $$ = newStmtNode(IfK);
|
||||
$$->child[0] = $2;
|
||||
$$->child[1] = $4;
|
||||
}
|
||||
| IF exp THEN stmt_seq ELSE stmt_seq END
|
||||
{ $$ = newStmtNode(IfK);
|
||||
$$->child[0] = $2;
|
||||
$$->child[1] = $4;
|
||||
$$->child[2] = $6;
|
||||
}
|
||||
;
|
||||
repeat_stmt : REPEAT stmt_seq UNTIL exp
|
||||
{ $$ = newStmtNode(RepeatK);
|
||||
$$->child[0] = $2;
|
||||
$$->child[1] = $4;
|
||||
}
|
||||
;
|
||||
assign_stmt : ID { savedName = copyString(tokenString);
|
||||
savedLineNo = lineno; }
|
||||
ASSIGN exp
|
||||
{ $$ = newStmtNode(AssignK);
|
||||
$$->child[0] = $4;
|
||||
$$->attr.name = savedName;
|
||||
$$->lineno = savedLineNo;
|
||||
}
|
||||
;
|
||||
read_stmt : READ ID
|
||||
{ $$ = newStmtNode(ReadK);
|
||||
$$->attr.name =
|
||||
copyString(tokenString);
|
||||
}
|
||||
;
|
||||
write_stmt : WRITE exp
|
||||
{ $$ = newStmtNode(WriteK);
|
||||
$$->child[0] = $2;
|
||||
}
|
||||
;
|
||||
exp : simple_exp LT simple_exp
|
||||
{ $$ = newExpNode(OpK);
|
||||
$$->child[0] = $1;
|
||||
$$->child[1] = $3;
|
||||
$$->attr.op = LT;
|
||||
}
|
||||
| simple_exp EQ simple_exp
|
||||
{ $$ = newExpNode(OpK);
|
||||
$$->child[0] = $1;
|
||||
$$->child[1] = $3;
|
||||
$$->attr.op = EQ;
|
||||
}
|
||||
| simple_exp { $$ = $1; }
|
||||
;
|
||||
simple_exp : simple_exp PLUS term
|
||||
{ $$ = newExpNode(OpK);
|
||||
$$->child[0] = $1;
|
||||
$$->child[1] = $3;
|
||||
$$->attr.op = PLUS;
|
||||
}
|
||||
| simple_exp MINUS term
|
||||
{ $$ = newExpNode(OpK);
|
||||
$$->child[0] = $1;
|
||||
$$->child[1] = $3;
|
||||
$$->attr.op = MINUS;
|
||||
}
|
||||
| term { $$ = $1; }
|
||||
;
|
||||
term : term TIMES factor
|
||||
{ $$ = newExpNode(OpK);
|
||||
$$->child[0] = $1;
|
||||
$$->child[1] = $3;
|
||||
$$->attr.op = TIMES;
|
||||
}
|
||||
| term OVER factor
|
||||
{ $$ = newExpNode(OpK);
|
||||
$$->child[0] = $1;
|
||||
$$->child[1] = $3;
|
||||
$$->attr.op = OVER;
|
||||
}
|
||||
| factor { $$ = $1; }
|
||||
;
|
||||
factor : LPAREN exp RPAREN
|
||||
{ $$ = $2; }
|
||||
| NUM
|
||||
{ $$ = newExpNode(ConstK);
|
||||
$$->attr.val = atoi(tokenString);
|
||||
}
|
||||
| ID { $$ = newExpNode(IdK);
|
||||
$$->attr.name =
|
||||
copyString(tokenString);
|
||||
}
|
||||
| error { $$ = NULL; }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
int yyerror(char * message)
|
||||
{ fprintf(listing,"Syntax error at line %d: %s\n",lineno,message);
|
||||
fprintf(listing,"Current token: ");
|
||||
printToken(yychar,tokenString);
|
||||
Error = TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* yylex calls getToken to make Yacc/Bison output
|
||||
* compatible with ealier versions of the TINY scanner
|
||||
*/
|
||||
static int yylex(void)
|
||||
{ return getToken(); }
|
||||
|
||||
TreeNode * parse(void)
|
||||
{ yyparse();
|
||||
return savedTree;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user