/*
 * Copyright (c) 1991, 1992, 1993 Brad Eacker,
 *              (Music, Intuition, Software, and Computers)
 * All Rights Reserved
 */

%token	L_PAREN
%token	R_PAREN
%token	AT
%token	QUEST
%token	AMPER
%token	CR

%token	PLUS
%token	MINUS

%token	MULT
%token	DIVIDE

%token	COMMA
%token	COLON
%token	BANG

%token	EQUAL
%token	NOT_EQUAL
%token	GREATER
%token	GREATER_EQUAL
%token	LESS
%token	LESS_EQUAL
%token	DOLLAR
%token	PTR
%token	PERIOD

%token	OR
%token	AND
%token	NOT

%token	STRING
%token	Identifier
%token	Constant

%token	ACCEPT
%token	ALIAS
%token	ALL
%token	APPEND
%token	ASSIST
%token	AVERAGE
%token	BLANK
%token	BOTTOM
%token	BROWSE
%token	CALL
%token	CANCEL
%token	CASE
%token	CHANGE
%token	CLEAR
%token	CLOSE
%token	CONTINUE
%token	COPY
%token	COUNT
%token	DATABASES
%token	DELETE
%token	DELIMITED
%token	DISPLAY
%token	DO
%token	EDIT
%token	EJECT
%token	ELSE
%token	ENDCASE
%token	ENDDO
%token	ENDIF
%token	ENDTEXT
%token	ERASE
%token	EXCLUSIVE
%token	EXIT
%token	EXPORT
%token	FIELDS
%token	FILE_T
%token	FIND
%token	FOR
%token	FORM
%token	FROM
%token	GET
%token	GO
%token	HELP
%token	HEADING
%token	IF
%token	INDEX
%token	INPUT
%token	INSERT
%token	JOIN
%token	LABEL
%token	LIST
%token	LOAD
%token	LOCATE
%token	LOCK
%token	LOGOUT
%token	LOOP
%token	MENU
%token	MODIFY
%token	NEXT
%token	NOEJECT
%token	NOTE
%token	OFF
%token	ON
%token	OTHERWISE
%token	PACK
%token	PARAMETERS
%token	PICTURE
%token	PLAIN
%token	PRINT
%token	PRIVATE
%token	PROMPT
%token	PROCEDURE
%token	PUBLIC
%token	QUIT
%token	RANGE
%token	READ
%token	RECALL
%token	RECORD
%token	REINDEX
%token	RELEASE
%token	RENAME
%token	REPLACE
%token	REPORT
%token	RESTORE
%token	REST
%token	RESUME
%token	RETRY
%token	RETURN
%token	RUN
%token	SAY
%token	SEEK
%token	SELECT
%token	SET
%token	SKIP
%token	SORT
%token	STORE
%token	STRUCTURE
%token	SUM
%token	SUMMARY
%token	SUSPEND
%token	TEXT
%token	TO
%token	TOP
%token	TOTAL
%token	TYPE
%token	UNLOCK
%token	UNIQUE
%token	USE
%token	VIEW
%token	WAIT
%token	WHILE
%token	WITH
%token	ZAP

%left	NOT_EQUAL LESS LESS_EQUAL GREATER GREATER_EQUAL
%left	AND OR NOT
%left	PLUS MINUS
%left	MULT DIVIDE
%left	EQUAL

%%

file
	: statements

statements
	:		/* NULL */
	| statements statement

statement
	: CR
	| set_statement CR
	| do_statement CR
	| at_statement CR
	| store_statement CR
	| clear_statement CR
	| quest_statement CR
	| go_statement CR
	| replace_statement CR
	| if_statement CR
	| use_statement CR
	| count_statement CR
	| skip_statement CR
	| index_statement CR
	| append_statement CR
	| recall_statement CR
	| delete_statement CR
	| assign_statement CR
	| proc_statement CR
	| select_statement CR
	| find_statement CR
	| copy_statement CR
	| report_statement CR
	| wait_statement CR
	| close_statement CR
	| erase_statement CR
	| simple_statement CR

set_statement
	: SET Identifier set_list
	| SET spec_ident set_list
	| SET INDEX TO ident_list
	| SET VIEW TO ident_list

set_list
	: ON
	| OFF
	| TO Identifier
	| TO spec_ident
	| TO Constant

do_statement
	: DO WHILE expression statements ENDDO
	| DO CASE cases ENDCASE
	| DO Identifier

cases
	: case
	| case cases

case
	: CR
	| CASE expression statements
	| OTHERWISE statements

at_statement
	: AT expression COMMA expression at_extras

at_extras
	: at_extra
	| at_extras at_extra

at_extra
	: SAY expression
	| SAY expression PICTURE STRING
	| GET ident_or_ref
	| GET ident_or_ref get_stuff
	| GET spec_ident
	| GET spec_ident get_stuff
	| CLEAR

get_stuff
	: PICTURE STRING
	| RANGE expression COMMA expression

store_statement
	: STORE expression TO ident_or_ref
	| STORE expression TO spec_ident

wait_statement
	: WAIT STRING
	| WAIT STRING TO ident_or_ref
	| WAIT STRING TO spec_ident

