home services resume portfolio contact us about me


Return To Portfolio Home


%{
/*
 * Copyright (c) 1998
 */
#ifndef lint
static char rcsid[] = "@(#)$Id$";
static char copyright[] = "Copyright (c) 1998";
#endif

/***********************************************************************
 * OpenROAD GRAMMAR
 */
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#include <string.h>
#include <assert.h>

#include "api.h"
#include "private.h"

#define YYSTYPE		union yystack

%}

/* types of the non-terminals */
%type <str>		com
%type <expr>		expr factor opt_expr
%type <variable>	variable opt_return
%type <builtin>		builtin
%type <arglist>		opt_arglist arg_list callproc_parms
%type <dotted>		dotted_var var
%type <array_expr>	array_expr
%type <args>		args
%type <str>		semicomma ',' ';'
%type <block>		stmt_block opt_block
%type <stmtlist>	stmtlist
%type <stmt>		stmt
%type <stmt>		s_assign s_call s_callsystem s_callframe s_callproc s_close s_commit
%type <stmt>		s_continue s_delete s_endloop s_execimm s_execproc s_exit s_fetch
%type <stmt>		s_for s_gotoframe s_ifthen s_inquiresql s_insert s_message s_open
%type <stmt>		s_openframe s_prompt s_resume s_return s_rollback s_select s_set
%type <stmt>		s_update s_while
%type <elseif_list>	elseif_part elseif_list elseif
%type <stmtlist>	else_part
%type <str>		opt_label opt_labelref
%type <val>		for_direction opt_work opt_repeated update_mode opt_next
%type <callparmlist>	callparmlist callparm
%type <callparm>	callparms
%type <framename>	frame_name
%type <optlist>		optlist attr
%type <str>		savepoint opt_corrname cursor
%type <decl>		initialize procedure on decl decl_list
%type <declarex>	declare locals local_list local
%type <parms>		parms parmlist parm
%type <onlist>		on_list on_clause
%type <variable>	column_name opt_fieldname
%type <str>		event
%type <nulldef>		nulldef_spec defspec
%type <datatype>	datatype basic_type type
%type <val>		'(' ')' '='
%type <varcol>		varcol_list varcol
%type <val>		sortorder selmode 
%type <expr>		sql_expr search_expr having_clause where_clause
%type <delete>		sql_delete
%type <insert>		sql_insert
%type <select>		sql_select
%type <update>		sql_update
%type <updateclause>	update_clause
%type <columnlist>	column_list columns update_of group_clause
%type <cursorlist>	cursor_list
%type <varlist>		varlist
%type <tablename>	tablename
%type <setclause>	set_clause set_expr
%type <fromlist>	from_list from_item from_clause
%type <orderspec>	orderspec order_list order_clause
%type <sqlexplist>	sql_explist
%type <subselect>	subselect select_union

