bc.y revision b390fe2cba75806c96e503c6b93335182cd98efd
%{
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
%}
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
%{
#pragma ident "%Z%%M% %I% %E% SMI"
%}
%{
#include <stdio.h>
#include <stdarg.h>
#include <limits.h>
#include <libintl.h>
#include <locale.h>
#include <signal.h>
static void getout(int) __NORETURN;
static int *bundle(int, ...);
static void usage(void);
int cpeek(char, int, char, int, char);
void yyerror(char *);
%}
%union {
int *iptr;
char *cptr;
int cc;
}
%right '='
%left '+' '-'
%left '*' '/' '%'
%right '^'
%{
/* plus NULL */
char string[STRING_SIZE];
int crs = '0';
int bindx = 0;
int lev = 0; /* current scope level */
int ln; /* line number of current file */
int *ttp;
char *ss; /* current input source */
int bstack[10] = { 0 };
char *numb[15] = {
" 0", " 1", " 2", " 3", " 4", " 5",
" 6", " 7", " 8", " 9", " 10", " 11",
" 12", " 13", " 14"
};
int interact = 0; /* talking to a tty? */
%}
%%
start :
= {
output($2);
}
= {
output((int *)"");
}
;
;
stat : e
|
| QSTR
| LETTER '=' e
| _BREAK
| _RETURN '(' ')'
| _RETURN
| SCALE '=' e
| BASE '=' e
| OBASE '=' e
= {
$$ = $2;
}
| FFF
| error
= {
}
= {
conout($$, $2);
}
= {
conout($$, $2);
}
;
= {
$$ = "+";
}
| EQMI
= {
$$ = "-";
}
| EQMUL
= {
$$ = "*";
}
| EQDIV
= {
$$ = "/";
}
| EQREM
= {
$$ = "%%";
}
| EQEXP
= {
$$ = "^";
}
;
= {
$$ = $3;
}
;
BLEV :
= --bindx;
;
;
tail : '\n'
= {
ln++;
}
| ';'
;
= {
}
| e '<' e
| e '>' e
| e NE e
| e GE e
| e LE e
| e
;
e : e '+' e
| e '-' e
| e '*' e
| e '/' e
| e '%' e
| e '^' e
| LETTER '(' ')'
| cons
| DOT
= {
$<cptr>$ = "l.";
}
| LETTER
| LETTER '=' e
= {
geta($1));
}
| '(' e ')'
= {
$$ = $2;
}
| '?'
| '~' LETTER
| SCALE '=' e
| BASE '=' e
| OBASE '=' e
| SCALE
| BASE
| OBASE
;
;
eora : e
| LETTER '[' ']'
;
= {
*cp++ = '\0';
}
constant: '_'
= {
checkbuffer();
*cp++ = '_';
}
| DIGIT
= {
checkbuffer();
*cp++ = $1;
}
= {
checkbuffer();
*cp++ = $2;
}
;
CRS :
= {
checkbuffer();
$$ = cp;
*cp++ = '\0';
if (crs == '[')
crs += 3;
if (crs == 'a')
crs = '{';
if (crs >= 0241) {
yyerror("program too big");
getout(1);
}
}
;
= {
$$ = getf($2);
pre = (int *)"";
post = (int *)"";
lev = 1;
}
;
dargs : /* empty */
| lora
= {
pp($1);
}
= {
pp($3);
}
;
= tp($1);
= tp($3);
;
= {
$<cptr>$ = $1;
}
| LETTER '[' ']'
= {
$$ = geta($1);
}
;
%%
#define error 256
int peekc = -1;
int ifile; /* current index into sargv */
int sargc; /* size of sargv[] */
char **sargv; /* saved arg list without options */
char funtab[52] = {
01, 0, 02, 0, 03, 0, 04, 0, 05, 0, 06, 0, 07, 0,
010, 0, 011, 0, 012, 0, 013, 0, 014, 0, 015, 0, 016, 0, 017, 0,
020, 0, 021, 0, 022, 0, 023, 0, 024, 0, 025, 0, 026, 0, 027, 0,
030, 0, 031, 0, 032, 0
};
unsigned char atab[52] = {
0241, 0, 0242, 0, 0243, 0, 0244, 0, 0245, 0, 0246, 0, 0247, 0, 0250, 0,
0251, 0, 0252, 0, 0253, 0, 0254, 0, 0255, 0, 0256, 0, 0257, 0, 0260, 0,
0261, 0, 0262, 0, 0263, 0, 0264, 0, 0265, 0, 0266, 0, 0267, 0, 0270, 0,
0271, 0, 0272, 0
};
char *letr[26] = {
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
"k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
"u", "v", "w", "x", "y", "z"
};
int
yylex(void)
{
int c, ch;
c = getch();
peekc = -1;
while (c == ' ' || c == '\t')
c = getch();
if (c == '\\') {
(void) getch();
goto restart;
}
if (c <= 'z' && c >= 'a') {
/* look ahead to look for reserved words */
/* must be reserved word */
c = _IF;
goto skip;
}
c = _WHILE;
goto skip;
}
c = _FOR;
goto skip;
}
c = SQRT;
goto skip;
}
c = _RETURN;
goto skip;
}
c = _BREAK;
goto skip;
}
c = _DEFINE;
goto skip;
}
c = SCALE;
goto skip;
}
c = BASE;
goto skip;
}
c = BASE;
goto skip;
}
c = OBASE;
goto skip;
}
c = FFF;
goto skip;
}
c = _AUTO;
goto skip;
}
c = LENGTH;
goto skip;
}
getout(0);
}
/* could not be found */
return (error);
skip: /* skip over rest of word */
peekc = -1;
;
return (c);
}
/* usual case; just one single letter */
return (LETTER);
}
if (c >= '0' && c <= '9' || c >= 'A' && c <= 'F') {
return (DIGIT);
}
switch (c) {
case '.':
return (DOT);
case '=':
case '=':
c = EQ;
goto gotit;
case '+':
c = EQPL;
goto gotit;
case '-':
c = EQMI;
goto gotit;
case '*':
c = EQMUL;
goto gotit;
case '/':
c = EQDIV;
goto gotit;
case '%':
c = EQREM;
goto gotit;
case '^':
c = EQEXP;
goto gotit;
default:
return ('=');
peekc = -1;
return (c);
}
case '+':
case '-':
case '*':
case '%':
case '^':
case '<':
case '>':
case '!':
case '/':
peekc = -1;
return (EQDIV);
}
if (peekc == '*') {
peekc = -1;
;
peekc = -1;
goto restart;
}
else
return (c);
case '"':
while ((c = getch()) != '"') {
*str++ = c;
yyerror("string space exceeded");
getout(1);
}
}
*str++ = '\0';
return (QSTR);
default:
return (c);
}
}
int
{
int r;
r = yes1;
r = yes2;
else
return (none);
peekc = -1;
return (r);
}
int
getch(void)
{
int ch;
loop:
peekc = -1;
return (ch);
getout(0);
ln = 0;
goto loop;
}
ln = 0;
goto loop;
}
ln = -1;
ss = "command line";
getout(1);
/*NOTREACHED*/
}
#define b_sp_max 5000
int bdebug = 0;
static int *
bundle(int i, ...)
{
int *q;
q = b_sp_nxt;
if (bdebug)
printf("bundle %d elements at %o\n", i, q);
while (i-- > 0) {
yyerror("bundling space exceeded");
}
* b_sp_nxt++ = 0;
return (q);
}
void
routput(int *p)
{
/* part of a bundle */
while (*p != 0)
routput((int *)*p++);
}
else
printf((char *)p); /* character string */
}
void
output(int *p)
{
routput(p);
printf("\n");
}
void
conout(int *p, char *s)
{
printf("[");
routput(p);
printf("]s%s\n", s);
lev--;
}
void
yyerror(char *s)
{
ss = "teletype";
else
bindx = 0;
lev = 0;
}
void
checkbuffer(void)
{
/* Do not exceed the last char in input line buffer */
yyerror("line too long\n");
getout(1);
}
}
void
pp(int *s)
{
/* puts the relevant stuff on pre and post for the letter s */
}
void
tp(int *s)
{ /* same as pp, but for temps */
}
void
{
if (sargc == 0)
sargv[0]);
ln = -1;
ss = "command line";
getout(1);
}
ifile = 0;
ln = 0;
}
static void
{
printf("q");
}
int *
getf(char *p)
{
}
int *
geta(char *p)
{
}
int
{
int p[2];
int cflag = 0;
int lflag = 0;
int flag = 0;
char **av;
int filecounter = 0;
#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
#endif
(void) textdomain(TEXT_DOMAIN);
switch (flag) {
case 'd':
case 'c':
cflag++;
break;
case 'l':
lflag++;
break;
default:
usage();
break;
}
}
/*
* argc is the count of arguments, which should be filenames,
* remaining in argv. av is a pointer to the first of the
* remaining arguments.
*/
gettext("File argument too long\n"));
exit(2);
}
}
if (lflag) {
/*
* if the user wants to include the math library, prepend
* the math library filename to the argument list by
* overwriting the last option (there must be at least one
* supplied option if this is being done).
*/
argc++;
}
if (cflag) {
yyparse();
exit(0);
}
pipe(p);
if (fork() == 0) {
(void) close(1);
dup(p[1]);
(void) close(p[0]);
(void) close(p[1]);
yyparse();
exit(0);
}
(void) close(0);
dup(p[0]);
(void) close(p[0]);
(void) close(p[1]);
#ifdef XPG6
#else
#endif
return (1);
}
static void
usage(void)
{
"usage: bc [ -c ] [ -l ] [ file ... ]\n"));
exit(2);
}