Interpreter Project Flex/Bison
Required Project 2 Files/scanner.l
/* This file contains flex input file */ %{ #include <cstdio> #include <string> using namespace std; #include "listing.h" #include "parser.tab.h" %} %option noyywrap ws [ \t\r]+ comment "//".*\n comment2 "--".* line [\n] id [_A-Za-z]([A-Za-z0-9_])* digit [0-9] dec {digit}+ hex_literal "#"({digit}|[A-Fa-f])+ char '([^\\]|\\[btnrf])' punc [\(\),:;] %% {ws} { ECHO; } {comment} { ECHO; nextLine(); } {line} { ECHO; nextLine(); } "+" { ECHO; return(ADDOP); } "-" { ECHO; return(ADDOP); } "*" { ECHO; return(MULOP); } "/" { ECHO; return(MULOP); } "%" { ECHO; return(MODOP); } "rem" { ECHO; return(REMOP); } "^" { ECHO; return(EXPOP); } "~" { ECHO; return(NEGOP); } "&" { ECHO; return(ANDOP); } "<" { ECHO; return(RELOP); } "=>" { ECHO; return(ARROW); } "=" { ECHO; return(RELOP); } "<>" { ECHO; return(RELOP); } ">" { ECHO; return(RELOP); } ">=" { ECHO; return(RELOP); } "<=" { ECHO; return(RELOP); } "|" { ECHO; return(OROP); } "!" { ECHO; return(NOTOP); } 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); } else { ECHO; return(ELSE); } elsif { ECHO; return(ELSIF); } endfold { ECHO; return(ENDFOLD); } endif { ECHO; return(ENDIF); } fold { ECHO; return(FOLD); } if { ECHO; return(IF); } left { ECHO; return(LEFT); } real { ECHO; return(REAL); } right { ECHO; return(RIGHT); } then { ECHO; return(THEN); } reduce { ECHO; return(REDUCE); } endreduce { ECHO; return(ENDREDUCE); } {id} { if (strstr(yytext, "___") || yytext[0] == '_' || yytext[strlen(yytext) - 1] == '_') { appendError(LEXICAL, "Invalid Identifier " + string(yytext)); // Flag invalid identifiers } else { ECHO; return(IDENTIFIER); } } [0-9]*\.[0-9]+([eE][+-]?[0-9]+)? { return(REAL_LITERAL); } {hex_literal} { ECHO; return(HEX_LITERAL); } {dec} { ECHO; return(INT_LITERAL); } {char} { ECHO; return(CHAR_LITERAL); } {punc} { ECHO; return(yytext[0]); } "--".* { /* Ignore comments starting with -- */ } . { ECHO; appendError(LEXICAL, "Invalid Character " + string(yytext)); } %%
__MACOSX/Required Project 2 Files/._scanner.l
Required Project 2 Files/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
__MACOSX/Required Project 2 Files/._makefile
Required Project 2 Files/listing.cc
Required Project 2 Files/listing.cc
// This file contains the bodies of the functions that produces the
// compilation listing
#include
<
cstdio
>
#include
<
string
>
#include
<
queue
>
using
namespace
std
;
#include
"listing.h"
static
queue
<
string
>
errorQueue
;
static
int
lineNumber
;
static
string error
=
""
;
static
int
totalErrors
=
0
;
int
lexicalErrors
=
0
;
int
syntaxErrors
=
0
;
int
semanticErrors
=
0
;
static
void
displayErrors
();
void
firstLine
()
{
lineNumber
=
1
;
printf
(
"\n%4d "
,
lineNumber
);
}
void
nextLine
()
{
displayErrors
();
lineNumber
++
;
printf
(
"%4d "
,
lineNumber
);
}
int
lastLine
()
{
printf
(
"\n"
);
displayErrors
();
printf
(
" Lexical Errors: %d\n"
,
lexicalErrors
);
printf
(
" Syntax Errors: %d\n"
,
syntaxErrors
);
printf
(
" Semantic Errors: %d\n"
,
semanticErrors
);
if
(
totalErrors
==
0
)
{
printf
(
"\nCompiled Successfully\n"
);
}
return
totalErrors
;
}
void
appendError
(
ErrorCategories
errorCategory
,
string message
)
{
string messages
[]
=
{
"Lexical Error: "
,
"Syntax Error: "
,
"Semantic Error: "
,
"Semantic Error: Duplicate Identifier "
,
"Semantic Error: Undeclared "
};
errorQueue
.
push
(
messages
[
errorCategory
]
+
message
);
switch
(
errorCategory
)
{
case
LEXICAL
:
lexicalErrors
++
;
break
;
case
SYNTAX
:
syntaxErrors
++
;
break
;
case
GENERAL_SEMANTIC
:
case
DUPLICATE_IDENTIFIER
:
case
UNDECLARED
:
semanticErrors
++
;
break
;
}
totalErrors
++
;
}
void
displayErrors
()
{
while
(
!
errorQueue
.
empty
())
{
printf
(
"%s\n"
,
errorQueue
.
front
().
c_str
());
errorQueue
.
pop
();
}
}
__MACOSX/Required Project 2 Files/._listing.cc
Required Project 2 Files/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 REAL_LITERAL HEX_LITERAL %token ADDOP MULOP EXPOP MODOP REMOP ANDOP OROP NOTOP NEGOP RELOP ARROW %token BEGIN_ CASE CHARACTER ELSE END ENDSWITCH FUNCTION INTEGER IS LIST OF OTHERS %token RETURNS SWITCH WHEN REAL IF THEN ENDIF ELSIF FOLD LEFT RIGHT ENDFOLD %token REDUCE ENDREDUCE %% function: function_header optional_variable body ; function_header: FUNCTION IDENTIFIER optional_parameters RETURNS type ';' | error ';' ; type: INTEGER | CHARACTER | REAL ; optional_variable: variable_list | %empty ; variable_list: variable_list variable | variable; variable: IDENTIFIER ':' type IS statement ';' | IDENTIFIER ':' LIST OF type IS list ';' ; list: '(' expressions ')' ; optional_parameters: parameters | %empty; parameters: parameters ',' parameter | parameter; parameter: IDENTIFIER ':' type; expressions: expressions ',' expression| expression ; body: BEGIN_ statement_ END ';' ; statement_list: statement_list statement_ | statement_; statement_: statement ';' | error ';' ; statement: expression | WHEN condition ',' expression ':' expression | SWITCH expression IS cases OTHERS ARROW statement ';' ENDSWITCH ;| IF condition THEN statement_list elsif_statements ELSE statement_list ENDIF | FOLD direction operator list_choice ENDFOLD ; elsif_statements: elsif_statements ELSIF condition THEN statement_list | %empty; cases: cases case_ | %empty ; case_: case ';' | error ';' ; case: CASE INT_LITERAL ARROW statement ; direction: LEFT | RIGHT; operator: ADDOP | MULOP; list_choice: list | IDENTIFIER; condition: condition ANDOP logical | condition OROP logical | logical; logical: NOTOP relation | relation; relation: '(' condition ')' | expression RELOP expression ; expression: expression ADDOP term | term ; term: term MULOP exponentiation | term MODOP exponentiation | exponentiation; exponentiation: exponentiation EXPOP primary | primary; primary: '(' expression ')' | NEGOP primary | INT_LITERAL | CHAR_LITERAL | REAL_LITERAL | HEX_LITERAL | IDENTIFIER '(' expression ')' | IDENTIFIER ; %% void yyerror(const char* message) { appendError(SYNTAX, message); } int main(int argc, char *argv[]) { firstLine(); yyparse(); lastLine(); return 0; }
__MACOSX/Required Project 2 Files/._parser.y
Required Project 2 Files/listing.h
// 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);