This server is intended for use for Academic Classwork related Git repositories only. Projects/repositories will generally be removed after 6 months following close of the semester. Inactive repositories from previous semester are now being archived when no activity for 365 days. They are renamed and marked as 'archived'. After 90 days in that state they will be removed from the system completely.

Commit 59ae1939 authored by amh6wr's avatar amh6wr

Basic changes made

parent 3d6aea27
%{
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <stack>
#include "SymbolTable.h"
using namespace std;
int lineNum = 1; // line # being processed
stack<SYMBOL_TABLE> scopeStack; // stack of scope hashtables
void beginScope();
void endScope();
void cleanUp();
void prepareToTerminate();
void bail();
bool findEntryInAnyScope(const string theName);
void printRule(const char*, const char*);
enum INT=2;
enum STR=4;
enum BOOL=8;
enum FUNCTION=16;
int yyerror(const char* s)
{
printf("Line %d: %s\n", lineNum, s);
bail();
}
extern "C"
{
int yyparse(void);
int yylex(void);
int yywrap() {return 1;}
}
%}
%union
{
char* text;
TYPE_INFO typeInfo;
};
/*
* Token declarations
*/
%token T_LPAREN T_RPAREN
%token T_IF T_LETSTAR T_LAMBDA T_PRINT T_INPUT T_PROGN T_EXIT
%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
%type <typeInfo> N_CONST N_EXPR N_PARENTHESIZED_EXPR N_IF_EXPR
/*
* Starting point.
*/
%start N_START
/*
* Translation rules.
*/
%%
N_START : // epsilon
{
}
| N_START N_EXPR
{
switch type:
case 1:
cout<<"INT"<<"\n";
case 2:
cout<<"STR"<<"\n";
case 4:
cout<<"BOOL"<<"\n";
case 8:
cout<<"FUNCTION"<<"\n";
case 3:
cout<<"INT_OR_STR"<<"\n";
case 5:
cout<<"INT_OR_BOOL"<<"\n";
case 6:
cout<<"STR_OR_BOOL"<<"\n";
case 7:
cout<<"INT_STR_OR_BOOL"<<"\n";
}
;
N_EXPR : N_CONST
{
//resulting type is the type of N_CONST
$$.type=$1.type;
$$.numParams=NOT_APPLICABLE;
$$.returnType=NOT_APPLICABLE;
}
| T_IDENT
{
if (!findEntryInAnyScope(string($1)))
yyerror("Undefined identifier");
//resulting type is the type of the identifier
//look up in the symbol table
}
| T_LPAREN N_PARENTHESIZED_EXPR T_RPAREN
{
//resulting type is the resulting type of the parenthesized expr
$$.type=$2.type;
$$.numParams=$2.numParams;
$$.returnType=$2.returnType;
}
;
N_CONST : T_INTCONST
{
//type is int
$$.type=INT;
$$.numParams=NOT_APPLICABLE;
$$.returnType=NOT_APPLICABLE;
}
| T_STRCONST
{
//type is string
$$.type=STR;
$$.numParams=NOT_APPLICABLE;
$$.returnType=NOT_APPLICABLE;
}
| T_T
{
//type is bool
$$.type=BOOL;
$$.numParams=NOT_APPLICABLE;
$$.returnType=NOT_APPLICABLE;
}
| T_NIL
{
//type is bool
$$.type=BOOL;
$$.numParams=NOT_APPLICABLE;
$$.returnType=NOT_APPLICABLE;
}
;
N_PARENTHESIZED_EXPR : N_ARITHLOGIC_EXPR //resulting type of whatever rule is applied
{
$$.type=$1.type;
$$.numParams=$1.numParams;
$$.returnType=$1.returnType;
}
| N_IF_EXPR
{
$$.type=$1.type;
$$.numParams=$1.numParams;
$$.returnType=$1.returnType;
}
| N_LET_EXPR
{
$$.type=$1.type;
$$.numParams=$1.numParams;
$$.returnType=$1.returnType;
}
| N_LAMBDA_EXPR
{
$$.type=$1.type;
$$.numParams=$1.numParams;
$$.returnType=$1.returnType;
}
| N_PRINT_EXPR
{
$$.type=$1.type;
$$.numParams=$1.numParams;
$$.returnType=$1.returnType;
}
| N_INPUT_EXPR
{
$$.type=$1.type;
$$.numParams=$1.numParams;
$$.returnType=$1.returnType;
}
| N_PROGN_OR_USERFUNCTCALL
{
$$.type=$1.type;
$$.numParams=$1.numParams;
$$.returnType=$1.returnType;
}
| T_EXIT
{
bail();
}
;
N_PROGN_OR_USERFUNCTCALL : N_FUNCT_NAME N_ACTUAL_PARAMS
{
}
| T_LPAREN N_LAMBDA_EXPR T_RPAREN N_ACTUAL_PARAMS
{
}
;
N_ACTUAL_PARAMS : N_EXPR_LIST
{
}
| /*epsilon*/
{
}
N_FUNCT_NAME : T_PROGN
{
}
| T_IDENT
{
if (!findEntryInAnyScope(string($1)))
yyerror("Undefined identifier");
}
;
N_ARITHLOGIC_EXPR : N_UN_OP N_EXPR
{
printRule("ARITHLOGIC_EXPR", "UN_OP EXPR");
if ($2.type == FUNCTION)
yyerror("Arg 1 cannot be function");
$$.type = BOOL;
$$.numParams = NOT_APPLICABLE;
$$.returnType = NOT_APPLICABLE;
}
| N_BIN_OP N_EXPR N_EXPR
{
//check if operation can be preformed
}
;
N_IF_EXPR : T_IF N_EXPR N_EXPR N_EXPR
{
//type of expr1 + type of expr2+ type of expr3= type of if statement
if($2.type == FUNCTION)
yyerror("Arg 1 cannot be function");
else if($3.type == FUNCTION)
yyerror("Arg 2 cannot be function");
else if($4.type == FUNCTION)
yyerror("Arg 3 cannot be function");
$$.type=$2.type + $3.type + $4.type;
}
;
N_LET_EXPR
: T_LETSTAR T_LPAREN N_ID_EXPR_LIST T_RPAREN N_EXPR
{
if($5.type==FUNCTION)
yyerror("Arg 1 cannot be function");
$$.type=$5.type;
endScope();
}
;
N_ID_EXPR_LIST : /* epsilon */
{
}
| N_ID_EXPR_LIST T_LPAREN T_IDENT N_EXPR T_RPAREN
{
string lexeme = string($3);
printf("___Adding %s to symbol table\n", $3);
bool success = scopeStack.top().addEntry
(SYMBOL_TABLE_ENTRY(lexeme,
UNDEFINED));
if (! success)
yyerror("Multiply defined identifier");
$4.type=$5.type;
}
;
N_LAMBDA_EXPR : T_LAMBDA T_LPAREN N_ID_LIST T_RPAREN N_EXPR
{
if($5.type==FUNCTION)
yyerror("Arg 1 cannot be function");
$$.type=FUNCTION;
$$.numParams=//length of id list
$$.returnType=$5.type;
endScope();
}
;
N_ID_LIST : /* epsilon */
{
}
| N_ID_LIST T_IDENT
{
string lexeme = string($2);
printf("___Adding %s to symbol table\n", $2);
bool success = scopeStack.top().addEntry(SYMBOL_TABLE_ENTRY(lexeme,UNDEFINED));
if (! success)
yyerror("Multiply defined identifier");
$2.type=INT_STR_OR_BOOL;
}
;
N_PRINT_EXPR : T_PRINT N_EXPR
{
if($2.type==FUNCTION)
yyerror("Arg 1 cannot be function");
$$.type=$2.type;
}
;
N_INPUT_EXPR : T_INPUT
{
$$.type=INT_OR_STR;
}
;
N_EXPR_LIST : N_EXPR N_EXPR_LIST
{
$$.type=$2.type;
}
| N_EXPR
{
$$.type=$1.type;
}
;
N_BIN_OP : N_ARITH_OP
{
}
|
N_LOG_OP
{
}
|
N_REL_OP
{
}
;
N_ARITH_OP : T_ADD
{
}
| T_SUB
{
}
| T_MULT
{
}
| T_DIV
{
}
;
N_REL_OP : T_LT
{
}
| T_GT
{
}
| T_LE
{
}
| T_GE
{
}
| T_EQ
{
}
| T_NE
{
}
;
N_LOG_OP : T_AND
{
}
| T_OR
{
}
;
N_UN_OP : T_NOT
{
}
;
%%
#include "lex.yy.c"
extern FILE *yyin;
void printRule(const char* lhs, const char* rhs)
{
printf("%s -> %s\n", lhs, rhs);
return;
}
void beginScope()
{
scopeStack.push(SYMBOL_TABLE());
printf("\n___Entering new scope...\n\n");
}
void endScope()
{
scopeStack.pop();
printf("\n___Exiting scope...\n\n");
}
bool findEntryInAnyScope(const string theName)
{
if (scopeStack.empty( )) return(false);
bool found = scopeStack.top().findEntry(theName);
if (found)
return(true);
else
{ // check in "next higher" scope
SYMBOL_TABLE symbolTable = scopeStack.top( );
scopeStack.pop( );
found = findEntryInAnyScope(theName);
scopeStack.push(symbolTable); // restore the stack
return(found);
}
}
void cleanUp()
{
if (scopeStack.empty())
return;
else
{
scopeStack.pop();
cleanUp();
}
}
void prepareToTerminate()
{
cleanUp();
cout << endl << "Bye!" << endl;
}
void bail()
{
prepareToTerminate();
exit(1);
}
int main()
{
do {
yyparse();
} while (!feof(yyin));
prepareToTerminate();
return 0;
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment