197403Sobrien%{
297403Sobrien# include <stdio.h>
397403Sobrien# include <ctype.h>
497403Sobrien
597403Sobrienint regs[26];
697403Sobrienint base;
797403Sobrien
897403Sobrienextern int yylex(void);
997403Sobrienstatic void yyerror(const char *s);
1097403Sobrien
1197403Sobrien%}
1297403Sobrien
1397403Sobrien%start list
1497403Sobrien
1597403Sobrien%token DIGIT LETTER
1697403Sobrien
1797403Sobrien%left '|'
1897403Sobrien%left '&'
1997403Sobrien%left '+' '-'
2097403Sobrien%left '*' '/' '%'
2197403Sobrien%left UMINUS   /* supplies precedence for unary minus */
2297403Sobrien
2397403Sobrien%% /* beginning of rules section */
2497403Sobrien
2597403Sobrienlist  :  /* empty */
2697403Sobrien      |  list stat '\n'
2797403Sobrien      |  list error '\n'
2897403Sobrien            {  yyerrok ; }
2997403Sobrien      ;
3097403Sobrien
3197403Sobrienstat  :  expr
3297403Sobrien            {  printf("%d\n",$1);}
3397403Sobrien      |  LETTER '=' expr
3497403Sobrien            {  regs[$1] = $3; }
3597403Sobrien      ;
3697403Sobrien
3797403Sobrienexpr  :  '(' expr ')'
3897403Sobrien            {  $$ = $2; }
3997403Sobrien      |  expr '+' expr
4097403Sobrien            {  $$ = $1 + $3; }
4197403Sobrien      |  expr '-' expr
4297403Sobrien            {  $$ = $1 - $3; }
4397403Sobrien      |  expr '*' expr
4497403Sobrien            {  $$ = $1 * $3; }
4597403Sobrien      |  expr '/' expr
4697403Sobrien            {  $$ = $1 / $3; }
4797403Sobrien      |  expr '%' expr
4897403Sobrien            {  $$ = $1 % $3; }
4997403Sobrien      |  expr '&' expr
5097403Sobrien            {  $$ = $1 & $3; }
5197403Sobrien      |  expr '|' expr
5297403Sobrien            {  $$ = $1 | $3; }
5397403Sobrien      |  '-' expr %prec UMINUS
5497403Sobrien            {  $$ = - $2; }
5597403Sobrien      |  LETTER
5697403Sobrien            {  $$ = regs[$1]; }
5797403Sobrien      |  number
5897403Sobrien      ;
5997403Sobrien
6097403Sobriennumber:  DIGIT
6197403Sobrien         {  $$ = $1; base = ($1==0) ? 8 : 10; }
6297403Sobrien      |  number DIGIT
6397403Sobrien         {  $$ = base * $1 + $2; }
6497403Sobrien      ;
6597403Sobrien
6697403Sobrien%% /* start of programs */
6797403Sobrien
6897403Sobrienint
6997403Sobrienmain (void)
7097403Sobrien{
7197403Sobrien    while(!feof(stdin)) {
7297403Sobrien	yyparse();
7397403Sobrien    }
7497403Sobrien    return 0;
7597403Sobrien}
7697403Sobrien
7797403Sobrienstatic void
7897403Sobrienyyerror(const char *s)
7997403Sobrien{
8097403Sobrien    fprintf(stderr, "%s\n", s);
8197403Sobrien}
8297403Sobrien
8397403Sobrienint
8497403Sobrienyylex(void)
8597403Sobrien{
8697403Sobrien	/* lexical analysis routine */
8797403Sobrien	/* returns LETTER for a lower case letter, yylval = 0 through 25 */
8897403Sobrien	/* return DIGIT for a digit, yylval = 0 through 9 */
8997403Sobrien	/* all other characters are returned immediately */
9097403Sobrien
9197403Sobrien    int c;
9297403Sobrien
9397403Sobrien    while( (c=getchar()) == ' ' )   { /* skip blanks */ }
9497403Sobrien
9597403Sobrien    /* c is now nonblank */
9697403Sobrien
97102782Skan    if( islower( c )) {
9897403Sobrien	yylval = c - 'a';
9997403Sobrien	return ( LETTER );
10097403Sobrien    }
10197403Sobrien    if( isdigit( c )) {
10297403Sobrien	yylval = c - '0';
10397403Sobrien	return ( DIGIT );
10497403Sobrien    }
10597403Sobrien    return( c );
10697403Sobrien}
107102782Skan