CMSC 430
listing.cc
listing.cc
// CMSC 430 Compiler Theory and Design
// Project 2 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 2 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 g++ -o compile scanner.o parser.o listing.o scanner.o: scanner.c 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 listing.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
parser.y
/* CMSC 430 Compiler Theory and Design Project 2 Skeleton UMGC CITE Summer 2023 Project 2 Parser */ %{ #include <string> using namespace std; #include "listing.h" int yylex(); void yyerror(const char* message); %} %define parse.error verbose %token IDENTIFIER INT_LITERAL CHAR_LITERAL %token ADDOP MULOP ANDOP RELOP ARROW %token BEGIN_ CASE CHARACTER ELSE END ENDSWITCH FUNCTION INTEGER IS LIST OF OTHERS RETURNS SWITCH WHEN %% function: function_header optional_variable body ; function_header: FUNCTION IDENTIFIER RETURNS type ';' ; type: INTEGER | CHARACTER ; optional_variable: variable | %empty ; variable: IDENTIFIER ':' type IS statement ';' | IDENTIFIER ':' LIST OF type IS list ';' ; list: '(' expressions ')' ; expressions: expressions ',' expression| expression ; body: BEGIN_ statement_ END ';' ; statement_: statement ';' | error ';' ; statement: expression | WHEN condition ',' expression ':' expression | SWITCH expression IS cases OTHERS ARROW statement ';' ENDSWITCH ; cases: cases case | %empty ; case: CASE INT_LITERAL ARROW statement ';' ; condition: condition ANDOP relation | relation ; relation: '(' condition ')' | expression RELOP expression ; expression: expression ADDOP term | term ; term: term MULOP primary | primary ; primary: '(' expression ')' | INT_LITERAL | CHAR_LITERAL | IDENTIFIER '(' expression ')' | IDENTIFIER ; %% void yyerror(const char* message) { appendError(SYNTAX, message); } int main(int argc, char *argv[]) { firstLine(); yyparse(); lastLine(); return 0; }
scanner.l
/* CMSC 430 Compiler Theory and Design Project 2 Skeleton UMGC CITE Summer 2023 */ /* This file contains flex input file */ %{ #include <cstdio> #include <string> using namespace std; #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; return(ADDOP); } "*" { ECHO; return(MULOP); } "&" { ECHO; return(ANDOP); } "<" { ECHO; return(RELOP); } "=>" { ECHO; return(ARROW); } begin { ECHO; return(BEGIN_); } case { ECHO; return(CASE); } character { ECHO; return(CHARACTER); } else { ECHO; return(ELSE); } 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; return(IDENTIFIER);} {dec} { ECHO; return(INT_LITERAL); } {char} { ECHO; return(CHAR_LITERAL); } {punc} { ECHO; return(yytext[0]); } . { ECHO; appendError(LEXICAL, yytext); } %%