/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1989-2012 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* *
***********************************************************************/
%{
/*
* Glenn Fowler
* AT&T Research
*
* expression library grammar and compiler
*/
#include <ast.h>
%}
%union
{
double floating;
int op;
char* string;
}
%{
#include "exgram.h"
%}
%%
{
{
{
Exnode_t* x;
x = $1;
}
}
}
;
;
exerror("no nested function definitions");
exnospace();
{
if (!(expr.procedure->data.procedure.frame = dtopen(disc, Dtset)) || !dtview(expr.procedure->data.procedure.frame, expr.program->symbols))
exnospace();
}
{
{
}
{
Exnode_t* x;
x = $4;
}
}
;
{
$$ = 0;
}
{
if (!$1)
$$ = $2;
else if (!$2)
$$ = $1;
{
$$ = $2;
}
{
$$ = $1;
$1->data.operand.last = $1->data.operand.last->data.operand.right = exnewnode(expr.program, ';', 1, $2->type, $2, NiL);
}
else
{
$$->data.operand.last = $$->data.operand.right = exnewnode(expr.program, ';', 1, $2->type, $2, NiL);
}
}
;
{
$$ = $2;
}
| expr_opt ';'
{
}
{
$$ = $5;
}
{
$$ = exnewnode(expr.program, $1->index, 1, INTEGER, $3, exnewnode(expr.program, ':', 1, $5 ? $5->type : 0, $5, $6));
}
{
exerror("simple index variable expected");
exerror("integer index variable expected");
}
{
if (!$5)
{
}
$$ = exnewnode(expr.program, $1->index, 1, INTEGER, $5, exnewnode(expr.program, ';', 1, 0, $7, $9));
if ($3)
}
{
$$ = exnewnode(expr.program, $1->index, 1, INTEGER, $3, exnewnode(expr.program, ';', 1, 0, NiL, $5));
}
{
$$ = exnewnode(expr.program, $1->index, 1, INTEGER, $3, exnewnode(expr.program, DEFAULT, 1, 0, sw->defcase, sw->firstcase));
}
{
if (!$2)
{
}
}
{
goto loopop;
}
{
if ($2)
{
exerror("return in void function");
}
}
;
{
int n;
{
{
exnospace();
}
}
else
n = 8;
{
exnospace();
n = 0;
}
}
;
{
int n;
{
else
}
else
{
exerror("duplicate default in switch");
else
}
}
;
;
{
int n;
{
{
exerror("too many case labels for switch");
n = 0;
}
}
{
}
}
| DEFAULT ':'
{
}
;
static : /* empty */
{
$$ = 0;
}
| STATIC
{
$$ = 1;
}
;
{
if ($3)
}
;
{
$$ = 0;
if ($1)
{
else if ($5)
}
{
}
else
{
{
exnospace();
}
if ($5)
{
{
}
$$ = $5;
{
}
}
else if (!$4)
}
}
;
| DYNAMIC
;
{
$$ = 0;
}
{
$$ = $2;
}
;
{
$$ = 0;
}
| expr
;
{
$$ = $2;
}
{
}
{
int rel;
goto coerce;
rel = 0;
if (!$1->type)
{
if (!$3->type)
else
}
else if (!$3->type)
{
}
if (!rel)
{
$$->binary = 0;
}
}
{
goto binary;
}
{
goto binary;
}
{
goto binary;
}
{
goto binary;
}
{
goto binary;
}
{
goto binary;
}
{
goto relational;
}
{
goto relational;
}
{
goto relational;
}
{
goto relational;
}
{
goto relational;
}
{
goto binary;
}
{
goto binary;
}
{
goto binary;
}
{
goto binary;
}
{
goto binary;
}
{
goto logical;
}
{
{
$$ = $3;
}
else
}
{
if (!$4->type)
{
if (!$7->type)
else
}
else if (!$7->type)
{
exerror("if statement string type mismatch");
}
{
{
$$ = $4;
}
else
{
$$ = $7;
}
}
else
$$ = exnewnode(expr.program, '?', 1, $4->type, $1, exnewnode(expr.program, ':', 1, $4->type, $4, $7));
}
| '!' expr
{
{
$$->binary = 0;
}
}
| '~' expr
{
goto iunary;
}
{
goto unary;
}
{
$$ = $2;
}
{
}
{
exerror("%s: function references not supported", $$->data.operand.left->data.variable.symbol->name);
(*expr.program->disc->reff)(expr.program, $$->data.operand.left, $$->data.operand.left->data.variable.symbol, $1, NiL, EX_CALL, expr.program->disc);
}
{
}
{
}
{
{
}
else
switch ($1->index)
{
case QUERY:
break;
case PRINTF:
break;
case SPRINTF:
break;
}
}
{
register Exnode_t* x;
{
}
else
switch ($1->index)
{
case SCANF:
break;
case SSCANF:
{
}
else
break;
}
{
}
}
{
else
{
$$->data.constant.value = (*expr.program->disc->reff)(expr.program, $$, $3, NiL, $1, EX_SCALAR, expr.program->disc);
}
}
{
if ($2)
{
else
{
if (!$1->type)
#if 0
#else
#endif
{
}
$$ = $2;
}
}
}
{
pre:
exerror("++ and -- invalid for string variables");
}
{
pos:
exerror("++ and -- invalid for string variables");
}
{
goto pre;
}
{
goto pos;
}
| constant
;
{
else
$$->data.constant.value = (*expr.program->disc->reff)(expr.program, $$, $1, NiL, NiL, EX_SCALAR, expr.program->disc);
}
| FLOATING
{
}
| INTEGER
{
}
| STRING
{
}
| UNSIGNED
{
}
;
| QUERY
| SPRINTF
;
| SSCANF
;
{
(*expr.program->disc->reff)(expr.program, $$, $$->data.variable.symbol, $1, NiL, $3 ? 0 : EX_SCALAR, expr.program->disc);
}
{
}
| NAME
{
exerror("unknown identifier");
}
;
{
$$ = 0;
}
| '[' ']'
{
$$ = 1;
}
;
{
$$ = 0;
}
{
$$ = $2;
}
;
{
$$ = 0;
}
| arg_list
{
}
;
{
}
{
$1->data.operand.right = $1->data.operand.right->data.operand.right = exnewnode(expr.program, ',', 1, $1->type, $3, NiL);
}
;
{
$$ = 0;
}
| DECLARE
{
$$ = 0;
if ($1->type)
exerror("(void) expected");
}
;
{
}
{
register Exnode_t* x;
register Exnode_t* y;
$$ = $1;
}
;
{
}
;
{
}
{
Exref_t* r;
{
}
else
{
r->symbol = $2;
}
r->next = 0;
r->index = $3;
}
;
{
$$ = 0;
}
| '=' expr
{
$$->subop = $1;
}
;
| '(' {
exnospace();
{
if (!(expr.procedure->data.procedure.frame = dtopen(disc, Dtset)) || !dtview(expr.procedure->data.procedure.frame, expr.program->symbols))
exnospace();
}
} formals {
{
{
}
/*
* NOTE: procedure definition was slipped into the
* declaration initializer statement production,
* therefore requiring the statement terminator
*/
}
;
%%
#include "exgram.h"