diff options
author | Baptiste Daroussin <bapt@FreeBSD.org> | 2024-06-20 11:48:44 +0000 |
---|---|---|
committer | Baptiste Daroussin <bapt@FreeBSD.org> | 2024-06-20 11:48:44 +0000 |
commit | 85a764b2c52b853993b20c6291983a1aac223f47 (patch) | |
tree | 1bdadbfcfab1670a3e7f0d95591305d721d0480c /test/calc3.y | |
parent | 0b234d7a89df4780e9d2ea9817afd5d3dfaf4d27 (diff) |
byacc: readd tests in the importvendor/byacc
Diffstat (limited to 'test/calc3.y')
-rw-r--r-- | test/calc3.y | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/test/calc3.y b/test/calc3.y new file mode 100644 index 000000000000..2c9148e80102 --- /dev/null +++ b/test/calc3.y @@ -0,0 +1,127 @@ +%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; +} + +#define UNUSED(x) ((void)(x)) + +static void +YYERROR_DECL() +{ + UNUSED(regs); /* %parse-param regs is not actually used here */ + UNUSED(base); /* %parse-param base is not actually used here */ + 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 ); +} |