uni

University stuff
git clone git://git.margiolis.net/uni.git
Log | Files | Refs | README | LICENSE

commit b8350feec76cd459f94c1511783ceb2576ec84ed
parent 1d7fb22b9ff8207d7303b430311e7ba8d3963d57
Author: Christos Margiolis <christos@margiolis.net>
Date:   Tue, 24 May 2022 00:43:10 +0300

almost

Diffstat:
Mlex_yacc_compilers/part3/Makefile | 2+-
Mlex_yacc_compilers/part3/input.txt | 43++++++++++++-------------------------------
Mlex_yacc_compilers/part3/lex.l | 25++++++++++++++++---------
Alex_yacc_compilers/part3/output.txt | 6++++++
Mlex_yacc_compilers/part3/syntax.y | 178+++++++++++++++++++++++++++++++++++++++++++------------------------------------
5 files changed, 132 insertions(+), 122 deletions(-)

diff --git a/lex_yacc_compilers/part3/Makefile b/lex_yacc_compilers/part3/Makefile @@ -2,7 +2,7 @@ all: bison -d syntax.y flex lex.l cc syntax.tab.c lex.yy.c -lm -o uniclips - ./uniclips input.txt + ./uniclips input.txt output.txt clean: rm -f *.yy.c *.output *.tab.c *.tab.h uniclips *.core diff --git a/lex_yacc_compilers/part3/input.txt b/lex_yacc_compilers/part3/input.txt @@ -1,31 +1,12 @@ -+1234 -50 --115 -3.14 --10.0 -+0.0001 -3.14e-10 -0e0 -static-facts -MoveUp -CUBES -sum-1 -table -pacman -A-21-b -?x -?X -?3 -?ad -?X1b23 -?32AbC -?ABcd1234de -"" -"Test" -"Hello world" -"Mark said, \"Boo!\"" -; this is a comment -ignore whitespace -#unknown ?2 ? ?hello ?world -deffacts defrule test -2 + 2 +(printout "hello" "hello") +(bind ?var 1) +(bind ?var (+ 1 2)) +(test (= 1 2)) +(= 1 (+ 2 3)) + +(defrule move-up + (+ 1 2) + (- 1 (+ 1 (* 1 2))) + (test (= 1 2)) + -> + (printout "hello")) diff --git a/lex_yacc_compilers/part3/lex.l b/lex_yacc_compilers/part3/lex.l @@ -8,8 +8,8 @@ * Με βάση το μέρος Α2, υλοποιούμε τις κανονικές εκφράσεις και τις * αντιστοιχούμε στα κατάλληλα tokens. */ -FUNC deffacts|defrule|test|bind|read|printout|quit|"+"|"-"|"*"|"/"|"="|"e" -DELIM [ \t]+ +ARITH "+"|"-"|"*"|"/"|"=" +DELIM [ \t\n]+ INT 0|[+-]?[1-9]+[0-9]* FLOAT [+-]?[0-9]+((\.[0-9]+)([eE][+-]?[0-9]*)?|([eE][+-]?[0-9]*)?) STR \"[^\"\\]*(?:\\.[^\"\\]*)*\" @@ -22,17 +22,24 @@ COMMENT ;.* * οποίο ανήκει */ %% -{FUNC} { yylval.sval = strdup(yytext); return FUNC; } -{INT} { yylval.dval = strtod(yytext, NULL); return INT; } -{FLOAT} { yylval.dval = strtod(yytext, NULL); return FLOAT; } -{STR} { yylval.sval = strdup(yytext); return STR; } -{DEFIN} { yylval.sval = strdup(yytext); return DEFIN; } -{VAR} { yylval.sval = strdup(yytext); return VAR; } +"deffacts" { return DEFFACTS; } +"defrule" { return DEFRULE; } +"bind" { return BIND; } +"read" { return READ; } +"printout" { return PRINT; } +"test" { return TEST; } +"=" { return COMP; } "(" { return LPAR; } ")" { return RPAR; } "->" { return ARROW; } -\n { return NEWLINE; } +{ARITH} { return ARITH; } +{INT} { return INT; } +{FLOAT} { return FLOAT;} +{STR} { return STR; } +{DEFIN} { return DEFIN; } +{VAR} { return VAR; } {DELIM} { /* ignore whitespace */ } {COMMENT} { /* skip comments */ } +"\n" { return NEWLINE; } . { return UNKNOWN; } %% diff --git a/lex_yacc_compilers/part3/output.txt b/lex_yacc_compilers/part3/output.txt @@ -0,0 +1,6 @@ +input.txt: success + +correct words: 0 +correct expressions: 12 +wrong words: 0 +wrong expressions: 0 diff --git a/lex_yacc_compilers/part3/syntax.y b/lex_yacc_compilers/part3/syntax.y @@ -2,116 +2,132 @@ #include <err.h> #include <stdio.h> #include <stdlib.h> -#include <string.h> -#include <math.h> +/* Silence warnings... */ extern int yylex(void); -extern int yyparse(void); + +/* Input and output files. */ extern FILE *yyin, *yyout; -extern char *yytext; -double func(char *); -double calc(char *, double, double); +int cw = 0; /* correct words */ +int ce = 0; /* correct expressions */ +int ww = 0; /* wrong words */ +int we = 0; /* wrong expressions */ + void yyerror(const char *); %} -%union { - double dval; - char *sval; -} - -%token <sval> FUNC STR DEFIN VAR -%token <dval> INT FLOAT -%token NEWLINE UNKNOWN LPAR RPAR ARROW - -%type <dval> expr +/* Tokens declared from flex. */ +%token DEFFACTS DEFRULE BIND READ PRINT TEST ARITH INT FLOAT COMP +%token STR DEFIN VAR LPAR RPAR ARROW NEWLINE UNKNOWN %start prog %% +/* Start here. */ prog: - { printf("> "); } - | prog expr NEWLINE { printf("%f\n> ", $2); } + | prog NEWLINE + | prog expr ; -expr: - INT { $$ = $1; } - | FLOAT { $$ = $1; } - | LPAR FUNC RPAR { $$ = func($2); } - | LPAR FUNC expr expr RPAR { $$ = calc($2, $3, $4); } - | error { yyerror("error"); } +/* + * Declare numbers. Variables only accept numerical values so add them here as + * well. + */ +num: + INT + | FLOAT + | VAR ; -%% -double -func(char *op) -{ - double n; - int rc; - - if (strcmp(op, "quit") == 0) { - exit(0); - } else if (strcmp(op, "read") == 0) { - do { - printf("read> "); - rc = scanf("%lf", &n); - (void)getchar(); - } while (rc != 1); - return (n); - } +/* Accept any number of strings (for use in printout) */ +str: + STR + | str STR + ; - yyerror("invalid expression"); - /* NOT REACHED */ - return (0); -} +/* (= (expr)) */ +cmp: + LPAR COMP expr expr RPAR + ; -double -calc(char *op, double arg1, double arg2) -{ - if (strcmp(op, "+") == 0) - return (arg1 + arg2); - else if (strcmp(op, "-") == 0) - return (arg1 - arg2); - else if (strcmp(op, "*") == 0) - return (arg1 * arg2); - else if (strcmp(op, "/") == 0) { - if (arg2 == 0) - yyerror("cannot divide by 0"); - return (arg1 / arg2); - } - else if (strcmp(op, "e") == 0) - return (pow(arg1, arg2)); - else if (strcmp(op, "=") == 0) - return (arg1 == arg2); +/* (test (= (expr))) */ +test: + LPAR TEST cmp RPAR + ; - yyerror("invalid expression"); - /* NOT REACHED */ - return (0); -} +/* (prinout (str)...) */ +print: + LPAR PRINT str RPAR + ; +fact: + expr + | fact expr + ; + +/* We match expressions here. */ +expr: + num /* numbers */ + | cmp { ce++; } /* comparisons */ + | test { ce++; } /* test keyword */ + | print { ce++; } /* (printout "str"...) */ + | LPAR READ RPAR { ce++; } /* (read) */ + | LPAR ARITH expr expr RPAR { ce++; } /* (arithmetic_op (expr)...) */ + | LPAR BIND VAR expr RPAR { ce++; } /* (bind ?var (expr)) */ + | LPAR DEFFACTS DEFIN fact RPAR { ce++; } /* (deffacts DEF facts...) */ + /* (defrule DEF + * (facts) + * ... + * (test) + * -> + * (printout)) + */ + | LPAR DEFRULE DEFIN fact test ARROW print RPAR { ce++; } + | error { we++; if (ce > 0) ce--; } + ; +%% + +/* Print errors. */ void yyerror(const char *s) { fprintf(stderr, "%s\n", s); - exit(1); } int main(int argc, char *argv[]) { - /*if (argc < 2) {*/ - /*fprintf(stderr, "usage: %s input [output]\n", *argv);*/ - /*return (-1);*/ - /*}*/ - /*if ((yyin = fopen(argv[1], "r")) == NULL)*/ - /*err(1, "fopen(%s)", argv[1]);*/ - /*if (argc == 3 && (yyout = fopen(argv[2], "w")) == NULL)*/ - /*err(1, "fopen(%s)", argv[2]);*/ - - if (yyparse() == 0) - fprintf(stderr, "success\n"); - else - fprintf(stderr, "failure\n"); + /* We need at least 1 input and 1 output file... */ + if (argc < 3) { + fprintf(stderr, "usage: %s input... output\n", *argv); + return (-1); + } + + /* Open last file as output. */ + if ((yyout = fopen(argv[--argc], "w")) == NULL) + err(1, "fopen(%s)", argv[argc]); + + /* Parse all input files in reverse order. */ + while (argc-- > 1) { + if ((yyin = fopen(argv[argc], "r")) == NULL) + err(1, "fopen(%s)", argv[argc]); + /* Parse file */ + if (yyparse() == 0) + fprintf(yyout, "%s: success\n", argv[argc]); + else + fprintf(yyout, "%s: failure\n", argv[argc]); + fclose(yyin); + } + + /* Print results. */ + fprintf(yyout, "\n"); + fprintf(yyout, "correct words: %d\n", cw); + fprintf(yyout, "correct expressions: %d\n", ce); + fprintf(yyout, "wrong words: %d\n", ww); + fprintf(yyout, "wrong expressions: %d\n", we); + + fclose(yyout); return (0); }