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
|
/*
mfpl.y
Specifications for the MFPL language, YACC input file.
To create syntax analyzer:
flex mfpl.l
bison mfpl.y
g++ mfpl.tab.c -o mfpl_parser
mfpl_parser < inputFileName
*/
/*
* Declaration section.
*/
%{
#include <stdio.h>
#include "SymbolTable.h"
#include <stack>
#include <string>
#include <iostream>
using namespace std;
// type codes
#define UNDEFINED -1
#define FUNCTION 0
#define INT 1
#define STR 2
#define BOOL 4
#define NOT_APPLICABLE -1
/*
* Datatype struct
*/
typedef struct
{
int type; // one of the above type codes
union dataStor
{
int i;
char* s;
bool b;
} data;
int numParams; // NumParams and returnType only applicable
int returnType; // if type == function
} TYPE_INFO;
typedef struct
{
char* text; // the operator class
char* op; // the exact operator
} OPERATOR_INFO;
stack<SYMBOL_TABLE> scopeStack;
int lineNum = 1;
void printRule(const char *, const char *);
int yyerror(const char *s) {
printf("Line %d: %s\n", lineNum, s);
}
extern "C" {
int yyparse(void);
int yylex(void);
int yywrap() {return 1;}
}
void beginScope() // Call when let* or lambda is processed in mfpl.l.
{
scopeStack.push(SYMBOL_TABLE());
printf("\n___Entering new scope...\n\n");
}
void endScope() // Call when LET_EXPR or LAMBDA_EXPR is processed in mfpl.y.
{
scopeStack.pop();
printf("\n___Exiting scope...\n\n");
}
int findEntryInAnyScope(std::string theName)
{
if(scopeStack.empty())
return false;
bool found = scopeStack.top().findEntry(theName);
if(found)
return true;
else
{// Check higher scopes
SYMBOL_TABLE SymbolTable = scopeStack.top();
scopeStack.pop();
found = findEntryInAnyScope(theName);
scopeStack.push(SymbolTable); // restore the stack
return (found);
}
}
TYPE_INFO CheckStringData(char* check)
{
TYPE_INFO ret;
ret.numParams = NOT_APPLICABLE;
ret.returnType = NOT_APPLICABLE;
}
%}
/*
* union declaration
*/
%union
{
char* text;
TYPE_INFO typeInfo;
int list_length;
OPERATOR_INFO opInfo;
};
/*
* Token declarations
*/
%token T_LPAREN T_RPAREN
%token T_IF T_LETSTAR T_LAMBDA T_PRINT T_INPUT
%token T_ADD T_SUB T_MULT T_DIV
%token T_LT T_GT T_LE T_GE T_EQ T_NE T_AND T_OR T_NOT
%token T_INTCONST T_STRCONST T_T T_NIL T_IDENT T_UNKNOWN
%type<text> T_IDENT N_ARITH_OP N_REL_OP N_LOG_OP T_INPUT T_INTCONST T_STRCONST
%type<typeInfo> N_EXPR N_PARENTHESIZED_EXPR N_IF_EXPR N_ARITHLOGIC_EXPR
%type<typeInfo> N_LET_EXPR N_LAMBDA_EXPR N_PRINT_EXPR N_CONST N_INPUT_EXPR
%type<typeInfo> N_EXPR_LIST
%type<list_length> N_ID_LIST
%type<opInfo> N_BIN_OP
/*
* Starting point.
*/
%start N_START
%%
|
%%
#include "lex.yy.c"
extern FILE *yyin;
void printRule(const char *lhs, const char *rhs) {
printf("%s -> %s\n", lhs, rhs);
return;
}
int main(int argc, char** argv) {
if(argc < 2)
{
printf("You must specify a file in the command line!\n");
exit(1);
}
do {
yyparse();
} while (!feof(yyin));
return 0;
} |