Esempio n. 1
0
/*
**  OPERATOR -- process a token starting with an operator
**
**	Processes operators, strings, comments, and 
**	floating constants without a leading 0.
**
**	Parameters:
**		chr - first character of token {equel_cmap (chr) == OPATR}
**
**	Returns:
**		NUMBER or STRING token, or operator token.
**		CONTINUE on error.
**
**	Side Effects:
**		Adds a node to the Symbol space, and returns adress
**		in "yylval".
**		Opcode is set to the opcode of the operator.
**		May backup a character.
*/
int
operator(char chr)
{
	register struct optab	*op;
	char			opbuf [3];

	opbuf [0] = chr;
	opbuf [1] = getch();
	opbuf [2] = '\0';

	if (opbuf [0] == '.' && equel_cmap(opbuf[1]) == NUMBR) {
		/* floating mantissa w/o leading 0 */
		backup(opbuf [1]);
		return (number(opbuf [0]));
	}
	if (equel_cmap(opbuf[1]) != OPATR) {
		backup(opbuf [1]);
		opbuf [1] = '\0';
	}
	/* operator has been reduced to its smallest 
	 * possible length, now try to find it in the
	 * operator table [tokens.y]
	 */
	for ( ; ; ) {
		for (op = Optab; op->op_term; op++)
			if (strcmp(op->op_term, opbuf) == 0)
				break;
		if (!op->op_term && opbuf [1]) {
			/* reduce a 2 char operator to 1 char,
			 * and re-search
			 */
			backup(opbuf[1]);
			opbuf [1] = '\0';
			continue;
		}
		break;
	}
	if (op->op_term) {
		/* string quotes ? */
		if (op->op_token == Tokens.sp_quote)
			return (string(op));

		/* comment indicator ? */
		if (op->op_token == Tokens.sp_bgncmnt)
			return (comment());

		/* {strcmp(opbuf, op->op_term) == 0} */
		Opcode = op->op_code;
		yylval.u_dn = addsym(op->op_term);
		return (op->op_token);
	}
	yysemerr("bad operator", opbuf);

	/* operator not found, skip token and try again */
	return (CONTINUE);
}
Esempio n. 2
0
/*
**  COMMENT.C -- routine to scan comments inside an EQL statement
**
**	Uses the endcmnt token code to find the endcmnt
**	terminal string, then reads the input until it sees this
**	terminal (must be <= 2 characters), returning EOF_TOK and
**	giving an error diagnostic if end-of-file is encountered.
**
**	Returns:
**		CONTINUE -- valid comment
**		EOF_TOK -- EOF in comment
**
**	Side Effects:
**		deletes comments from within an EQL statement
**
*/
comment()
{
	register int		i;
	register int		l;
	register struct optab	*op;
	char			buf[3];

	/* find end of comment operator */
	for (op = Optab; op->op_term; op++)
		if (op->op_token == Tokens.sp_endcmnt)
			break;

	if (!op->op_term)
		AAsyserr(13000);
	/* scan for the end of comment */
	l = AAlength(op->op_term);
	if (l > sizeof buf - 1)
		AAsyserr(13001, l, op->op_term, sizeof buf -1);

	/* fill buffer to length of endmnt terminal */
	for (i = 0; i < l; i++)
	{
		if ((buf[i] = getch()) == EOF_TOK)
		{
nontermcom :
			/* non-terminated comment */
			yysemerr("premature EOF encountered in comment", (char *) 0);
			return (EOF_TOK);
		}
	}

	/* shift on input until endcmnt */
	while (!AAbequal(buf, op->op_term, l))
	{
		for (i = 0; i < l - 1; i++)
			buf[i] = buf[i + 1];
		if ((buf[l - 1] = getch()) == EOF_TOK)
			goto nontermcom;
	}
	return (CONTINUE);
}