uni

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

syntax.y (2549B)


      1 %{
      2 #include <err.h>
      3 #include <stdio.h>
      4 #include <stdlib.h>
      5 
      6 /* Silence warnings... */
      7 extern int	yylex(void);
      8 
      9 /* Input and output files. */
     10 extern FILE	*yyin, *yyout;
     11 
     12 extern int	cw;	/* correct words */
     13 extern int	ww;	/* wrong words */
     14 int		ce = 0;	/* correct expressions */
     15 int		we = 0;	/* wrong expressions */
     16 
     17 void	yyerror(const char *);
     18 %}
     19 
     20 /* Tokens declared from flex. */
     21 %token DEFFACTS DEFRULE BIND READ PRINT TEST ARITH INT FLOAT COMP
     22 %token STR DEFIN VAR LPAR RPAR ARROW NEWLINE UNKNOWN
     23 
     24 %start prog
     25 
     26 %%
     27 /* Start here. */
     28 prog:
     29 	| prog NEWLINE
     30 	| prog expr
     31 	;
     32 
     33 /*
     34  * Declare numbers. Variables only accept numerical values so add them here as
     35  * well.
     36  */
     37 num:
     38 	INT
     39 	| FLOAT
     40 	| VAR
     41 	;
     42 
     43 /* Accept any number of strings (for use in printout) */
     44 str:
     45 	STR
     46 	| str STR
     47 	;
     48 
     49 /* (= (expr)) */
     50 cmp:
     51 	LPAR COMP expr expr RPAR
     52 	;
     53 
     54 /* (test (= (expr))) */
     55 test:
     56 	LPAR TEST cmp RPAR
     57 	;
     58 
     59 /* (prinout (str)...) */
     60 print:
     61 	LPAR PRINT str RPAR
     62 	;
     63 
     64 fact:
     65 	expr
     66 	| fact expr
     67 	;
     68 
     69 /* We match expressions here. */
     70 expr:
     71 	num						/* numbers */
     72 	| cmp				{ ce++; }	/* comparisons */
     73 	| test				{ ce++; }	/* test keyword */
     74 	| print				{ ce++; }	/* (printout "str"...) */
     75 	| LPAR READ RPAR		{ ce++; }	/* (read) */
     76 	| LPAR ARITH expr expr RPAR	{ ce++; }	/* (arithmetic_op (expr)...) */
     77 	| LPAR BIND VAR expr RPAR	{ ce++; }	/* (bind ?var (expr)) */
     78 	| LPAR DEFFACTS DEFIN fact RPAR { ce++; }	/* (deffacts DEF facts...) */
     79 	/* (defrule DEF
     80 	 *	(facts)
     81 	 *	...
     82 	 *	(test)
     83 	 *	->
     84 	 *	(printout))
     85 	 */
     86 	| LPAR DEFRULE DEFIN fact test ARROW print RPAR { ce++; }
     87 	| error				{ we++; if (ce > 0) ce--; }
     88 	;
     89 %%
     90 
     91 /* Print errors. */
     92 void
     93 yyerror(const char *s)
     94 {
     95 	fprintf(stderr, "%s\n", s);
     96 }
     97 
     98 int
     99 main(int argc, char *argv[])
    100 {
    101 	/* We need at least 1 input and 1 output file... */
    102 	if (argc < 3) {
    103 		fprintf(stderr, "usage: %s input... output\n", *argv);
    104 		return (-1);
    105 	}
    106 
    107 	/* Open last file as output. */
    108 	if ((yyout = fopen(argv[--argc], "w")) == NULL)
    109 		err(1, "fopen(%s)", argv[argc]);
    110 
    111 	/* Parse all input files in reverse order. */
    112 	while (argc-- > 1) {
    113 		if ((yyin = fopen(argv[argc], "r")) == NULL)
    114 			err(1, "fopen(%s)", argv[argc]);
    115 		/* Parse file */
    116 		if (yyparse() == 0)
    117 			fprintf(yyout, "%s: success\n", argv[argc]);
    118 		else
    119 			fprintf(yyout, "%s: failure\n", argv[argc]);
    120 		fclose(yyin);
    121 	}
    122 
    123 	/* Print results. */
    124 	fprintf(yyout, "\n");
    125 	fprintf(yyout, "correct words: %d\n", cw);
    126 	fprintf(yyout, "correct expressions: %d\n", ce);
    127 	fprintf(yyout, "wrong words: %d\n", ww);
    128 	fprintf(yyout, "wrong expressions: %d\n", we);
    129 
    130 	fclose(yyout);
    131 
    132 	return (0);
    133 }