/* Definition of returned tokens from the lexical analyzer */
%token <val> ARRAY
%token <val> DOWNTO
%token <val> READONLY
%token <val> DEFERRED
%token <val> RETURNING
%token <val> ALL
%token <val> ALTER
%token <val> AND
%token <val> ANY
%token <val> AS
%token <val> ASC
%token <val> AT
%token <val> BEGIN
%token <val> BETWEEN
%token <val> BY
%token <val> BYREF
%token <val> CALL
%token <val> CALLFRAME
%token <val> CALLPROC
%token <val> CLOSE
%token <val> COMMIT
%token <val> CONTINUE
%token <val> COPY
%token <val> COUNT
%token <val> CURRENT
%token <val> DECLARE
%token <val> DEFAULT
%token <val> DELETE
%token <val> DESC
%token <val> DIRECT
%token <val> DISTINCT
%token <val> DO
%token <val> ELSE
%token <val> ELSEIF
%token <val> END
%token <val> ENDDECLARE
%token <val> ENDFOR
%token <val> ENDIF
%token <val> ENDLOOP
%token <val> ENDWHILE
%token <val> ESCAPE
%token <val> EXECUTE
%token <val> EXIT
%token <val> FETCH
%token <val> FOR
%token <val> FROM
%token <val> GOTOFRAME
%token <val> GROUP
%token <val> HAVING
%token <val> IF
%token <val> IMMEDIATE
%token <val> IN
%token <val> INITIALIZE
%token <val> INQUIRE_INGRES
%token <val> INQUIRE_SQL
%token <val> INSERT
%token <val> INTO
%token <val> IS
%token <val> LIKE
%token <val> MESSAGE
%token <val> NEXT
%token <val> NOT
%token <val> KW_NULL
%token <val> OF
%token <val> ON
%token <val> OPEN
%token <val> OPENFRAME
%token <val> OR
%token <val> ORDER
%token <val> PROCEDURE
%token <val> PROMPT
%token <val> REPEATED
%token <val> RESUME
%token <val> RETURN
%token <val> ROLLBACK
%token <val> SELECT
%token <val> SET
%token <val> SYSTEM
%token <val> THEN
%token <val> TO
%token <val> UNION
%token <val> UPDATE
%token <val> VALUES
%token <val> WHERE
%token <val> WHILE
%token <val> WITH
%token <val> WORK

/*
 * Tokens representing operators in expressions
 */

%token LE		/* <= */
%token GE		/* >= */
%token NE		/* <> */
%token EXP		/* * */

/*
 * Tokens representing literals
 */
%token	<str>	INTEGER
%token	<str>	FLOAT
%token	<str>	STRING

/*
 * Tokens representing symbols or identifiers
 */
%token	<str>	IDENT

/*
 * Operators precedence
 */
%left AS
%left OR
%left BETWEEN
%left AND
%left IS IN
%left LIKE
%left ESCAPE
%left '=' NE '<' LE '>' GE
%left '+' '-'
%left '*' '/' '%'
%left EXP
%nonassoc NOT
%nonassoc UNIMINUS

/*
 * Union operator precedence
 */
%left UNION ALL

%start program

%%
program		: decl_list				{ G.program = $1; }
		;

decl_list	: decl					{ $$ = $1; }
		| decl_list decl			{ $$ = decl_add($1, $2); }
		;

decl		: initialize opt_semi			{ $$ = $1; }
		| procedure opt_semi			{ $$ = $1; }
		| on opt_semi				{ $$ = $1; }
		;

com		: /* empty */				{ $$ = CommentGet(); }
		;

initialize	: INITIALIZE com parms '=' declare stmt_block
							{ $$ = decl_initialize($1, $2, $3, $5, $6);  }
		;

procedure	: PROCEDURE com IDENT parms '=' declare stmt_block
							{ $$ = decl_procedure($1, $2, $3, $4, $6, $7); }
		;

on		: on_list '=' com stmt_block		{ $$ = decl_on($2, $3, $1, $4); }
		;

/* ------ on_list -------- */
on_list		: on_clause				{ $$ = $1; }
		| on_list ',' on_clause			{ $$ = onlist_add($1, $3); }
		;

on_clause	: ON event opt_fieldname		{ $$ = onlist($2, $3, NULL); }
		| ON event STRING			{ $$ = onlist($2, NULL, $3); }
		;

opt_fieldname	: variable				{ $$ = $1; }
		| /* empty */				{ $$ = NULL; }
		;

event		: IDENT					{ $$ = $1; }
		| EXIT					{ $$ = NULL; }
		;

/* ------ parms ------ */
parms		: '(' parmlist opt_semicomma ')'	{ $$ = $2; }
		| '('   ')'				{ $$ = NULL; }
		| /* empty */				{ $$ = NULL; }
		;

parmlist	: parm					{ $$ = $1; }
		| parmlist semicomma parm		{ $$ = parms_add($1, $3); }
		;

parm		: IDENT '=' type			{ $$ = parms($1, $3); }
		;

