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 0725f9de authored by Hogan's avatar Hogan

merging conflicts

Merge branch 'master' of https://git-classes.mst.edu/jdev52/plants-hw4
parents c88de1eb 3a54b5fc
......@@ -2,6 +2,7 @@
#define SYMBOL_TABLE_ENTRY_H
#include <string>
#include <cstring>
#include <ostream>
#include <stdexcept>
using namespace std;
......@@ -21,6 +22,20 @@ using namespace std;
#define LOGICAL 11
#define RELATIONAL 12
#define ADD 0
#define SUBTRACT 1
#define MULTIPLY 2
#define DIVIDE 3
#define AND 4
#define OR 5
#define NOT 6
#define LT 7
#define GT 8
#define LE 9
#define GE 10
#define EQ 11
#define NE 12
union TYPE_VALUE{
char* text;
bool boolean;
......@@ -40,6 +55,67 @@ struct TYPE_INFO
// operatorType is only applicable if production is an operator
int operatorType;
int operatorInstance;
operator bool(){
if(type == BOOL){
return value.boolean;
}
return true;
}
bool operator!(){
return !(*this);
}
// man I really wish I had c++20's operator<=>/operator semantics right now
bool operator<(const TYPE_INFO& rhs) {
if(type != rhs.type){
throw std::invalid_argument("invalid type for comparison");
}
bool result = false;
switch(rhs.type){
case INT:
result = value.number < rhs.value.number;
break;
case STR:
result = (strcmp(value.text, rhs.value.text) == -1);
break;
}
return result;
}
bool operator==(const TYPE_INFO& rhs){
if(type != rhs.type){
throw std::invalid_argument("invalid type for comparison");
}
bool result = false;
switch(rhs.type){
case INT:
result = value.number == rhs.value.number;
break;
case STR:
result = (strcmp(value.text, rhs.value.text) == 0);
break;
}
return result;
}
bool operator<=(const TYPE_INFO& rhs){
return (*this < rhs) || (*this == rhs);
}
bool operator>=(const TYPE_INFO& rhs){
return !(*this < rhs);
}
bool operator>(const TYPE_INFO& rhs){
return !(*this <= rhs);
}
bool operator!=(const TYPE_INFO& rhs){
return !(*this == rhs);
}
friend ostream& operator<<(ostream& os, const TYPE_INFO& rhs){
switch(rhs.type){
......@@ -80,7 +156,6 @@ public:
typeInfo.type = theType.type;
typeInfo.returnType = theType.returnType;
typeInfo.numParams = theType.numParams;
typeInfo.value = theType.value;
}
SYMBOL_TABLE_ENTRY(const string theName, const int type = UNDEFINED,
......@@ -88,7 +163,7 @@ public:
name = theName;
typeInfo.type = type;
typeInfo.returnType = numParams;
typeInfo.numParams = returnType;
typeInfo.numParams = returnType;
}
// Accessors
......@@ -97,3 +172,4 @@ public:
};
#endif // SYMBOL_TABLE_ENTRY_H
......@@ -137,14 +137,16 @@ COMMENT ";".*
}
{INTCONST} {
yylval.number = atoi(yytext);
return T_INTCONST;
}
{STRCONST} {
yylval.text = strdup(yytext);
return T_STRCONST;
}
{NEWLINE} {
{NEWLINE} {
numLines++;
}
......
......@@ -37,6 +37,7 @@ extern "C"
%union
{
char* text;
int number;
TYPE_INFO typeInfo;
};
......@@ -53,6 +54,8 @@ extern "C"
* Type Identifications
*/
%type <text> T_IDENT
%type <text> T_STRCONST
%type <number> T_INTCONST
%type <typeInfo> N_START N_EXPR N_CONST N_PARENTHESIZED_EXPR
%type <typeInfo> N_PROGN_OR_USERFUNCTCALL N_ACTUAL_PARAMS N_FUNCT_NAME
%type <typeInfo> N_ARITHLOGIC_EXPR N_IF_EXPR N_LET_EXPR N_ID_EXPR_LIST
......@@ -73,9 +76,38 @@ N_START : // epsilon
}
| N_START N_EXPR
{
/*
cout << "EXPR type is: ";
switch ($2.type){
case 1:
cout<<"INT"<<"\n";
break;
case 2:
cout<<"STR"<<"\n";
break;
case 4:
cout<<"BOOL"<<"\n";
break;
case 8:
cout<<"FUNCTION"<<"\n";
break;
case 3:
cout<<"INT_OR_STR"<<"\n";
break;
case 5:
cout<<"INT_OR_BOOL"<<"\n";
break;
case 6:
cout<<"STR_OR_BOOL"<<"\n";
break;
case 7:
cout<<"INT_OR_STR_OR_BOOL"<<"\n";
break;
}
*/
cout << "\n---- Completed parsing ----\n" << endl;
cout << "\nValue of the expression is: ";
cout << $2 <<"\n";
cout << "---- Completed parsing ----\n" << endl;
}
;
N_EXPR : N_CONST
......@@ -96,16 +128,17 @@ N_EXPR : N_CONST
}
//resulting type is the type of the identifier
//look up in the symbol table
$$.type = getEntryInAnyScope(lexeme).getTypeInfo().type;
$$.value = getEntryInAnyScope(lexeme).getTypeInfo().value;
TYPE_INFO entryInfo = getEntryInAnyScope(lexeme).getTypeInfo();
$$.type = entryInfo.type;
$$.value = entryInfo.value;
}
| T_LPAREN N_PARENTHESIZED_EXPR T_RPAREN
{
//resulting value is the value of the N_PARENTHESIZED_EXPR
//resulting type is the resulting type of the parenthesized expr
$$.type=$2.type;
$$.numParams=$2.numParams;
$$.returnType=$2.returnType;
$$.type = $2.type;
$$.numParams = $2.numParams;
$$.returnType = $2.returnType;
$$.value = $2.value;
}
;
......@@ -113,10 +146,10 @@ N_CONST : T_INTCONST
{
//value is the value of the T_INTCONST
//type is int
$$.type=INT;
$$.numParams=NOT_APPLICABLE;
$$.returnType=NOT_APPLICABLE;
$$.type = INT;
$$.numParams = NOT_APPLICABLE;
$$.returnType = NOT_APPLICABLE;
$$.value.number = $1;
}
| T_STRCONST
{
......@@ -125,6 +158,7 @@ N_CONST : T_INTCONST
$$.type=STR;
$$.numParams=NOT_APPLICABLE;
$$.returnType=NOT_APPLICABLE;
$$.value.text = $1;
}
| T_T
{
......@@ -133,6 +167,7 @@ N_CONST : T_INTCONST
$$.type=BOOL;
$$.numParams=NOT_APPLICABLE;
$$.returnType=NOT_APPLICABLE;
$$.value.boolean = true;
}
| T_NIL
{
......@@ -141,10 +176,11 @@ N_CONST : T_INTCONST
$$.type=BOOL;
$$.numParams=NOT_APPLICABLE;
$$.returnType=NOT_APPLICABLE;
$$.value.boolean = false;
}
;
N_PARENTHESIZED_EXPR : N_ARITHLOGIC_EXPR
{
{
//check for divison by 0
//resulting type of whatever rule is applied
......@@ -172,18 +208,21 @@ N_PARENTHESIZED_EXPR : N_ARITHLOGIC_EXPR
$$.type=$1.type;
$$.numParams=$1.numParams;
$$.returnType=$1.returnType;
$$.value=$1.value;
}
| N_INPUT_EXPR
{
$$.type=$1.type;
$$.numParams=$1.numParams;
$$.returnType=$1.returnType;
$$.value=$1.value;
}
| N_PROGN_OR_USERFUNCTCALL
{
$$.type=$1.type;
$$.numParams=$1.numParams;
$$.returnType=$1.returnType;
$$.value=$1.value;
}
| T_EXIT
{
......@@ -195,8 +234,10 @@ N_PROGN_OR_USERFUNCTCALL : N_FUNCT_NAME N_ACTUAL_PARAMS
if($1.type == UNDEFINED){
if($2.type == NOT_APPLICABLE){
$$.type = BOOL;
$$.value.boolean = false;
} else {
$$.type = $2.type;
$$.value = $2.value;
}
} else {
if($1.numParams < $2.numParams){
......@@ -210,6 +251,7 @@ N_PROGN_OR_USERFUNCTCALL : N_FUNCT_NAME N_ACTUAL_PARAMS
$$.numParams = $2.numParams;
$$.returnType = UNDEFINED;
$$.value = $2.value;
}
;
N_ACTUAL_PARAMS : N_EXPR_LIST
......@@ -217,6 +259,7 @@ N_ACTUAL_PARAMS : N_EXPR_LIST
$$.type = $1.type;
$$.numParams = $1.numParams;
$$.returnType = $1.type;
$$.value = $1.value;
}
| /*epsilon*/
{
......@@ -256,6 +299,12 @@ N_ARITHLOGIC_EXPR : N_UN_OP N_EXPR
$$.type = BOOL;
$$.numParams = NOT_APPLICABLE;
$$.returnType = NOT_APPLICABLE;
//Slightly redundant, but good in the event of future expansion
switch($1.operatorInstance){
case NOT:
$$.value.boolean = !$2;
break;
}
}
| N_BIN_OP N_EXPR N_EXPR
{
......@@ -278,6 +327,27 @@ N_ARITHLOGIC_EXPR : N_UN_OP N_EXPR
yyerror("Arg 2 must be string");
}
switch($1.operatorInstance){
case LT:
$$.value.boolean = ($2 < $3);
break;
case GT:
$$.value.boolean = ($2 > $3);
break;
case LE:
$$.value.boolean = ($2 <= $3);
break;
case GE:
$$.value.boolean = ($2 >= $3);
break;
case EQ:
$$.value.boolean = ($2 == $3);
break;
case NE:
$$.value.boolean = ($2 != $3);
break;
}
break;
case LOGICAL:
if($2.type == FUNCTION) {
......@@ -288,6 +358,15 @@ N_ARITHLOGIC_EXPR : N_UN_OP N_EXPR
yyerror("Arg 2 cannot be a function");
}
switch($1.operatorInstance){
case AND:
$$.value.boolean = (($2) && ($3));
break;
case OR:
$$.value.boolean = (($2) || ($3));
break;
}
break;
case ARITHMETIC:
switch($2.type){
......@@ -312,6 +391,21 @@ N_ARITHLOGIC_EXPR : N_UN_OP N_EXPR
break;
}
switch($1.operatorInstance){
case ADD:
$$.value.number = $2.value.number + $3.value.number;
break;
case SUBTRACT:
$$.value.number = $2.value.number - $3.value.number;
break;
case MULTIPLY:
$$.value.number = $2.value.number * $3.value.number;
break;
case DIVIDE:
$$.value.number = $2.value.number / $3.value.number;
break;
}
break;
}
......@@ -332,7 +426,14 @@ N_IF_EXPR : T_IF N_EXPR N_EXPR N_EXPR
yyerror("Arg 3 cannot be a function");
}
$$.type = $3.type | $4.type;
if($2){
$$.type = $3.type;
$$.value = $3.value;
} else {
$$.type = $4.type;
$$.value = $4.value;
}
$$.numParams = NOT_APPLICABLE;
$$.returnType = NOT_APPLICABLE;
}
......@@ -355,7 +456,7 @@ 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);
// printf("___Adding %s to symbol table\n", $3);
bool found = scopeStack.top().findEntry(lexeme);
if (found){
yyerror("Multiply defined identifier");
......@@ -370,6 +471,9 @@ N_PRINT_EXPR : T_PRINT N_EXPR
yyerror("Arg 1 cannot be a function");
}
cout << $2 << endl;
$$.value=$2.value;
$$.type=$2.type;
$$.numParams = $2.numParams;
$$.returnType = $2.returnType;
......@@ -384,12 +488,14 @@ N_INPUT_EXPR : T_INPUT
;
N_EXPR_LIST : N_EXPR N_EXPR_LIST
{
$$.value = $2.value;
$$.type = $2.type;
$$.numParams = $2.numParams+1;
$$.returnType = NOT_APPLICABLE;
}
| N_EXPR
{
$$.value = $1.value;
$$.type=$1.type;
if($1.type == FUNCTION) {
$$.type = $1.returnType;
......@@ -405,6 +511,7 @@ N_BIN_OP : N_ARITH_OP
$$.numParams = NOT_APPLICABLE;
$$.returnType = NOT_APPLICABLE;
$$.operatorType = ARITHMETIC;
$$.operatorInstance = $1.operatorInstance;
}
| N_LOG_OP
{
......@@ -412,6 +519,7 @@ N_BIN_OP : N_ARITH_OP
$$.numParams = NOT_APPLICABLE;
$$.returnType = NOT_APPLICABLE;
$$.operatorType = LOGICAL;
$$.operatorInstance = $1.operatorInstance;
}
| N_REL_OP
{
......@@ -419,49 +527,63 @@ N_BIN_OP : N_ARITH_OP
$$.numParams = NOT_APPLICABLE;
$$.returnType = NOT_APPLICABLE;
$$.operatorType = RELATIONAL;
$$.operatorInstance = $1.operatorInstance;
}
;
N_ARITH_OP : T_ADD
{
$$.operatorInstance = ADD;
}
| T_SUB
{
$$.operatorInstance = SUBTRACT;
}
| T_MULT
{
$$.operatorInstance = MULTIPLY;
}
| T_DIV
{
$$.operatorInstance = DIVIDE;
}
;
N_REL_OP : T_LT
{
$$.operatorInstance = LT;
}
| T_GT
{
$$.operatorInstance = GT;
}
| T_LE
{
$$.operatorInstance = LE;
}
| T_GE
{
$$.operatorInstance = GE;
}
| T_EQ
{
$$.operatorInstance = EQ;
}
| T_NE
{
$$.operatorInstance = NE;
}
;
N_LOG_OP : T_AND
{
$$.operatorInstance = AND;
}
| T_OR
{
$$.operatorInstance = OR;
}
;
N_UN_OP : T_NOT
{
$$.operatorInstance = NOT;
}
;
%%
......@@ -489,13 +611,13 @@ void printToken(const char* tokenType, char* lexeme){
void beginScope()
{
scopeStack.push(SYMBOL_TABLE());
printf("\n___Entering new scope...\n\n");
// printf("\n___Entering new scope...\n\n");
}
void endScope()
{
scopeStack.pop();
printf("\n___Exiting scope...\n\n");
// printf("\n___Exiting scope...\n\n");
}
bool findEntryInAnyScope(const string theName)
......@@ -563,6 +685,8 @@ int main(int argc, char** argv)
{
yyparse();
}
while (!feof(yyin));
while (!feof(yyin));
bail();
return 0;
}
Value of the expression is: 0
---- Completed parsing ----
Value of the expression is: 60
......@@ -14,7 +14,7 @@ ___Adding sandwich to symbol table
___Exiting scope...
Value of the expression is: 0
---- Completed parsing ----
Value of the expression is: 0
Value of the expression is: 0
---- Completed parsing ----
Value of the expression is: 0
---- Completed parsing ----
Value of the expression is: 20
---- Completed parsing ----
Value of the expression is: 100
---- Completed parsing ----
Value of the expression is: 100
---- Completed parsing ----
Value of the expression is: "false"
---- Completed parsing ----
Value of the expression is: 100
Value of the expression is: 0
---- Completed parsing ----
Value of the expression is: -42
......@@ -4,10 +4,11 @@ ___Entering new scope...
___Adding x to symbol table
___Adding y to symbol table
___Adding z to symbol table
34848944
___Exiting scope...
Value of the expression is: 0
---- Completed parsing ----
Value of the expression is: 0
......@@ -4,10 +4,12 @@ ___Entering new scope...
___Adding x to symbol table
___Adding y to symbol table
___Adding z to symbol table
28856496
28856496
___Exiting scope...
Value of the expression is: 0
---- Completed parsing ----
Value of the expression is: 0
Value of the expression is: 0
---- Completed parsing ----
Value of the expression is: 1
Value of the expression is: 0
---- Completed parsing ----
Value of the expression is: 1
Value of the expression is: 0
---- Completed parsing ----
Value of the expression is: 1
Value of the expression is: 0
---- Completed parsing ----
Value of the expression is: 1