yacc.c revision 1591
155714Skris/*
255714Skris * Copyright (c) 1987, 1993, 1994
355714Skris *	The Regents of the University of California.  All rights reserved.
455714Skris *
555714Skris * Redistribution and use in source and binary forms, with or without
655714Skris * modification, are permitted provided that the following conditions
755714Skris * are met:
868651Skris * 1. Redistributions of source code must retain the above copyright
968651Skris *    notice, this list of conditions and the following disclaimer.
1068651Skris * 2. Redistributions in binary form must reproduce the above copyright
1168651Skris *    notice, this list of conditions and the following disclaimer in the
1276866Skris *    documentation and/or other materials provided with the distribution.
1355714Skris * 3. All advertising materials mentioning features or use of this software
1455714Skris *    must display the following acknowledgement:
1568651Skris *	This product includes software developed by the University of
1668651Skris *	California, Berkeley and its contributors.
1768651Skris * 4. Neither the name of the University nor the names of its contributors
18109998Smarkm *    may be used to endorse or promote products derived from this software
19109998Smarkm *    without specific prior written permission.
20109998Smarkm *
21109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22109998Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3155714Skris * SUCH DAMAGE.
3255714Skris */
3355714Skris
3455714Skris#ifndef lint
3555714Skrisstatic char sccsid[] = "@(#)yacc.c	8.3 (Berkeley) 4/2/94";
3655714Skris#endif /* not lint */
3755714Skris
3855714Skris#include <ctype.h>
3955714Skris#include <limits.h>
4055714Skris#include <stdio.h>
4155714Skris#include <string.h>
4255714Skris
4355714Skris#include "ctags.h"
4455714Skris
4555714Skris/*
4655714Skris * y_entries:
4755714Skris *	find the yacc tags and put them in.
4855714Skris */
4955714Skrisvoid
5055714Skrisy_entries()
5155714Skris{
5255714Skris	int	c;
5355714Skris	char	*sp;
5455714Skris	bool	in_rule;
5555714Skris	char	tok[MAXTOKEN];
5655714Skris
5755714Skris	in_rule = NO;
5855714Skris
5955714Skris	while (GETC(!=, EOF))
6055714Skris		switch (c) {
6155714Skris		case '\n':
6255714Skris			SETLINE;
6355714Skris			/* FALLTHROUGH */
6476866Skris		case ' ':
6555714Skris		case '\f':
6676866Skris		case '\r':
67109998Smarkm		case '\t':
68109998Smarkm			break;
6955714Skris		case '{':
7055714Skris			if (skip_key('}'))
7159191Skris				in_rule = NO;
7268651Skris			break;
73109998Smarkm		case '\'':
7455714Skris		case '"':
75111147Snectar			if (skip_key(c))
76111147Snectar				in_rule = NO;
77111147Snectar			break;
78111147Snectar		case '%':
79111147Snectar			if (GETC(==, '%'))
80111147Snectar				return;
81111147Snectar			(void)ungetc(c, inf);
82111147Snectar			break;
8355714Skris		case '/':
8455714Skris			if (GETC(==, '*'))
8555714Skris				skip_comment();
8655714Skris			else
8755714Skris				(void)ungetc(c, inf);
8855714Skris			break;
8955714Skris		case '|':
9055714Skris		case ';':
9155714Skris			in_rule = NO;
9255714Skris			break;
9355714Skris		default:
9455714Skris			if (in_rule || !isalpha(c) && c != '.' && c != '_')
9555714Skris				break;
9655714Skris			sp = tok;
9755714Skris			*sp++ = c;
9855714Skris			while (GETC(!=, EOF) && (intoken(c) || c == '.'))
9955714Skris				*sp++ = c;
10055714Skris			*sp = EOS;
10155714Skris			getline();		/* may change before ':' */
10255714Skris			while (iswhite(c)) {
10355714Skris				if (c == '\n')
10455714Skris					SETLINE;
10555714Skris				if (GETC(==, EOF))
10655714Skris					return;
10755714Skris			}
10855714Skris			if (c == ':') {
10955714Skris				pfnote(tok, lineno);
11055714Skris				in_rule = YES;
11155714Skris			}
11255714Skris			else
11355714Skris				(void)ungetc(c, inf);
11455714Skris		}
11555714Skris}
11655714Skris
11755714Skris/*
11855714Skris * toss_yysec --
11955714Skris *	throw away lines up to the next "\n%%\n"
12055714Skris */
12155714Skrisvoid
12255714Skristoss_yysec()
12355714Skris{
12455714Skris	int	c;			/* read character */
12555714Skris	int	state;
12655714Skris
12755714Skris	/*
12855714Skris	 * state == 0 : waiting
12955714Skris	 * state == 1 : received a newline
13055714Skris	 * state == 2 : received first %
13155714Skris	 * state == 3 : recieved second %
13255714Skris	 */
13355714Skris	lineftell = ftell(inf);
13455714Skris	for (state = 0; GETC(!=, EOF);)
13555714Skris		switch (c) {
13655714Skris		case '\n':
13755714Skris			++lineno;
13855714Skris			lineftell = ftell(inf);
13955714Skris			if (state == 3)		/* done! */
14055714Skris				return;
14155714Skris			state = 1;		/* start over */
14255714Skris			break;
14355714Skris		case '%':
14455714Skris			if (state)		/* if 1 or 2 */
14555714Skris				++state;	/* goto 3 */
14655714Skris			break;
14755714Skris		default:
14855714Skris			state = 0;		/* reset */
14955714Skris			break;
15055714Skris		}
15155714Skris}
15255714Skris