Skip to content

Instantly share code, notes, and snippets.

@clarknelson
Created June 4, 2016 02:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save clarknelson/f70ff0ccab860ab587b93b42014b8acc to your computer and use it in GitHub Desktop.
Save clarknelson/f70ff0ccab860ab587b93b42014b8acc to your computer and use it in GitHub Desktop.
%{
/*-------------------------------------------------------------------------*
*--- ---*
*--- assign4.lex ---*
*--- ---*
*--- This file defines the LEX-style tokenizer for the language ---*
*--- at the bottom of page 173 of Fischer, Cytron, LeBlanc "Crafting ---*
*--- a Compiler" Addison-Wesley, 2010. ---*
*--- ---*
*--- ---- ---- ---- ---- ---- ---- ---- ---- ---*
*--- ---*
*--- Version 1.0 2016 May 25 Joseph Phillips ---*
*--- ---*
*-------------------------------------------------------------------------*/
#include "assign4.h"
#include "assign4.tab.h"
#undef YY_INPUT
#define YY_INPUT(buffer, result, maxSize) { result = ourInput(buffer,maxSize); }
extern int ourInput(char* buffer, int maxSize);
%}
%%
[0-9]+ {
printf("%s", yytext);
yylval.number_=atoi(yytext);
return(NUM);
}
[ \t\n] { /* ignore spaces */; }
\( { return(LPAREN); }
\) { return(RPAREN); }
\+ { return(PLUS); }
\* { return(STAR); }
%%
// PURPOSE: To hold the input file from which to read the program (if it is
// not 'stdin').
FILE* filePtr = NULL;
// PURPOSE: To point to the beginning of the input yet to read (if being
// typed from the command line).
char* textPtr = NULL;
// PURPOSE: To point to the end of all input (if being typed from the command
// line).
char* textEndPtr = NULL;
// PURPOSE: To hold the value that results from parse.
double result = 0.0;
// PURPOSE: To return 1 if the tokenizer should quit after EOF is reached.
// Returns 0 otherwise. No parameters.
int yywrap(){
return(1);
}
// PURPOSE: To show the error message pointed to by 'cPtr'. Returns '0'.
int yyerror (const char *cPtr)
{
printf("%s, sorry!\n",cPtr);
return(1);
}
// PURPOSE: To get up to 'maxSize' more characters of input and put them
// into 'buffer'. Returns how many characters were obtained.
int ourInput( char* buffer, int maxSize ) {
unsigned int n;
if (filePtr == NULL) {
n = MIN(maxSize, textEndPtr - textPtr);
if (n > 0) {
memcpy(buffer,textPtr,n);
textPtr += n;
}
} else {
errno = 0;
while ( (n = fread(buffer,1,maxSize,yyin)) == 0 && ferror(yyin))
{
if (errno != EINTR) {
fprintf(stderr,"Reading file failed: %s\n",strerror(errno));
exit(EXIT_FAILURE);
}
errno = 0;
clearerr(yyin);
}
}
return(n);
}
// PURPOSE: To parse and execute the program whose filename is given on the
// command line at 'argv[1]' (if 'argc' >= 1), or that the user types in.
// Returns 'EXIT_SUCCESS' on success or 'EXIT_FAILURE' otherwise.
int main (int argc, char* argv[]) {
// I. Application validity check:
// II. Parse and execute program:
// II.A. Get program source:
char line[LINE_LEN];
if ( (argc >= 2) && ( (filePtr = fopen(argv[1],"r")) != NULL ) )
{
yyin = filePtr;
} else {
printf("Please enter an expression: ");
textPtr = fgets(line,LINE_LEN,stdin);
textEndPtr = textPtr + strlen(textPtr);
}
// II.B. Attempt to parse program:
try {
yyparse();
}
catch (std::string* errStrPtr)
{
fprintf(stderr,"Error: %s.\n",errStrPtr->c_str());
delete(errStrPtr);
}
// II.C. Print output:
printf("%g\n",result);
// II.D. Clean up:
// II.D.1. Close file (if open):
if (filePtr != NULL)
fclose(filePtr);
fflush(stdout);
// III. Finished:
return(EXIT_SUCCESS);
}
%{
/*-------------------------------------------------------------------------*
*--- ---*
*--- assign4.y ---*
*--- ---*
*--- This file defines the YACC-style grammar for the language ---*
*--- at the bottom of page 173 of Fischer, Cytron, LeBlanc "Crafting ---*
*--- a Compiler" Addison-Wesley, 2010. ---*
*--- ---*
*--- ---- ---- ---- ---- ---- ---- ---- ---- ---*
*--- ---*
*--- Version 1.0 2016 May 25 Joseph Phillips ---*
*--- ---*
*-------------------------------------------------------------------------*/
#include "assign4.h"
%}
%union
{
double number_;
NumberList* listPtr_;
}
%start start
%nonassoc LPAREN RPAREN
%nonassoc STAR PLUS
%token <number_> NUM
%type <number_> start
%type <number_> expr
%type <number_> value
%type <listPtr_> values
%%
// YOUR CODE HERE FOR GRAMMAR RULES
start : value
{
printf("start : value\n");
};
value : NUM
{
printf("value : NUM\n");
}
| LPAREN expr RPAREN
{
printf("value : LPAREN expr RPAREN\n");
};
expr : PLUS value value
{
printf("expr : PLUS value value\n");
}
| STAR values
{
printf("expr : STAR values\n");
}
values : value value
{
printf("values : value value\n");
}
|
{
printf("values : \n");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment