Add another version slightly cleaned up and using flex/bison with a header file
authorNick Downing <downing.nick@gmail.com>
Thu, 21 Jun 2018 13:14:19 +0000 (23:14 +1000)
committerNick Downing <downing.nick@gmail.com>
Thu, 21 Jun 2018 13:19:35 +0000 (23:19 +1000)
.gitignore
Makefile
calc.l [new file with mode: 0644]
calc.y [new file with mode: 0644]

index d719633..c41a4fd 100644 (file)
@@ -2,3 +2,7 @@
 cal
 lex.yy.c
 y.tab.c
+calc
+calc.tab.c
+calc.tab.h
+calc.yy.c
index ecd7219..b1c5ad5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,3 +1,6 @@
+all: cal calc
+
+# cal program
 cal: y.tab.o
        ${CC} -o $@ $<
 
@@ -9,5 +12,18 @@ y.tab.c: cal.y
 lex.yy.c: cal.l
        lex $<
 
+# calc program
+calc: calc.tab.o calc.yy.o
+       gcc -o $@ calc.tab.o calc.yy.o
+
+calc.tab.h: calc.tab.c
+calc.tab.c: calc.y
+       bison -d $<
+
+calc.yy.o: calc.yy.c calc.tab.h
+calc.yy.c: calc.l
+       flex -o $@ $<
+
+# other
 clean:
-       rm -f *.o cal lex.yy.c y.tab.c
+       rm -f *.o cal lex.yy.c y.tab.c calc calc.tab.c calc.tab.h calc.yy.c
diff --git a/calc.l b/calc.l
new file mode 100644 (file)
index 0000000..4bb295a
--- /dev/null
+++ b/calc.l
@@ -0,0 +1,14 @@
+%{
+#define YYSTYPE double
+#include "calc.tab.h"
+%}
+
+DIGIT [0-9]+\.?|[0-9]*\.[0-9]+
+
+%option noyywrap
+
+%%
+
+[ ]
+{DIGIT}        { yylval = atof(yytext); return NUM; }
+\n|.   { return yytext[0]; }
diff --git a/calc.y b/calc.y
new file mode 100644 (file)
index 0000000..d0efd30
--- /dev/null
+++ b/calc.y
@@ -0,0 +1,41 @@
+%{
+#include <stdio.h>
+#include <stdlib.h>
+#define YYSTYPE double
+%}
+
+%token NUM
+
+%left '+' '-'
+%left '*' '/'
+%right UMINUS
+
+%%
+
+S : S E '\n' { printf("Answer: %g\nEnter:\n", $2); }
+  | S '\n'
+  |
+  | error '\n' { yyerror("Error: Enter once more...\n"); yyerrok; }
+  ;
+E : E '+' E { $$ = $1 + $3; }
+  | E '-' E { $$ = $1 - $3; }
+  | E '*' E { $$ = $1 * $3; }
+  | E '/' E { $$ = $1 / $3; }
+  | '(' E ')' { $$ = $2; }
+  | '-' E %prec UMINUS { $$ = -$2; }
+  | NUM
+  ;
+
+%%
+
+int main()
+{
+  printf("Enter the expression:\n");
+  yyparse();
+}
+
+yyerror(char * s)
+{
+  printf("%s\n", s);
+  exit(EXIT_FAILURE);
+}