/* ----- declare ----- */
declare		: DECLARE locals enddeclare	{ $$ = $2; CommentReset(); }
		| /* empty */			{ $$ = NULL; CommentReset(); }
		;

enddeclare	: ENDDECLARE
		| /* empty */
		;

/* ----- locals ----- */
locals		: local_list opt_semicomma		{ $$ = $1; }
		| /* empty */				{ $$ = NULL; }
		;

local_list	: local					{ $$ = $1; }
		| local_list semicomma local		{ $$ = declarex_add($1, $3); }
		;

local		: IDENT com '=' PROCEDURE			{ $$ = declarex($2, $1, DX_PROC, NULL); }
		| IDENT com '=' PROCEDURE RETURNING type	{ $$ = declarex($2, $1, DX_PROCRET, $6); }
		| IDENT com '=' type				{ $$ = declarex($2, $1, DX_VAR, $4); }
		;

/* ------------- statements ------------------------------------------------- */
stmt		: s_assign			{ $$ = $1; }
		| s_call			{ $$ = $1; }
		| s_callsystem			{ $$ = $1; }
		| s_callframe			{ $$ = $1; }
		| s_callproc			{ $$ = $1; }
		| s_close			{ $$ = $1; }
		| s_commit			{ $$ = $1; }
		| s_continue			{ $$ = $1; }
		| s_delete			{ $$ = $1; }
		| s_endloop			{ $$ = $1; }
		| s_execimm			{ $$ = $1; }
		| s_execproc			{ $$ = $1; }
		| s_exit			{ $$ = $1; }
		| s_fetch			{ $$ = $1; }
		| s_for				{ $$ = $1; }
		| s_gotoframe			{ $$ = $1; }
		| s_ifthen			{ $$ = $1; }
		| s_inquiresql			{ $$ = $1; }
		| s_insert			{ $$ = $1; }
		| s_message			{ $$ = $1; }
		| s_open			{ $$ = $1; }
		| s_openframe			{ $$ = $1; }
		| s_prompt			{ $$ = $1; }
		| s_resume			{ $$ = $1; }
		| s_return			{ $$ = $1; }
		| s_rollback			{ $$ = $1; }
		| s_select			{ $$ = $1; }
		| s_set				{ $$ = $1; }
		| s_update			{ $$ = $1; }
		| s_while			{ $$ = $1; }
		| /* empty */			{ $$ = mk_empty(); }
		;

/* ----- sytactic sugar ----- */

semicomma	: ','			{ $$ = $1; }
		| ';'			{ $$ = $1; }
		;

opt_semicomma	: semicomma
		| /* empty */
		;

opt_semi	: ';'
		| /* empty */
		;

/* ----- type ----- */
type		: basic_type			{ $$ = $1; }
		| ARRAY OF basic_type		{ $$ = datatype_arrayof($3); }
		;

basic_type	: datatype nulldef_spec		{ $$ = datatype_nulldef($1, $2); }
		;

datatype	: IDENT				{ $$ = datatype($1, NULL); }
		| IDENT '(' INTEGER ')'		{ $$ = datatype($1, $3); }


nulldef_spec	: WITH KW_NULL defspec		{ $$ = nulldef_merge(WITH_NULL, $3); }
		| NOT KW_NULL defspec		{ $$ = nulldef_merge(NOT_NULL, $3); }
		| NOT DEFAULT			{ $$ = nulldef(EMPTY_NULL, NOT_DEFAULT, NULL); }
		| WITH DEFAULT opt_expr		{ $$ = nulldef(EMPTY_NULL, WITH_DEFAULT, $3); }
		| DEFAULT expr			{ $$ = nulldef(EMPTY_NULL, USE_DEFAULT, $2); }
		| /* empty */			{ $$ = nulldef(EMPTY_NULL, EMPTY_DEFAULT, NULL); }
		;