clear_statement
	: CLEAR
	| CLEAR ALL
	| CLEAR Identifier

copy_statement
	: COPY TO ident_or_ref copy_list
	| COPY TO ident_or_ref STRUCTURE
	| COPY ident_or_ref TO ident_or_ref

copy_list
	: 			/* blank is ok */
	| copy_list scope
	| copy_list FIELDS ident_list
	| copy_list FOR expression
	| copy_list WHILE expression

find_statement
	: FIND ident_or_ref

quest_statement
	: QUEST opt_list

go_statement
	: GO ident_or_ref
	| GO spec_ident
	| GO AMPER spec_ident
	| GO BOTTOM
	| GO TOP

replace_statement
	: REPLACE repl_list repl_cond
	| REPLACE scope repl_list repl_cond

repl_cond
	:			/* blank coditions ok */
	| FOR expression repl_cond
	| WHILE expression repl_cond

if_statement
	: IF expression statements ENDIF
	| IF expression statements ELSE statements ENDIF

use_statement
	: USE use_list
	| USE ident_or_ref use_list

use_list
	:			/* blank line is valid */
	| use_list INDEX ident_list
	| use_list ALIAS Identifier
	| use_list EXCLUSIVE

count_statement
	: COUNT count_list

count_list
	:
	| scope count_list
	| FOR expression count_list
	| WHILE expression count_list
	| TO Identifier

ident_list
	: ident_or_ref
	| spec_ident
	| AMPER spec_ident
	| ident_list COMMA ident_or_ref

skip_statement
	: SKIP
	| SKIP expression

index_statement
	: INDEX ON expression TO ident_or_ref
	| INDEX ON expression TO ident_or_ref UNIQUE

append_statement
	: APPEND append_list

append_list
	:		/* blank is reasonable */
	| BLANK
	| FROM Identifier from_extras

from_extras
	:		/* from not reqired */
	| FOR expression
	| TYPE DELIMITED from_type

from_type
	:		/* not required */
	| WITH STRING
	| WITH BLANK
	| Identifier

recall_statement
	: RECALL recall_extras

recall_extras
	:		/* can be blank */
	| scope recall_extras
	| FOR expression recall_extras
	| WHILE expression recall_extras

delete_statement
	: DELETE recall_extras
	| DELETE FILE_T ident_or_ref

assign_statement
	: Identifier EQUAL expression

proc_statement
	: PROCEDURE Identifier

report_statement
	: REPORT FORM Identifier rep_list
	| REPORT FORM spec_ident rep_list
	| REPORT FORM AMPER spec_ident rep_list

rep_list
	:			/* blank is ok */
	| rep_list scope
	| rep_list FOR expression
	| rep_list WHILE expression
	| rep_list NOEJECT
	| rep_list PLAIN
	| rep_list SUMMARY
	| rep_list HEADING expression
	| rep_list TO PRINT
	| rep_list TO FILE_T Identifier

simple_statement
	: CANCEL
	| EJECT
	| LOOP
	| PACK
	| READ
	| REINDEX
	| RETURN
	| SEEK expression

close_statement
	: CLOSE ALL
	| CLOSE DATABASES

erase_statement
	: ERASE file_name

file_name
	: Identifier
	| Identifier PERIOD Identifier

repl_list
	: ident_or_ref WITH expression
	| repl_list COMMA ident_or_ref WITH expression

scope
	: ALL
	| NEXT expression
	| RECORD expression
	| REST

select_statement
	: SELECT Identifier
	| SELECT Constant

spec_ident
	: BLANK
	| COUNT
	| DELETE
	| TOTAL
	| COPY
	| INDEX
	| REPORT
	| HEADING
	| PRINT
	| RECORD
	| AMPER RECORD

ident_or_ref
	: Identifier
	| AMPER Identifier
	| ident_or_ref PTR Identifier
	| ident_or_ref PERIOD Identifier

expression
	: Constant
	| ident_or_ref
	| spec_ident
	| STRING
	| STRING DOLLAR ident_or_ref
	| L_PAREN expression R_PAREN
	| Identifier L_PAREN opt_list R_PAREN
	| spec_ident L_PAREN opt_list R_PAREN
	| MINUS expression
	| PLUS expression
	| NOT expression
	| expression PLUS expression		%prec PLUS
	| expression MINUS expression		%prec PLUS
	| expression MULT expression		%prec MULT
	| expression DIVIDE expression		%prec MULT
	| expression AND expression		%prec AND
	| expression OR expression		%prec AND
	| expression EQUAL expression		%prec EQUAL
	| expression NOT_EQUAL expression	%prec NOT_EQUAL
	| expression GREATER expression		%prec NOT_EQUAL
	| expression GREATER_EQUAL expression	%prec NOT_EQUAL
	| expression LESS expression		%prec NOT_EQUAL
	| expression LESS_EQUAL expression	%prec NOT_EQUAL

opt_list
	:		/* no actual args */
	| arg_list

arg_list
	: expression
	| arg_list COMMA expression

%%

main()
{
	int	yyret;
#ifdef YYDEBUG
	extern int yydebug;

	yydebug = 1;
#endif
	yyret = yyparse();
	printf("yyparse() == %d\n", yyret);
	exit(yyret);
}
