/////////////
// Compile
/////////////
bison -d field.y
flex field.l
g++ field.tab.c lex.yy.c -ll
/////////////
// field.y
/////////////
%{
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int yylex(void);
void yyerror(const char *s);
vector<string> inv;
%}
%union {
char *s;
}
%token LOOK TAKE QUIT TREE DOOR KEY EOL
%token <s> WORD
%type <s> item
%%
input:
/* empty string / epsilon */
| input command EOL
;
command:
LOOK command {
cout << "You see a tree. Your Inventory:" << endl;
for (int i = 0; i < inv.size(); i++){
cout << inv[i] << endl;
}
}
| TAKE item command { //This line causes a shift/reduce warning! Bison will shift by default.
cout << "You took the " << $2 << "." << endl;
free($2); //Free the strdup (malloc) or we will eventually run out of memory!
}
| QUIT command {
printf("Goodbye.\n");
YYACCEPT;
}
| TREE command {
cout << "The tree is hiding a key." << endl;
}
| DOOR command {
cout << "This is the door of the shack." << endl;
if (find(inv.begin(), inv.end(), "Key") != inv.end()) {
cout << "The door opens with the key. You win!" << endl;
YYACCEPT;
} else {
cout << "The door is locked." << endl;
}
}
| WORD command {
cout << "You can imagine a " << $1 << "." << endl;
}
| /* empty string / epsilon */
;
item:
WORD {
inv.push_back($1); //$1 is the value of WORD
$$ = $1;
}
| KEY {
inv.push_back("Key");
$$ = strdup("Key");
}
| { printf("Take what?\n"); }
%%
int main(void) {
cout << "You wake up in a field in Oakland (uh oh). You see a shack with a door, and a tree." << endl;
yyparse();
return 0;
}
void yyerror(const char *s) {
fprintf(stderr, "Error: %s\n", s);
}
////////////
// field.l
////////////
%{
#include "field.tab.h"
%}
%%
"look" { return LOOK; }
"take" { return TAKE; }
"quit" { return QUIT; }
"tree" { return TREE; }
"door" { return DOOR; }
"key" { return KEY; }
\n { return EOL; }
[ \t]+ ; //ignore spaces
[a-zA-Z]+ { yylval.s = strdup(yytext); return WORD; }
. { printf("Not valid.\n"); }
%%
int yywrap(void){
return 1;
}