defspec		: NOT DEFAULT			{ $$ = nulldef(EMPTY_NULL, NOT_DEFAULT, NULL); }
		| WITH DEFAULT opt_expr		{ $$ = nulldef(EMPTY_NULL, WITH_DEFAULT, $3); }
		| DEFAULT opt_expr		{ $$ = nulldef(EMPTY_NULL, USE_DEFAULT, $2); }
		| /* empty */			{ $$ = nulldef(EMPTY_NULL, EMPTY_DEFAULT, NULL); }
		;

/* ------ callproc_parms ----- */
callproc_parms	: opt_arglist				{ $$ = $1; }
		| /* empty */				{ $$ = arglist_empty(0); }
		;

/* ------ callparms ----- */

callparms	: '(' callparmlist ')'			{ $$ = callparm(1, $2); }
		| '('   ')'				{ $$ = callparm(1, NULL); }
		| /* empty */				{ $$ = callparm(0, NULL); }
		;

callparmlist	: callparm				{ $$ = $1; }
		| callparmlist ',' callparm		{ $$ = callparmlist_add($1, $3); }
		;

callparm	: IDENT '=' expr			{ $$ = callparmlist($1, $3, NULL); }
		| BYREF '(' variable ')'		{ $$ = callparmlist(NULL, NULL, $3); }
		;

/***********************************************************************
 *			EXPRESSIONS
 ***********************************************************************
 */
expr		: expr '+' expr					{ $$ = expr2(C_ADD, $1, $3); }
		| expr '-' expr					{ $$ = expr2(C_SUB, $1, $3); }

		| '-' expr			%prec UNIMINUS
								{ $$ = expr1(C_NEG, $2); }

		| expr '*' expr					{ $$ = expr2(C_MUL, $1, $3); }
		| expr '/' expr					{ $$ = expr2(C_DIV, $1, $3); }
		| expr EXP expr					{ $$ = expr2(C_EXP, $1, $3); }

		| NOT expr					{ $$ = expr1(C_NOT, $2); }
		| expr AND expr					{ $$ = expr2(C_AND, $1, $3); }
		| expr OR expr					{ $$ = expr2(C_OR, $1, $3); }

		| expr '=' expr					{ $$ = expr2(C_EQ, $1, $3); }
		| expr NE expr					{ $$ = expr2(C_NE, $1, $3); }
		| expr '<' expr					{ $$ = expr2(C_LT, $1, $3); }
		| expr LE expr					{ $$ = expr2(C_LE, $1, $3); }
		| expr '>' expr					{ $$ = expr2(C_GT, $1, $3); }
		| expr GE expr					{ $$ = expr2(C_GE, $1, $3); }

		| expr IS KW_NULL		%prec IS	{ $$ = expr2(C_ISNULL, $1, NULL); }
		| expr IS NOT KW_NULL		%prec IS	{ $$ = expr2(C_ISNNULL, $1, NULL); }

		| expr LIKE expr		%prec LIKE	{ $$ = expr_like(C_LIKE, $1, $3, NULL); }
		| expr NOT LIKE expr		%prec LIKE	{ $$ = expr_like(C_NLIKE, $1, $4, NULL); }

		| expr LIKE expr ESCAPE STRING			%prec ESCAPE
								{ $$ = expr_like(C_LIKE, $1, $3, $5); }

		| expr NOT LIKE expr ESCAPE STRING		%prec ESCAPE
								{ $$ = expr_like(C_NLIKE, $1, $4, $6); }

		| expr IN arg_list		%prec IN	{ $$ = expr_in(C_IN, $1, $3); }
		| expr NOT IN arg_list		%prec IN	{ $$ = expr_in(C_NIN, $1, $4); }

		| expr BETWEEN expr				{ $$ = expr2(C_BETWEEN, $1, $3); }
		| expr NOT BETWEEN expr				{ $$ = expr2(C_NBETWEEN, $1, $4); }

		| expr AS IDENT					{ $$ = expr_as($1, $3); }

		| factor					{ $$ = $1; }
		;

