[comp.unix.questions] Any YACC / BISON gurus out there?

richard@ssf.uucp (Richard Thombs) (10/24/89)

Hi, I'm trying to write a YACC grammar to parse an adventure game description
database and I need YOUR help!

I need to be able to get YACC (or BISON if need be) to fail a parse when an
action tells it to. As an example, character level names are described using
a format like this:-

...
male	levelname1
	levelname2
	levelname3
female	levelname1
	levelname2
	levelname3
...

I use a symbol table entry that allows the symbol to be defined as a reserved
word (in this case 'male' and 'female') and / or many other things including
actions, object names etc. The lexical analyser returns all names as being of
type SYMBOL, and the grammar does the deciding on what really constitutes a
valid symbol at the point of parsing. In this case, a level name can be any
symbol so long as its not the reserved words 'male' or 'female' which are
identified by having a reserved word class of 'SEX'.

The grammar I came up with is this one:-

level_name_decl_list	:	level_name_decl_list
				level_name_decl
			|	level_name_decl
			;

level_name_decl	:	sex
			level_name_list
		;

sex	:	SYMBOL
{
	if ($1->reserved != 1 || $1->reserved_data->class != SEX) YYERROR;
}

level_name_list	:	level_name_list
			level_name
		|	level_name
		;

level_name	:	SYMBOL
{
	if ($1->reserved == 1 && $1->reserved_data->class == SEX) YYERROR;
}

And my trouble is that the YYERROR directives don't do what I hoped they'd do,
which is fail the current non-terminal as being unparsable and trying further
rules, indstead it just fails the non-terminal and generates a syntax error.

What I need to be able to encapsulate in a non-terminal is an action that will
only allow the non-terminal to be parsed if I want it to be. I thought there
would be a YYREJECT or similar, but I can't find any mention of it in the
documentation or sources.

So, if you know of any ways to do this, then let me know either by mail or
news.

		Thanks in advance,

				Richard Thombs
-- 
Post:  System Software Factors, Chiltern Chambers, Caversham, Reading, England.
Mail:  richard@ssf.{co.uk,uucp}
Phone: +44 734 476644

johnl@esegue.segue.boston.ma.us (John R. Levine) (10/26/89)

In article <1341@ssf> richard@ssf.uucp (Richard Thombs) writes:
>I need to be able to get YACC (or BISON if need be) to fail a parse when an
>action tells it to ... [and parse the token as something else].

Yacc doesn't work that way.  For any grammar that yacc can parse, there is
at most one thing that yacc can do with any token in any state.  If you want
to have context-sensitive parsing, you need to have the parser pass info
back to the lexer to give it hints about what kind of token to look for next.

I wrote a Fortran-77 subset parser a while ago that I have been giving away,
that does a lot of context-sensitive parsing hackery.  Feel free to ask.
-- 
John R. Levine, Segue Software, POB 349, Cambridge MA 02238, +1 617 864 9650
johnl@esegue.segue.boston.ma.us, {ima|lotus|spdcc}!esegue!johnl
Massachusetts has over 100,000 unlicensed drivers.  -The Globe

ndjc@capone.UUCP (Nick Crossley) (10/27/89)

In article <1341@ssf> richard@ssf.uucp (Richard Thombs) writes:
>I need to be able to get YACC (or BISON if need be) to fail a parse when an
>action tells it to.

Some versions of yacc have a YYBACKUP macro in the parser skeleton.
This allows limited backup, possibly not as much as you want.  I have
found it most useful to reduce the number of 'reserved words' in a
grammar:

rule	:	identifier	{ YYBACKUP(special($1)); }
	|	token1		{ ... }
	|	token2		{ ... }
	...
	;

The lexer never returns 'token1', etc.  The function 'special'
examines the identifier and returns token1, etc., as appropriate.
So token1, etc., are only recognised as keywords in the correct context;
elsewhere, they are just identifiers.
-- 

<<< standard disclaimers >>>
Nick Crossley, ICL NA, 9801 Muirlands, Irvine, CA 92718-2521, USA 714-458-7282
uunet!ccicpg!ndjc  /  ndjc@ccicpg.UUCP