430 CMSC

ebote
Project3SkeletonCode.zip

listing.cc

listing.cc

// CMSC 430 Compiler Theory and Design
// Project 3 Skeleton
// UMGC CITE
// Summer 2023

// This file contains the bodies of the functions that produces the 
// compilation listing

#include   < cstdio >
#include   < string >

using   namespace  std ;

#include   "listing.h"

static   int  lineNumber ;
static  string error  =   "" ;
static   int  totalErrors  =   0 ;

static   void  displayErrors ();

void  firstLine ()
{
    lineNumber  =   1 ;
    printf ( "\n%4d  " , lineNumber );
}

void  nextLine ()
{
    displayErrors ();
    lineNumber ++ ;
    printf ( "%4d  " , lineNumber );
}

int  lastLine ()
{
    printf ( "\r" );
    displayErrors ();
    printf ( "     \n" );
     return  totalErrors ;
}
    
void  appendError ( ErrorCategories  errorCategory ,  string message )
{
    string messages []   =   {   "Lexical Error, Invalid Character " ,   "" ,
         "Semantic Error, " ,   "Semantic Error, Duplicate " ,
         "Semantic Error, Undeclared "   };

    error  =  messages [ errorCategory ]   +  message ;
    totalErrors ++ ;
}

void  displayErrors ()
{
     if   ( error  !=   "" )
        printf ( "%s\n" ,  error . c_str ());
    error  =   "" ;
}

listing.h

// CMSC 430 Compiler Theory and Design // Project 3 Skeleton // UMGC CITE // Summer 2023 // This file contains the function prototypes for the functions that produce // the compilation listing enum ErrorCategories {LEXICAL, SYNTAX, GENERAL_SEMANTIC, DUPLICATE_IDENTIFIER, UNDECLARED}; void firstLine(); void nextLine(); int lastLine(); void appendError(ErrorCategories errorCategory, string message);

makefile

compile: scanner.o parser.o listing.o values.o g++ -o compile scanner.o parser.o listing.o values.o scanner.o: scanner.c values.h listing.h tokens.h g++ -c scanner.c scanner.c: scanner.l flex scanner.l mv lex.yy.c scanner.c parser.o: parser.c values.h listing.h symbols.h g++ -c parser.c parser.c tokens.h: parser.y bison -d -v parser.y mv parser.tab.c parser.c cp parser.tab.h tokens.h listing.o: listing.cc listing.h g++ -c listing.cc values.o: values.cc values.h g++ -c values.cc

parser.y