factor		: '(' expr ')'					{ $$ = exprE(C_PAREN, $2); }
		| variable					{ $$ = exprV(C_VARIABLE, $1); }
		| builtin					{ $$ = exprB(C_BUILTIN, $1); }
		| INTEGER					{ $$ = exprS(C_INTEGER, $1); }
		| FLOAT						{ $$ = exprS(C_FLOAT, $1); }
		| STRING					{ $$ = exprS(C_STRING, $1); }
		| KW_NULL					{ $$ = exprS(C_NULL, "NULL"); }
		;

/* ------ variable ------ */

variable	: dotted_var			{ $$ = variable(0, $1); }
		| ':' dotted_var		{ $$ = variable(1, $2); }
		;

dotted_var	: var				{ $$ = $1; }
		| dotted_var '.' var		{ $$ = dotted_add($1, $3); }
		;

var		: IDENT				{ $$ = dotted(C_SVAR, $1, NULL, NULL); }
		| IDENT '[' array_expr ']'	{ $$ = dotted(C_AVAR, $1, $3, NULL); }
		| IDENT opt_arglist		{ $$ = dotted(C_PVAR, $1, NULL, $2); }
		;

array_expr	: expr				{ $$ = array_expr(0, $1); }
		| '*'				{ $$ = array_expr(1, NULL); }
		| /* empty */			{ $$ = array_expr(0, NULL); }
		;

/* ------ arg_list opt_arglist ----- */

opt_arglist	: arg_list				{ $$ = $1; }
		| '('   ')'				{ $$ = arglist_empty($1); }
		;

arg_list	: '(' args ')'				{ $$ = arglist($1, $2); }
		;

args		: expr					{ $$ = args($1); }
		| args semicomma expr			{ $$ = args_add($1, $2, args($3)); }
		;

/* ----- builtin ----- */

builtin		: BYREF arg_list			{ $$ = builtin_byref($2); }
		| COUNT '(' expr ')'			{ $$ = builtin_count(0, $3); }
		| COUNT '(' DISTINCT expr ')'		{ $$ = builtin_count(1, $4); }
		| COUNT '(' '*' ')'			{ $$ = builtin_count(0, NULL); }
		;

/***********************************************************************
 *		STATEMENTS
 ***********************************************************************
 */
s_assign	: variable '=' com expr			{ $$ = mk_assign($3, $1, $4); }
		| variable com				{ $$ = mk_assign($2, $1, NULL); }
		;

s_call		: opt_return CALL com IDENT callparms	{ $$ = mk_call($2, $3, $1, $4, $5); }
		;

s_callsystem	: opt_return CALL com SYSTEM expr	{ $$ = mk_callsystem($2, $3, $1, $5); }
		;

s_callframe	: opt_return CALLFRAME com frame_name callparms WITH optlist
							{ $$ = mk_callframe($2, $3, $1, $4, $5, $7); }
		| opt_return CALLFRAME com frame_name callparms
							{ $$ = mk_callframe($2, $3, $1, $4, $5, NULL); }
		;

s_callproc	: opt_return CALLPROC com IDENT callproc_parms
							{ $$ = mk_callproc($2, $3, $1, $4, $5); }
		;

s_close		: CLOSE com expr			{ $$ = mk_close($1, $2, $3); }
		;

s_commit	: COMMIT com opt_work			{ $$ = mk_commit($1, $2, $3); }
		;

opt_work	: WORK					{ $$ = 1; }
		| /* empty */				{ $$ = 0; }
		;

s_continue	: CONTINUE com opt_labelref		{ $$ = mk_continue($1, $2, $3); }
		;

s_delete	: opt_repeated sql_delete		{ $$ = mk_delete($1, $2); }
		;

s_endloop	: ENDLOOP com opt_labelref		{ $$ = mk_endloop($1, $2, $3); }
		;

