I am writing a Flex & Bison program for a class, and I feel that I am almost done. However, when I try to run the program with an input file, it simply refuses to read it and has me input lines instead.
I have two code files:tp2.l(for Flex) and tp2.y (for Bison). Their code is below.
tp2.l (Flex code)
%option noyywrap%{ //#include <stdio.h> #include <stdlib.h> //#include <string.h> #include "tp2.tab.h" int yylex();%}%%[0-9]+ { printf("%s, integer\n", yytext); yylval.numValue = atoi(yytext); return NUM; }"+" { printf("%s, operator\n", yytext); return ADD; }"-" { printf("%s, operator\n", yytext); return SUB; }"*" { printf("%s, operator\n", yytext); return MUL; }"/" { printf("%s, operator\n", yytext); return DIV; }"^" { printf("%s, operator\n", yytext); return POW; }"=" { printf("equal sign\n"); return EQUAL; }[a-zA-Z][a-zA-Z0-9]* { strcpy(yylval.stringValue, yytext); printf("%s, variable\n", yytext); return VAR; }[ \t] {}"\n" { printf("Newline\n"); yylval.charValue = yytext[0]; return ENDL; }. { printf("Unknown\n"); return ERR; }%%tp2.y (Bison code)
%{ #include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> const int ADDITION = 0; const int SUBTRACTION = 1; const int MULTIPLICATION = 2; const int DIVISION = 3; const int POWER = 4; // Node types const int INSTRUCTION = 0; const int VALUE = 1; const int VARIABLE = 2; int yyerror(const char *s); extern int yylex(); extern int yyparse(); extern FILE *yyin; // A parse tree node. Has either a value, instruction, or variable name. struct ParseNode { int type; int value; // Holds numerical value.. char varName[255]; // Holds variable name. char symbol; // Mathematical symbol // Branch nodes, can be NULL. struct ParseNode* left; struct ParseNode* right; }; // Node creation functions. // These create & return a node. If the ROOT is NULL, set the root to the node you created. // Creates & returns an instruction node. struct ParseNode *createInstructionNode(char op, struct ParseNode* left, struct ParseNode* right) { struct ParseNode* node = (struct ParseNode* )malloc(sizeof(struct ParseNode)); //struct ParseNode node; node->type = INSTRUCTION; node->symbol = op; node->left = left; node->right = right; return node; } // Creates & returns a value node. struct ParseNode *createValueNode(int value, struct ParseNode* left, struct ParseNode* right) { struct ParseNode* node = (struct ParseNode* )malloc(sizeof(struct ParseNode)); node->type = VALUE; node->value = value; node->left = left; node->right = right; return node; } // Creates & returns a variable node. struct ParseNode *createVariableNode(char *varName, struct ParseNode* left, struct ParseNode* right) { struct ParseNode* node = (struct ParseNode* )malloc(sizeof(struct ParseNode)); node->type = VARIABLE; node->left = left; node->right = right; strcpy(varName, node->varName); return node; } // Calculate the depth of a tree node. int treeDepth(struct ParseNode *root) { if(root == NULL) { return 0; } else { int left_depth = treeDepth(root->left); int right_depth = treeDepth(root->right); if(left_depth > right_depth) return left_depth; return right_depth; } } // Print a NULL spot in the tree. void printNull(int depth, int index) { if(depth > 0) { printNull(depth-1, (index*2)); printNull(depth-1, (index*2) + 1); } printf("%d %d \n", depth, index); } void printNode(struct ParseNode* root, int depth, int index) { // Recurse to lower nodes. if(depth > 0) { if(root->left == NULL) printNull(depth-1, (index*2)); else printNode(root->left, depth-1, (index * 2)); if(root->right == NULL) printNull(depth-1, (index*2) + 1); else printNode(root->right, depth-1, (index * 2) + 1); } // Print the contents of the node. printf("%d %d ", depth, index); if(root == NULL) { printf("_"); return; } switch(root->type) { case 0: printf("%c", root->symbol); break; case 2: printf("%d", root->value); break; default: printf("%s", root->varName); break; } printf("\n"); } // Print a tree using postorder traversal. void printTree(struct ParseNode* root) { int depth = treeDepth(root); printNode(root, depth, 1); } void freeTree(struct ParseNode *node) { if(node->left != NULL) freeTree(node->left); if(node->right != NULL) freeTree(node->right); node = NULL; }%}%union{ int numValue; char stringValue[255]; char charValue; struct ParseNode *node;}// I am sorry I was not able to finish this. I would like to come in for help.%token <node> NUM VAR EQUAL ADD SUB MUL DIV POW ENDL ERR%type <node> assign exp term factor//%type <node> assign exp//%type <node> input assign exp term factor%%input: /* nothing */| input exp ENDL { printTree($2); freeTree($2); };assign: VAR EQUAL exp { $$ = createInstructionNode('=', $1, $3); };exp: term { $$ = $1; }| exp ADD exp { $$ = createInstructionNode('+', $1, $3); }| exp SUB exp { $$ = createInstructionNode('-', $1, $3); };term: factor { $$ = $1; }| term MUL term { $$ = createInstructionNode('*', $1, $3); }| term DIV term { $$ = createInstructionNode('/', $1, $3); }| term POW term { $$ = createInstructionNode('^', $1, $3); };factor: exp { $$ = $1; }| NUM { $$ = createValueNode($1->value, NULL, NULL); }| VAR { $$ = createVariableNode($1->varName, NULL, NULL); };%%int yyerror(const char *s){ fprintf(stderr, "error: %s\n", s); return 0;}int main(int argc, char *argv[]){ yyin = fopen(argv[1], "r"); if(!yyin) { perror("File not found."); return 1; } do { yyparse(); } while( !feof(yyin) ); //yyparse(); fclose(yyin); return 0;}And this is the makefile I use:
tp2: tp2.l tp2.y bison -d tp2.y flex tp2.l cc -o $@ tp2.tab.c lex.yy.c -lflWhen I run it using ./a.out input.txt, it should try to read in the file line by line and print a parse tree. Instead, it simply asks for my input on the command line.
I think this is an issue with trying to set yyin to read from a file. Could anyone help me with this?