mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-17 15:27:36 +00:00
3a92d97ff0
I'm starting with the easy cases. The leftovers need to be looked at a bit more closely. Note that this change _does_ modify the code of the old tests. This is required in order to allow the code to locate the data files in the source directory instead of the current directory, because Kyua automatically changes the latter to a temporary directory. Also note that at least one test is known to be broken here. Actually, the test is not really broken: it's marked as a TODO but unfortunately Kyua's TAP parser currently does not understand that. Will have to be fixed separately.
124 lines
2.2 KiB
Plaintext
124 lines
2.2 KiB
Plaintext
%pure-parser
|
|
|
|
%parse-param { int regs[26] }
|
|
%parse-param { int *base }
|
|
|
|
%lex-param { int *base }
|
|
|
|
%{
|
|
# include <stdio.h>
|
|
# include <ctype.h>
|
|
|
|
#ifdef YYBISON
|
|
#define YYSTYPE int
|
|
#define YYLEX_PARAM base
|
|
#define YYLEX_DECL() yylex(YYSTYPE *yylval, int *YYLEX_PARAM)
|
|
#define YYERROR_DECL() yyerror(int regs[26], int *base, const char *s)
|
|
int YYLEX_DECL();
|
|
static void YYERROR_DECL();
|
|
#endif
|
|
|
|
%}
|
|
|
|
%start list
|
|
|
|
%token DIGIT LETTER
|
|
|
|
%left '|'
|
|
%left '&'
|
|
%left '+' '-'
|
|
%left '*' '/' '%'
|
|
%left UMINUS /* supplies precedence for unary minus */
|
|
|
|
%% /* beginning of rules section */
|
|
|
|
list : /* empty */
|
|
| list stat '\n'
|
|
| list error '\n'
|
|
{ yyerrok ; }
|
|
;
|
|
|
|
stat : expr
|
|
{ printf("%d\n",$1);}
|
|
| LETTER '=' expr
|
|
{ regs[$1] = $3; }
|
|
;
|
|
|
|
expr : '(' expr ')'
|
|
{ $$ = $2; }
|
|
| expr '+' expr
|
|
{ $$ = $1 + $3; }
|
|
| expr '-' expr
|
|
{ $$ = $1 - $3; }
|
|
| expr '*' expr
|
|
{ $$ = $1 * $3; }
|
|
| expr '/' expr
|
|
{ $$ = $1 / $3; }
|
|
| expr '%' expr
|
|
{ $$ = $1 % $3; }
|
|
| expr '&' expr
|
|
{ $$ = $1 & $3; }
|
|
| expr '|' expr
|
|
{ $$ = $1 | $3; }
|
|
| '-' expr %prec UMINUS
|
|
{ $$ = - $2; }
|
|
| LETTER
|
|
{ $$ = regs[$1]; }
|
|
| number
|
|
;
|
|
|
|
number: DIGIT
|
|
{ $$ = $1; (*base) = ($1==0) ? 8 : 10; }
|
|
| number DIGIT
|
|
{ $$ = (*base) * $1 + $2; }
|
|
;
|
|
|
|
%% /* start of programs */
|
|
|
|
#ifdef YYBYACC
|
|
extern int YYLEX_DECL();
|
|
#endif
|
|
|
|
int
|
|
main (void)
|
|
{
|
|
int regs[26];
|
|
int base = 10;
|
|
|
|
while(!feof(stdin)) {
|
|
yyparse(regs, &base);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
YYERROR_DECL()
|
|
{
|
|
fprintf(stderr, "%s\n", s);
|
|
}
|
|
|
|
int
|
|
YYLEX_DECL()
|
|
{
|
|
/* lexical analysis routine */
|
|
/* returns LETTER for a lower case letter, yylval = 0 through 25 */
|
|
/* return DIGIT for a digit, yylval = 0 through 9 */
|
|
/* all other characters are returned immediately */
|
|
|
|
int c;
|
|
|
|
while( (c=getchar()) == ' ' ) { /* skip blanks */ }
|
|
|
|
/* c is now nonblank */
|
|
|
|
if( islower( c )) {
|
|
*yylval = (c - 'a');
|
|
return ( LETTER );
|
|
}
|
|
if( isdigit( c )) {
|
|
*yylval = (c - '0') % (*base);
|
|
return ( DIGIT );
|
|
}
|
|
return( c );
|
|
}
|