s_execimm	: opt_return EXECUTE com IMMEDIATE expr INTO varlist opt_block
							{ $$ = mk_execimm($2, $3, $1, $5, $7, $8); }
		| opt_return EXECUTE com IMMEDIATE expr opt_block
							{ $$ = mk_execimm($2, $3, $1, $5, NULL, $6); }
		;

s_execproc	: opt_return EXECUTE com PROCEDURE IDENT callparms
							{ $$ = mk_execproc($2, $3, $1, $5, $6, NULL); }
		| opt_return EXECUTE com PROCEDURE IDENT callparms INTO cursor_list
							{ $$ = mk_execproc($2, $3, $1, $5, $6, $8); }
		;

s_exit		: EXIT com				{ $$ = mk_exit($1, $2); }
		;

s_fetch		: FETCH com cursor INTO varcol_list	{ $$ = mk_fetch($1, $2, $3, $5); }
		;

varcol_list	: varcol				{ $$ = $1; }
		| varcol_list ',' varcol		{ $$ = varcol_add($1, $3); }
		;

varcol		: variable				{ $$ = varcol($1, NULL); }
		| variable '=' column_name		{ $$ = varcol($1, $3); }
		;

s_for		: opt_label FOR com variable '=' expr for_direction expr DO stmtlist ENDFOR
							{ $$ = mk_for($2, $3, $1, $4, $6, $7, $8, $10); }
		;

for_direction	: TO					{ $$ = TO; }
		| DOWNTO				{ $$ = DOWNTO; }
		;

s_gotoframe	: GOTOFRAME com frame_name callparms WITH optlist
							{ $$ = mk_gotoframe($1, $2, $3, $4, $6); }
		| GOTOFRAME com frame_name callparms
							{ $$ = mk_gotoframe($1, $2, $3, $4, NULL); }
		;

s_ifthen	: IF com expr THEN stmtlist elseif_part else_part ENDIF
							{ $$ = mk_ifthen($1, $2, $3, $5, $6, $7); }
		;

elseif_part	: elseif_list				{ $$ = $1; }
		| /* empty */				{ $$ = NULL; }
		;

elseif_list	: elseif				{ $$ = $1; }
		| elseif_list elseif			{ $$ = elseif_add($1, $2); }
		;

elseif		: ELSEIF expr THEN stmtlist		{ $$ = mk_elseif($2, $4); }
		;

else_part	: ELSE stmtlist				{ $$ = $2; }
		| /* empty */				{ $$ = NULL; }
		;

s_inquiresql	: INQUIRE_SQL com callproc_parms	{ $$ = mk_inquiresql($1, $2, $3); }
		;

s_insert	: opt_repeated sql_insert		{ $$ = mk_insert($1, $2); }
		;

s_message	: MESSAGE com expr			{ $$ = mk_message($1, $2, $3); }
		;

s_open		: OPEN com cursor FOR sql_select	{ $$ = mk_open($1, $2, $3, $5, NULL); }
		| OPEN com cursor FOR sql_select FOR update_clause
							{ $$ = mk_open($1, $2, $3, $5, $7); }
		;

update_clause	: update_mode update_of			{ $$ = updateclause($1, $2); } 
		;

update_mode	: READONLY				{ $$ = READONLY; }
		| DEFERRED				{ $$ = DEFERRED; }
		| DIRECT				{ $$ = DIRECT; }
		| /* empty */				{ $$ = 0; }
		;

update_of	: UPDATE OF column_list			{ $$ = $3; }
		| /* empty */				{ $$ = NULL; }
		;

s_openframe	: opt_return OPENFRAME com frame_name callparms
							{ $$ = mk_openframe($2, $3, $1, $4, $5, NULL); }
		| opt_return OPENFRAME com frame_name callparms WITH optlist
							{ $$ = mk_openframe($2, $3, $1, $4, $5, $7); }
		;

