Home | History | Annotate | Line # | Download | only in test
      1 /*	$NetBSD: calc2.y,v 1.1.1.7 2016/01/09 21:59:45 christos Exp $	*/
      2 
      3 %parse-param { int regs[26] }
      4 %parse-param { int *base }
      5 
      6 %lex-param { int *base }
      7 
      8 %{
      9 # include <stdio.h>
     10 # include <ctype.h>
     11 
     12 #ifdef YYBISON
     13 #define YYLEX_PARAM base
     14 #define YYLEX_DECL() yylex(int *YYLEX_PARAM)
     15 #define YYERROR_DECL() yyerror(int regs[26], int *base, const char *s)
     16 int YYLEX_DECL();
     17 static void YYERROR_DECL();
     18 #endif
     19 
     20 %}
     21 
     22 %start list
     23 
     24 %token DIGIT LETTER
     25 
     26 %left '|'
     27 %left '&'
     28 %left '+' '-'
     29 %left '*' '/' '%'
     30 %left UMINUS   /* supplies precedence for unary minus */
     31 
     32 %% /* beginning of rules section */
     33 
     34 list  :  /* empty */
     35       |  list stat '\n'
     36       |  list error '\n'
     37             {  yyerrok ; }
     38       ;
     39 
     40 stat  :  expr
     41             {  printf("%d\n",$1);}
     42       |  LETTER '=' expr
     43             {  regs[$1] = $3; }
     44       ;
     45 
     46 expr  :  '(' expr ')'
     47             {  $$ = $2; }
     48       |  expr '+' expr
     49             {  $$ = $1 + $3; }
     50       |  expr '-' expr
     51             {  $$ = $1 - $3; }
     52       |  expr '*' expr
     53             {  $$ = $1 * $3; }
     54       |  expr '/' expr
     55             {  $$ = $1 / $3; }
     56       |  expr '%' expr
     57             {  $$ = $1 % $3; }
     58       |  expr '&' expr
     59             {  $$ = $1 & $3; }
     60       |  expr '|' expr
     61             {  $$ = $1 | $3; }
     62       |  '-' expr %prec UMINUS
     63             {  $$ = - $2; }
     64       |  LETTER
     65             {  $$ = regs[$1]; }
     66       |  number
     67       ;
     68 
     69 number:  DIGIT
     70          {  $$ = $1; (*base) = ($1==0) ? 8 : 10; }
     71       |  number DIGIT
     72          {  $$ = (*base) * $1 + $2; }
     73       ;
     74 
     75 %% /* start of programs */
     76 
     77 #ifdef YYBYACC
     78 extern int YYLEX_DECL();
     79 #endif
     80 
     81 int
     82 main (void)
     83 {
     84     int regs[26];
     85     int base = 10;
     86 
     87     while(!feof(stdin)) {
     88 	yyparse(regs, &base);
     89     }
     90     return 0;
     91 }
     92 
     93 #define UNUSED(x) ((void)(x))
     94 
     95 static void
     96 YYERROR_DECL()
     97 {
     98     UNUSED(regs); /* %parse-param regs is not actually used here */
     99     UNUSED(base); /* %parse-param base is not actually used here */
    100     fprintf(stderr, "%s\n", s);
    101 }
    102 
    103 int
    104 YYLEX_DECL()
    105 {
    106 	/* lexical analysis routine */
    107 	/* returns LETTER for a lower case letter, yylval = 0 through 25 */
    108 	/* return DIGIT for a digit, yylval = 0 through 9 */
    109 	/* all other characters are returned immediately */
    110 
    111     int c;
    112 
    113     while( (c=getchar()) == ' ' )   { /* skip blanks */ }
    114 
    115     /* c is now nonblank */
    116 
    117     if( islower( c )) {
    118 	yylval = c - 'a';
    119 	return ( LETTER );
    120     }
    121     if( isdigit( c )) {
    122 	yylval = (c - '0') % (*base);
    123 	return ( DIGIT );
    124     }
    125     return( c );
    126 }
    127