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