s_prompt	: variable '=' PROMPT com expr		{ $$ = mk_prompt($3, $4, $1, $5); }
		;

s_resume	: RESUME com opt_next			{ $$ = mk_resume($1, $2, $3); }
		;

opt_next	: NEXT					{ $$ = 1; }
		| /* empty */				{ $$ = 0; }
		;

s_return	: RETURN com opt_expr			{ $$ = mk_return($1, $2, $3); }
		;

s_rollback	: ROLLBACK com opt_work savepoint	{ $$ = mk_rollback($1, $2, $3, $4); }
		;

savepoint	: TO IDENT				{ $$ = $2; }
		| /* empty */				{ $$ = NULL; }
		;

s_select	: opt_repeated com sql_select opt_block	{ $$ = mk_select($1, $2, $3, $4); }
		;

s_update	: opt_repeated sql_update		{ $$ = mk_update($1, $2); }
		;

s_while		: opt_label WHILE com expr DO stmtlist ENDWHILE
							{ $$ = mk_while($2, $3, $1, $4, $6); }
		;

s_set		: SET com IDENT IDENT WHERE expr	{ $$ = mk_set($1, $2, $3, 0, $4, $6); }
		| SET com IDENT ON IDENT WHERE expr	{ $$ = mk_set($1, $2, $3, 1, $5, $7); }
		;

/***********************************************************************
 *		COMMON STATEMENT RULES
 ***********************************************************************
 */

stmtlist	: stmt					{ $$ = mk_stmtlist($1); }
		| stmtlist ';' stmt			{ $$ = stmtlist_add($1, mk_stmtlist($3)); }
		;

stmt_block	: BEGIN stmtlist END			{ $$ = mk_block($2); }
		;

opt_block	: stmt_block				{ $$ = $1; }
		| /* empty */				{ $$ = NULL; }
		;

opt_return	: variable '='				{ $$ = $1; }
		| /* empty */				{ $$ = NULL; }
		;

optlist		: attr					{ $$ = $1; }
		| optlist ',' attr			{ $$ = optlist_add($1, $3); }
		;

attr		: IDENT '=' expr			{ $$ = optlist($1, $3); }
		;

opt_labelref	: IDENT					{ $$ = $1; }
		| /* empty */				{ $$ = NULL; }
		;

opt_repeated	: REPEATED				{ $$ = 1; }
		| /* empty */				{ $$ = 0; }
		;

tablename	: IDENT					{ $$ = tablename(0, $1); }
		| ':' IDENT				{ $$ = tablename(1, $2); }
		;

opt_corrname	: IDENT					{ $$ = $1; }
		| /* empty */				{ $$ = NULL; }
		;

cursor_list	: cursor				{ $$ = cursorlist($1); }
		| cursor_list ',' cursor		{ $$ = cursorlist_add($1, cursorlist($3)); }
		;

cursor		: IDENT					{ $$ = $1; }
		;

varlist		: variable				{ $$ = varlist($1); }
		| varlist ',' variable			{ $$ = varlist_add($1, varlist($3)); }
		;

column_name	: variable				{ $$ = $1; }
		;

opt_label	: IDENT ':'				{ $$ = $1; }
		| /* empty */				{ $$ = NULL; }
		;

frame_name	: IDENT					{ $$ = frame_name(0, $1); }
		| ':' IDENT				{ $$ = frame_name(1, $2); }
		;

opt_expr	: expr					{ $$ = $1; }
		| /* empty */				{ $$ = NULL; }
		;

/***********************************************************************
 *		SQL RULES
 ***********************************************************************
 */
sql_expr	: expr				{ $$ = $1; }
		;

sql_explist	: sql_expr			{ $$ = sqlexplist($1); }
		| sql_explist ',' sql_expr	{ $$ = sqlexplist_add($1, sqlexplist($3)); }

search_expr	: expr				{ $$ = $1; }
		;

