aboutsummaryrefslogtreecommitdiff
path: root/store/works/life/compile-principle-experiment/1/hoc.y
diff options
context:
space:
mode:
Diffstat (limited to 'store/works/life/compile-principle-experiment/1/hoc.y')
-rw-r--r--store/works/life/compile-principle-experiment/1/hoc.y65
1 files changed, 65 insertions, 0 deletions
diff --git a/store/works/life/compile-principle-experiment/1/hoc.y b/store/works/life/compile-principle-experiment/1/hoc.y
new file mode 100644
index 0000000..c4452ad
--- /dev/null
+++ b/store/works/life/compile-principle-experiment/1/hoc.y
@@ -0,0 +1,65 @@
+%{
+#define YYSTYPE double /* data type of yacc stack */
+#include <stdio.h>
+#include <ctype.h>
+#include <math.h>
+
+int yylex();
+int yyerror(const char * s);
+%}
+%token NUMBER
+%left '+' '-' /* left associative, same precedence */
+%left '*' '/' '%' /* left assoc., higher precedence */
+%left UNARYMINUS
+%%
+list: /* nothing */
+ | list '\n'
+ | list expr '\n' { printf("%lf\n", $2); }
+ ;
+expr: NUMBER { $$ = $1; }
+ | expr '+' expr { $$ = $1 + $3; }
+ | expr '-' expr { $$ = $1 - $3; }
+ | expr '*' expr { $$ = $1 * $3; }
+ | expr '/' expr { $$ = $1 / $3; }
+ | expr '%' expr { $$ = fmod($1, $3); }
+ | '-' expr %prec UNARYMINUS { $$ = -$2; }
+ | '(' expr ')' { $$ = $2; }
+ ;
+%%
+
+int lineno = 1;
+
+int main(int argc, char** argv)
+{
+ yyparse();
+ return 0;
+}
+
+int yylex()
+{
+ int c;
+
+ do {
+ c = getchar();
+ } while (c == ' ' || c == '\t');
+
+ if (c == EOF)
+ return 0;
+
+ if (c == '.' || isdigit(c)) {
+ ungetc(c, stdin);
+ scanf("%lf", &yylval);
+ return NUMBER;
+ }
+
+ if (c == '\n')
+ lineno++;
+
+ return c;
+}
+
+int yyerror(const char* s)
+{
+ fprintf(stderr, "Error occured near line %d\n", lineno);
+ return 0;
+}