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 3d6aea27 authored by Jonathan Evans's avatar Jonathan Evans

Previous assignment push

parent aca5edb6
default: all
all: evansj_parser
evansj_parser: evansj.tab.c lex.yy.c
g++ evansj.tab.c -o evansj_parser
evansj.tab.c: evansj.y
bison evansj.y
lex.yy.c: evansj.l
flex evansj.l
clean:
-@rm -f lex.yy.c
-@rm -f evansj.tab.c
\ No newline at end of file
#ifndef SYMBOL_TABLE_H
#define SYMBOL_TABLE_H
#include <map>
#include <string>
#include <iostream>
#include "SymbolTableEntry.h"
using namespace std;
class SYMBOL_TABLE
{
private:
std::map<string, SYMBOL_TABLE_ENTRY> hashTable;
public:
//Constructor
SYMBOL_TABLE( ) { }
// Add SYMBOL_TABLE_ENTRY x to this symbol table.
// If successful, return true; otherwise, return false.
bool addEntry(SYMBOL_TABLE_ENTRY x)
{
// Make sure there isn't already an entry with the same name
map<string, SYMBOL_TABLE_ENTRY>::iterator itr;
if ((itr = hashTable.find(x.getName())) == hashTable.end())
{
hashTable.insert(make_pair(x.getName(), x));
return(true);
}
else return(false);
}
// If a SYMBOL_TABLE_ENTRY with name theName is
// found in this symbol table, then return true;
// otherwise, return false.
bool findEntry(string theName)
{
map<string, SYMBOL_TABLE_ENTRY>::iterator itr;
if ((itr = hashTable.find(theName)) == hashTable.end())
return(false);
else return(true);
}
};
#endif // SYMBOL_TABLE_H
#ifndef SYMBOL_TABLE_ENTRY_H
#define SYMBOL_TABLE_ENTRY_H
#include <string>
using namespace std;
#define UNDEFINED -1
class SYMBOL_TABLE_ENTRY
{
private:
// Member variables
string name;
int typeCode;
public:
// Constructors
SYMBOL_TABLE_ENTRY( ) { name = ""; typeCode = UNDEFINED; }
SYMBOL_TABLE_ENTRY(const string theName, const int theType)
{
name = theName;
typeCode = theType;
}
// Accessors
string getName() const { return name; }
int getTypeCode() const { return typeCode; }
};
#endif // SYMBOL_TABLE_ENTRY_H
/*
*
*
*
*
*/
%{
int numLines = 1;
void beginScope();
%}
NEWLINE \n
WSPACE [ \t\v\r]+
UNDERSCORE _
DIGIT [0-9]
ALPHA [A-Za-z]
ALPHANUM {DIGIT}|{ALPHA}
IDENT ({ALPHA}|{UNDERSCORE})({ALPHANUM}|{UNDERSCORE})*
INTCONST (\+|-)?{DIGIT}*
STRCONST \"[^\n\r]*\"
COMMENT ;.*
%%
{COMMENT} {}
"let*" {
printToken("LETSTAR", yytext);
beginScope();
return T_LETSTAR;
}
"lambda" {
printToken("LAMBDA", yytext);
beginScope();
return T_LAMBDA;
}
"input" {
printToken("INPUT", yytext);
return T_INPUT;
}
"print" {
printToken("PRINT", yytext);
return T_PRINT;
}
"if" {
printToken("IF", yytext);
return T_IF;
}
"exit" {
printToken("EXIT", yytext);
return T_EXIT;
}
"progn" {
printToken("PROGN", yytext);
return T_PROGN;
}
"(" {
printToken("LPAREN", yytext);
return T_LPAREN;
}
")" {
printToken("RPAREN", yytext);
return T_RPAREN;
}
"+" {
printToken("ADD", yytext);
return T_ADD;
}
"*" {
printToken("MULT", yytext);
return T_MULT;
}
"/" {
printToken("DIV", yytext);
return T_DIV;
}
"-" {
printToken("SUB", yytext);
return T_SUB;
}
"and" {
printToken("AND", yytext);
return T_AND;
}
"or" {
printToken("OR", yytext);
return T_OR;
}
"not" {
printToken("NOT", yytext);
return T_NOT;
}
"<" {
printToken("LT", yytext);
return T_LT;
}
">" {
printToken("GT", yytext);
return T_GT;
}
"<=" {
printToken("LE", yytext);
return T_LE;
}
">=" {
printToken("GE", yytext);
return T_GE;
}
"=" {
printToken("EQ", yytext);
return T_EQ;
}
"/=" {
printToken("NE", yytext);
return T_NE;
}
"t" {
printToken("T", yytext);
return T_T;
}
"nil" {
printToken("NIL", yytext);
return T_NIL;
}
{IDENT} {
yylval.text = strdup(yytext);
printToken("IDENT", yytext);
return T_IDENT;
}
{INTCONST} {
printToken("INTCONST", yytext);
return T_INTCONST;
}
{STRCONST} {
printToken("STRCONST", yytext);
return T_STRCONST;
}
{NEWLINE} {
numLines++;
}
{WSPACE} { }
. {
printToken("UNKNOWN", yytext);
return T_UNKNOWN;
}
%%
\ No newline at end of file
%{
#include <stdio.h>
#include "SymbolTable.h"
#include <stack>
using std::stack;
stack<SYMBOL_TABLE> scopeStack;
void endScope();
void printRule(const char* ruleType, const char* token);
int yyerror(const char *s);
void printToken(const char* tokenType, char* lexeme);
bool findEntryInAnyScope(const string theName);
extern "C"
{
int yyparse(void);
int yylex(void);
int yywrap(void){
return 1;
};
}
%}
%union
{
char* text;
}
%token T_LETSTAR T_LAMBDA T_INPUT T_PRINT T_IF T_EXIT T_PROGN T_LPAREN T_RPAREN
%token T_ADD T_MULT T_SUB T_DIV T_AND T_OR T_NOT T_LT T_GT T_LE T_GE T_EQ T_NE
%token T_IDENT T_INTCONST T_STRCONST T_T T_NIL T_UNKNOWN
%type <text> T_IDENT
%start N_START
%%
N_START : //epsilon
{
printRule("START", "epsilon");
}
| N_START N_EXPR
{
printRule("START", "START EXPR");
//Should this be printed?
printf("\n---- Completed parsing ----\n\n");
};
N_EXPR : N_CONST
{
printRule("EXPR", "CONST");
}
| T_IDENT
{
printRule("EXPR", "IDENT");
if(!findEntryInAnyScope(string($1))){
yyerror("Undefined identifier");
}
}
| T_LPAREN N_PARENTHESIZED_EXPR T_RPAREN
{
printRule("EXPR", "( PARENTHESIZED_EXPR )");
};
N_CONST : T_INTCONST
{
printRule("CONST", "INTCONST");
}
| T_STRCONST
{
printRule("CONST", "STRCONST");
}
| T_T
{
printRule("CONST", "t");
}
| T_NIL
{
printRule("CONST", "nil");
};
N_PARENTHESIZED_EXPR : N_ARITHLOGIC_EXPR
{
printRule("PARENTHESIZED_EXPR", "ARITHLOGIC_EXPR");
}
| N_IF_EXPR
{
printRule("PARENTHESIZED_EXPR", "IF_EXPR");
}
| N_LET_EXPR
{
printRule("PARENTHESIZED_EXPR", "LET_EXPR");
}
| N_LAMBDA_EXPR
{
printRule("PARENTHESIZED_EXPR", "LAMBDA_EXPR");
}
| N_PRINT_EXPR
{
printRule("PARENTHESIZED_EXPR", "PRINT_EXPR");
}
| N_INPUT_EXPR
{
printRule("PARENTHESIZED_EXPR", "INPUT_EXPR");
}
| N_PROGN_OR_USERFUNCTCALL
{
printRule("PARENTHESIZED_EXPR", "PROGN_OR_USERFUNCTCALL");
}
| T_EXIT
{
printRule("PARENTHESIZED_EXPR", "EXIT");
printf("\nBye!\n");
exit(1);
};
N_PROGN_OR_USERFUNCTCALL : N_FUNCT_NAME N_EXPR_LIST
{
//example outputs have a space after PROGN_OR_USERFUNCTCALL ...is that deliberate?
printRule("PROGN_OR_USERFUNCTCALL ", "FUNCT_NAME EXPR_LIST");
};
N_FUNCT_NAME : T_PROGN
{
printRule("FUNCT_NAME", "PROGN");
}
| T_IDENT
{
printRule("FUNCT_NAME", "IDENT");
if(!findEntryInAnyScope(string($1))){
yyerror("Undefined identifier");
}
};
N_ARITHLOGIC_EXPR : N_UN_OP N_EXPR
{
printRule("ARITHLOGIC_EXPR", "UN_OP EXPR");
}
| N_BIN_OP N_EXPR N_EXPR
{
printRule("ARITHLOGIC_EXPR", "BIN_OP EXPR EXPR");
};
N_IF_EXPR : T_IF N_EXPR N_EXPR N_EXPR
{
printRule("IF_EXPR", "if EXPR EXPR EXPR");
};
N_LET_EXPR : T_LETSTAR T_LPAREN N_ID_EXPR_LIST T_RPAREN N_EXPR
{
printRule("LET_EXPR", "let* ( ID_EXPR_LIST ) EXPR");
endScope();
};
N_ID_EXPR_LIST : //epsilon
{
printRule("ID_EXPR_LIST", "epsilon");
}
| N_ID_EXPR_LIST T_LPAREN T_IDENT N_EXPR T_RPAREN
{
printRule("ID_EXPR_LIST", "ID_EXPR_LIST ( IDENT EXPR )");
printf("___Adding %s to symbol table\n", $3);
if(findEntryInAnyScope(string($3))){
yyerror("Multiply defined identifier");
} else {
scopeStack.top().addEntry(SYMBOL_TABLE_ENTRY(string($3), UNDEFINED));
}
};
N_LAMBDA_EXPR : T_LAMBDA T_LPAREN N_ID_LIST T_RPAREN N_EXPR
{
printRule("LAMBDA_EXPR", "lambda ( ID_LIST ) EXPR");
endScope();
};
N_ID_LIST : //epsilon
{
printRule("ID_LIST", "epsilon");
}
| N_ID_LIST T_IDENT
{
printRule("ID_LIST", "ID_LIST IDENT");
if(scopeStack.top().findEntry($2)){
yyerror("Multiply defined identifier");
} else {
scopeStack.top().addEntry(SYMBOL_TABLE_ENTRY(string($2), UNDEFINED));
printf("___Adding %s to symbol table\n", $2);
}
};
N_PRINT_EXPR : T_PRINT N_EXPR
{
printRule("PRINT_EXPR", "print EXPR");
};
N_INPUT_EXPR : T_INPUT
{
printRule("INPUT_EXPR", "input");
};
N_EXPR_LIST : N_EXPR N_EXPR_LIST
{
printRule("EXPR_LIST", "EXPR EXPR_LIST");
}
| //epsilon
{
printRule("EXPR_LIST", "epsilon");
};
N_BIN_OP : N_ARITH_OP
{
printRule("BIN_OP", "ARITH_OP");
}
| N_LOG_OP
{
printRule("BIN_OP", "LOG_OP");
}
| N_REL_OP
{
printRule("BIN_OP", "REL_OP");
};
N_ARITH_OP : T_MULT
{
printRule("ARITH_OP", "*");
}
| T_SUB
{
printRule("ARITH_OP", "-");
}
| T_DIV
{
printRule("ARITH_OP", "/");
}
| T_ADD
{
printRule("ARITH_OP", "+");
};
N_LOG_OP : T_AND
{
printRule("LOG_OP", "and");
}
| T_OR
{
printRule("LOG_OP", "or");
};
N_REL_OP : T_LT
{
printRule("REL_OP", "<");
}
| T_GT
{
printRule("REL_OP", ">");
}
| T_LE
{
printRule("REL_OP", "<=");
}
| T_GE
{
printRule("REL_OP", ">=");
}
| T_EQ
{
printRule("REL_OP", "=");
}
| T_NE
{
printRule("REL_OP", "/=");
};
N_UN_OP : T_NOT
{
printRule("UN_OP", "not");
};
%%
#include "lex.yy.c"
extern FILE *yyin;
void printRule(const char *lhs, const char *rhs){
printf("%s -> %s\n", lhs, rhs);
return;
}
int yyerror(const char *s){
printf("Line %i: %s\n", numLines, s);
printf("\nBye!\n");
exit(1);
return 1;
}
void printToken(const char* tokenType, char* lexeme){
printf("TOKEN: %-8s LEXEME: %s\n", tokenType, lexeme);
}
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 beginScope()
{
scopeStack.push(SYMBOL_TABLE());
printf("\n___Entering new scope...\n\n");
}
void endScope()
{
scopeStack.pop();
printf("\n___Exiting scope...\n\n");
}
int main(){
do {
yyparse();
}while (!feof(yyin));
printf("\nBye!\n");
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