column_list	: column_name			{ $$ = columnlist($1); }
		| column_list ',' column_name	{ $$ = columnlist_add($1, columnlist($3)); }
		;

columns		: '(' column_list ')'		{ $$ = $2; }
		| /* empty */			{ $$ = NULL; }
		;

sql_delete	: DELETE com FROM tablename opt_corrname WHERE CURRENT OF cursor
					{ $$ = mk_sqldelete($1, $2, $4, $5, $9, NULL); }
		| DELETE com FROM tablename opt_corrname where_clause
					{ $$ = mk_sqldelete($1, $2, $4, $5, NULL, $6); }
		;

sql_insert	: INSERT com INTO tablename columns VALUES '(' sql_explist ')'
					{ $$ = mk_sqlinsert($1, $2, $4, $5, $8, NULL); }
		| INSERT com INTO tablename columns sql_select
					{ $$ = mk_sqlinsert($1, $2, $4, $5, NULL, $6); }
		;

sql_select	: select_union order_clause			{ $$ = mk_sqlselect($1, $2); }
		;

select_union	: subselect					{ $$ = $1; }
		| select_union UNION select_union		{ $$ = subselect_join(1, $1, $3); }
		| select_union UNION ALL select_union		{ $$ = subselect_join(2, $1, $4); }
		;

subselect	: SELECT selmode sql_explist from_clause where_clause group_clause having_clause
						{ $$ = subselect($1, $2, $3, $4, $5, $6, $7); }
		;

order_clause	: ORDER BY order_list		{ $$ = $3; }
		| /* empty */			{ $$ = NULL; }
		;

order_list	: orderspec			{ $$ = $1; }
		| order_list ',' orderspec	{ $$ = orderspec_add($1, $3); }
		;

orderspec	: column_name sortorder		{ $$ = orderspec($1, NULL, $2); }
		| INTEGER sortorder		{ $$ = orderspec(NULL, $1, $2); }
		;

sortorder	: ASC				{ $$ = ASC; }
		| DESC				{ $$ = DESC; }
		| /* empty */			{ $$ = 0; }
		;

selmode		: ALL				{ $$ = ALL; }
		| DISTINCT			{ $$ = DISTINCT; }
		| /* empty */			{ $$ = 0; }
		;

where_clause	: WHERE search_expr		{ $$ = $2; }
		| /* empty */			{ $$ = NULL; }
		;

group_clause	: GROUP BY column_list		{ $$ = $3; }
		| /* empty */			{ $$ = NULL; }
		;

having_clause	: HAVING sql_expr		{ $$ = $2; }
		| /* empty */			{ $$ = NULL; }
		;

sql_update	: UPDATE com tablename opt_corrname from_clause SET set_clause where_clause
					{ $$ = mk_sqlupdate($1, $2, $3, $4, $5, $7, NULL, $8); }

		| UPDATE com tablename opt_corrname from_clause SET set_clause WHERE CURRENT OF cursor
					{ $$ = mk_sqlupdate($1, $2, $3, $4, $5, $7, $11, NULL); }

		;

from_clause	: FROM from_list			{ $$ = $2; }
		| /* empty */				{ $$ = NULL; }
		;

from_list	: from_item				{ $$ = $1; }
		| from_list ',' from_item		{ $$ = fromlist_add($1, $3); }
		;

from_item	: tablename opt_corrname		{ $$ = fromlist($1, $2); }
		;

set_clause	: set_expr				{ $$ = $1; }
		| set_clause ',' set_expr		{ $$ = setclause_add($1, $3); }
		;

set_expr	: column_name '=' sql_expr		{ $$ = setclause($1, $3); }
		;

%%

/* yyerror -
 *	Call the Parse_Error routine, and exit.
 */
static void yyerror(char *s)
{
	Parse_Error(MSG_YACC_SYNTAX, s);
}

Return To Portfolio Home

compilers • parsers • translators • C++ • yacc &bull lex • bison • unix • windows • eiffel • grammars