/* CMSC 430 Compiler Theory and Design Project 3 Skeleton UMGC CITE Summer 2023 Project 3 Parser with semantic actions for the interpreter */ %{ #include <iostream> #include <cmath> #include <string> #include <vector> #include <map> using namespace std; #include "values.h" #include "listing.h" #include "symbols.h" int yylex(); void yyerror(const char* message); double extract_element(CharPtr list_name, double subscript); Symbols<double> scalars; Symbols<vector<double>*> lists; double result; %} %define parse.error verbose %union { CharPtr iden; Operators oper; double value; vector<double>* list; } %token <iden> IDENTIFIER %token <value> INT_LITERAL CHAR_LITERAL %token <oper> ADDOP MULOP ANDOP RELOP %token ARROW %token BEGIN_ CASE CHARACTER ELSE END ENDSWITCH FUNCTION INTEGER IS LIST OF OTHERS RETURNS SWITCH WHEN %type <value> body statement_ statement cases case expression term primary condition relation %type <list> list expressions %% function: function_header optional_variable body ';' {result = $3;} ; function_header: FUNCTION IDENTIFIER RETURNS type ';' ; type: INTEGER | CHARACTER ; optional_variable: variable | %empty ; variable: IDENTIFIER ':' type IS statement ';' {scalars.insert($1, $5);}; | IDENTIFIER ':' LIST OF type IS list ';' {lists.insert($1, $7);} ; list: '(' expressions ')' {$$ = $2;} ; expressions: expressions ',' expression {$1->push_back($3); $$ = $1;} | expression {$$ = new vector<double>(); $$->push_back($1);} body: BEGIN_ statement_ END {$$ = $2;} ; statement_: statement ';' | error ';' {$$ = 0;} ; statement: expression | WHEN condition ',' expression ':' expression {$$ = $2 ? $4 : $6;} | SWITCH expression IS cases OTHERS ARROW statement ';' ENDSWITCH {$$ = !isnan($4) ? $4 : $7;} ; cases: cases case {$$ = !isnan($1) ? $1 : $2;} | %empty {$$ = NAN;} ; case: CASE INT_LITERAL ARROW statement ';' {$$ = $<value>-2 == $2 ? $4 : NAN;} ; condition: condition ANDOP relation {$$ = $1 && $2;} | relation ; relation: '(' condition ')' {$$ = $2;} | expression RELOP expression {$$ = evaluateRelational($1, $2, $3);} ; expression: expression ADDOP term {$$ = evaluateArithmetic($1, $2, $3);} | term ; term: term MULOP primary {$$ = evaluateArithmetic($1, $2, $3);} | primary ; primary: '(' expression ')' {$$ = $2;} | INT_LITERAL | CHAR_LITERAL | IDENTIFIER '(' expression ')' {$$ = extract_element($1, $3); } | IDENTIFIER {if (!scalars.find($1, $$)) appendError(UNDECLARED, $1);} ; %% void yyerror(const char* message) { appendError(SYNTAX, message); } double extract_element(CharPtr list_name, double subscript) { vector<double>* list; if (lists.find(list_name, list)) return (*list)[subscript]; appendError(UNDECLARED, list_name); return NAN; } int main(int argc, char *argv[]) { firstLine(); yyparse(); if (lastLine() == 0) cout << "Result = " << result << endl; return 0; }

scanner.l

/* CMSC 430 Compiler Theory and Design Project 3 Skeleton UMGC CITE Summer 2023 */ /* This file contains flex input file */ %{ #include <cstdio> #include <string> #include <vector> using namespace std; #include "values.h" #include "listing.h" #include "tokens.h" %} %option noyywrap ws [ \t\r]+ comment "//".*\n line [\n] id [A-Za-z]([A-Za-z0-9])* digit [0-9] dec {digit}+ char '.' punc [\(\),:;] %% {ws} { ECHO; } {comment} { ECHO; nextLine(); } {line} { ECHO; nextLine(); } "+" { ECHO; yylval.oper = ADD; return(ADDOP); } "*" { ECHO; yylval.oper = MULTIPLY; return(MULOP); } "&" { ECHO; yylval.oper = AND; return(ANDOP); } "<" { ECHO; yylval.oper = LESS; return(RELOP); } "=>" { ECHO; return(ARROW); } begin { ECHO; return(BEGIN_); } case { ECHO; return(CASE); } character { ECHO; return(CHARACTER); } end { ECHO; return(END); } endswitch { ECHO; return(ENDSWITCH); } function { ECHO; return(FUNCTION); } integer { ECHO; return(INTEGER); } is { ECHO; return(IS); } list { ECHO; return(LIST); } of { ECHO; return(OF); } others { ECHO; return(OTHERS); } returns { ECHO; return(RETURNS); } switch { ECHO; return(SWITCH); } when { ECHO; return(WHEN); } {id} { ECHO; yylval.iden = (CharPtr)malloc(yyleng + 1); strcpy(yylval.iden, yytext); return(IDENTIFIER);} {dec} { ECHO; yylval.value = atoi(yytext); return(INT_LITERAL); } {char} { ECHO; yylval.value = yytext[1]; return(CHAR_LITERAL); } {punc} { ECHO; return(yytext[0]); } . { ECHO; appendError(LEXICAL, yytext); } %%

symbols.h

// CMSC 430 Compiler Theory and Design // Project 3 Complete // UMGC CITE // Summer 2023 // This file contains the template symbol table template <typename T> class Symbols { public: void insert(char* lexeme, T entry); bool find(char* lexeme, T& entry); private: map<string, T> symbols; }; template <typename T> void Symbols<T>::insert(char* lexeme, T entry) { string name(lexeme); symbols[name] = entry; } template <typename T> bool Symbols<T>::find(char* lexeme, T& entry) { string name(lexeme); typedef typename map<string, T>::iterator Iterator; Iterator iterator = symbols.find(name); bool found = iterator != symbols.end(); if (found) entry = iterator->second; return found; }

values.cc

values.cc

// CMSC 430 Compiler Theory and Design
// Project 3 Skeleton
// UMGC CITE
// Summer 2023

// This file contains the bodies of the evaluation functions

#include   < string >
#include   < cmath >

using   namespace  std ;

#include   "values.h"
#include   "listing.h"

double  evaluateArithmetic ( double  left ,   Operators  operator_ ,   double  right )   {
     double  result ;
     switch   ( operator_ )   {
         case  ADD :
            result  =  left  +  right ;
             break ;
         case  MULTIPLY :
            result  =  left  *  right ;
             break ;
     }
     return  result ;
}

double  evaluateRelational ( double  left ,   Operators  operator_ ,   double  right )   {
     double  result ;
     switch   ( operator_ )   {
         case  LESS :
            result  =  left  <  right ;
             break ;
     }
     return  result ;
}

values.h

// CMSC 430 Compiler Theory and Design // Project 3 Skeleton // UMGC CITE // Summer 2023 // This file contains type definitions and the function // definitions for the evaluation functions typedef char* CharPtr; enum Operators {ADD, MULTIPLY, LESS, AND}; double evaluateArithmetic(double left, Operators operator_, double right); double evaluateRelational(double left, Operators operator_, double right);