/*
* aegis - project change supervisor
* Copyright (C) 1994-1996, 1999, 2002, 2005-2008, 2012 Peter Miller
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see
* .
*/
%{
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef DEBUG
#define YYDEBUG 1
#endif
static void
turn_on_debug(void)
{
#ifdef DEBUG
extern int yydebug;
yydebug = trace_pretest_;
#endif
}
static rpt_stmt::pointer result;
void
report_interpret(void)
{
assert(!!result);
sub_context_ty sc;
rpt_stmt_result_ty ok;
result->run(&ok);
switch (ok.status)
{
case rpt_stmt_status_normal:
break;
case rpt_stmt_status_break:
sc.fatal_intl(i18n("floating \"break\" statement"));
break;
case rpt_stmt_status_continue:
sc.fatal_intl(i18n("floating \"continue\" statement"));
break;
case rpt_stmt_status_return:
sc.fatal_intl(i18n("floating \"return\" statement"));
break;
case rpt_stmt_status_error:
{
rpt_value_error *ep =
dynamic_cast(ok.thrown.get());
assert(ep);
if (ep)
ep->print();
sc.fatal_intl(i18n("report aborted"));
}
break;
}
result.reset();
}
%}
%token AND_BIT
%token AND_LOGICAL
%token ASSIGN
%token ASSIGN_AND_BIT
%token ASSIGN_DIV
%token ASSIGN_JOIN
%token ASSIGN_MINUS
%token ASSIGN_MOD
%token ASSIGN_MUL
%token ASSIGN_OR_BIT
%token ASSIGN_PLUS
%token ASSIGN_POWER
%token ASSIGN_SHIFT_LEFT
%token ASSIGN_SHIFT_RIGHT
%token ASSIGN_XOR_BIT
%token AUTO
%token BREAK
%token CASE
%token CATCH
%token COLON
%token COMMA
%token CONSTANT
%token CONTINUE
%token DECR
%token DEFAULT
%token DIV
%token DO
%token DOT
%token ELSE
%token EQ
%token FOR
%token FUNCTION
%token GE
%token GLOBAL
%token GOTO
%token GT
%token IF
%token IN
%token INCR
%token JOIN
%token JUNK
%token LB
%token LBB
%token LE
%token LP
%token LT
%token MATCH
%token MINUS
%token MOD
%token MUL
%token NAME
%token NE
%token NMATCH
%token NOT_BIT
%token NOT_LOGICAL
%token OR_BIT
%token OR_LOGICAL
%token PLUS
%token POWER
%token RB
%token RBB
%token RETURN
%token RP
%token SEMICOLON
%token SHIFT_LEFT
%token SHIFT_RIGHT
%token SWITCH
%token THROW
%token TRY
%token WHILE
%token XOR_BIT
%union
{
long lv_number;
nstring *lv_string;
rpt_value::pointer *lv_value;
rpt_stmt::pointer *lv_stmt;
rpt_expr::pointer *lv_expr;
}
%type expr
%type CONSTANT
%type stmt stmt_list compound_stmt
%type NAME
%type expr_list struct_list expr_list_opt struct_assign
%type declaration decl_name_list decl_name
/*
* the precedences, lowest to highest
*/
%right ELSE
%left COMMA
%right ASSIGN ASSIGN_PLUS ASSIGN_MINUS ASSIGN_MUL ASSIGN_DIV ASSIGN_MOD
ASSIGN_POWER ASSIGN_SHIFT_LEFT ASSIGN_SHIFT_RIGHT ASSIGN_AND_BIT
ASSIGN_OR_BIT ASSIGN_XOR_BIT ASSIGN_JOIN
%right QUESTION COLON
%left OR_LOGICAL
%left AND_LOGICAL
%left OR_BIT
%left XOR_BIT
%left AND_BIT
%left EQ NE
%left LT GT LE GE
%left SHIFT_LEFT SHIFT_RIGHT
%left PLUS MINUS JOIN
%left MUL DIV MOD MATCH NMATCH IN
%right POWER
%right INCR DECR NOT_LOGICAL NOT_BIT unary.prec
%left LP RP LBB RBB LB RB DOT
%%
report_debugged
: turn_on_debug report
;
turn_on_debug
: /* empty */
{ turn_on_debug(); }
;
report
: stmt_list
{
result = *$1;
delete $1;
}
;
stmt_list
: /* empty */
{
rpt_stmt::pointer sp = rpt_stmt_compound::create();
$$ = new rpt_stmt::pointer(sp);
}
| stmt_list stmt
{
$$ = $1;
(*$$)->append(*$2);
delete $2;
}
;
stmt
: SEMICOLON
{
rpt_stmt::pointer sp = rpt_stmt_null::create();
$$ = new rpt_stmt::pointer(sp);
}
| expr SEMICOLON
{
rpt_stmt::pointer sp = rpt_stmt_expr::create(*$1);
$$ = new rpt_stmt::pointer(sp);
delete $1;
}
| compound_stmt
{ $$ = $1; }
| FOR LP expr SEMICOLON expr SEMICOLON expr RP stmt
{
rpt_stmt::pointer sp = rpt_stmt_for::create(*$3, *$5, *$7, *$9);
$$ = new rpt_stmt::pointer(sp);
delete $3;
delete $5;
delete $7;
delete $9;
}
| FOR LP expr IN expr RP stmt
{
rpt_stmt::pointer sp = rpt_stmt_foreach::create(*$3, *$5, *$7);
$$ = new rpt_stmt::pointer(sp);
delete $3;
delete $5;
delete $7;
}
| declaration
{ $$ = $1; }
| BREAK SEMICOLON
{
rpt_stmt::pointer sp = rpt_stmt_break::create();
$$ = new rpt_stmt::pointer(sp);
}
| CONTINUE SEMICOLON
{
rpt_stmt::pointer sp = rpt_stmt_continue::create();
$$ = new rpt_stmt::pointer(sp);
}
| IF LP expr RP stmt
%prec ELSE
{
rpt_stmt::pointer sp = rpt_stmt_if::create(*$3, *$5);
$$ = new rpt_stmt::pointer(sp);
delete $3;
delete $5;
}
| IF LP expr RP stmt ELSE stmt
{
rpt_stmt::pointer sp = rpt_stmt_if::create(*$3, *$5, *$7);
$$ = new rpt_stmt::pointer(sp);
delete $3;
delete $5;
delete $7;
}
| WHILE LP expr RP stmt
{
rpt_stmt::pointer sp = rpt_stmt_while::create(*$3, *$5);
$$ = new rpt_stmt::pointer(sp);
delete $3;
delete $5;
}
| DO stmt WHILE LP expr RP SEMICOLON
{
rpt_stmt::pointer sp = rpt_stmt_do::create(*$2, *$5);
$$ = new rpt_stmt::pointer(sp);
delete $2;
delete $5;
}
| RETURN expr SEMICOLON
{
rpt_stmt::pointer sp = rpt_stmt_return::create(*$2);
$$ = new rpt_stmt::pointer(sp);
delete $2;
}
| RETURN SEMICOLON
{
rpt_stmt::pointer sp = rpt_stmt_return::create();
$$ = new rpt_stmt::pointer(sp);
}
| THROW expr SEMICOLON
{
rpt_stmt::pointer sp = rpt_stmt_throw::create(*$2);
$$ = new rpt_stmt::pointer(sp);
delete $2;
}
| TRY stmt CATCH LP expr RP stmt
{
rpt_stmt::pointer sp = rpt_stmt_try::create(*$2, *$5, *$7);
$$ = new rpt_stmt::pointer(sp);
delete $2;
delete $5;
delete $7;
}
| error
{
rpt_stmt::pointer sp = rpt_stmt_null::create();
$$ = new rpt_stmt::pointer(sp);
}
;
compound_stmt
: LB stmt_list RB
{ $$ = $2; }
;
declaration
: AUTO decl_name_list SEMICOLON
{ $$ = $2; }
;
decl_name_list
: decl_name
{
rpt_stmt::pointer sp = rpt_stmt_compound::create();
sp->append(*$1);
delete $1;
$$ = new rpt_stmt::pointer(sp);
}
| decl_name_list COMMA decl_name
{
$$ = $1;
(*$$)->append(*$3);
delete $3;
}
;
decl_name
: NAME
{
/*
* declare the name
* and initialize it to nul
*/
rpt_expr_name__declare(*$1);
rpt_expr::pointer e1 = rpt_expr_name(*$1);
e1->pos_from_lex();
delete $1;
rpt_value::pointer vp = rpt_value_null::create();
rpt_expr::pointer e2 = rpt_expr_constant::create(vp);
e2->pos_from_lex();
rpt_expr::pointer e3 = rpt_expr_assign::create(e1, e2);
rpt_stmt::pointer sp = rpt_stmt_expr::create(e3);
$$ = new rpt_stmt::pointer(sp);
}
;
expr
: CONSTANT
{
rpt_expr::pointer ep = rpt_expr_constant::create(*$1);
delete $1;
ep->pos_from_lex();
$$ = new rpt_expr::pointer(ep);
}
| NAME
{
rpt_expr::pointer ep = rpt_expr_name(*$1);
ep->pos_from_lex();
delete $1;
$$ = new rpt_expr::pointer(ep);
}
| LP expr RP
{ $$ = $2; }
| expr LP expr_list_opt RP
{
rpt_expr::pointer ep = rpt_expr_func::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| LB struct_list RB
{
$$ = $2;
}
| LBB expr_list_opt RBB
{ $$ = $2; }
| expr LBB expr RBB
{
rpt_expr::pointer ep = rpt_expr_lookup::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr DOT NAME
{
rpt_expr::pointer ep = rpt_expr_lookup::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| MINUS expr
%prec unary.prec
{
rpt_expr::pointer ep = rpt_expr_neg::create(*$2);
delete $2;
$$ = new rpt_expr::pointer(ep);
}
| PLUS expr
%prec unary.prec
{
rpt_expr::pointer ep = rpt_expr_pos::create(*$2);
delete $2;
$$ = new rpt_expr::pointer(ep);
}
| NOT_LOGICAL expr
{
rpt_expr::pointer ep = rpt_expr_not_logical::create(*$2);
delete $2;
$$ = new rpt_expr::pointer(ep);
}
| NOT_BIT expr
{
rpt_expr::pointer ep = rpt_expr_not_bit::create(*$2);
delete $2;
$$ = new rpt_expr::pointer(ep);
}
| INCR expr
{
rpt_expr::pointer ep = rpt_expr_inc_pre::create(*$2);
delete $2;
$$ = new rpt_expr::pointer(ep);
}
| DECR expr
{
rpt_expr::pointer ep = rpt_expr_dec_pre::create(*$2);
delete $2;
$$ = new rpt_expr::pointer(ep);
}
| expr INCR
{
rpt_expr::pointer ep = rpt_expr_inc_post::create(*$1);
delete $1;
$$ = new rpt_expr::pointer(ep);
}
| expr DECR
{
rpt_expr::pointer ep = rpt_expr_dec_post::create(*$1);
delete $1;
$$ = new rpt_expr::pointer(ep);
}
| expr POWER expr
{
rpt_expr::pointer ep = rpt_expr_power::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr MUL expr
{
rpt_expr::pointer ep = rpt_expr_mul::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr DIV expr
{
rpt_expr::pointer ep = rpt_expr_div::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr MOD expr
{
rpt_expr::pointer ep = rpt_expr_mod::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr SHIFT_LEFT expr
{
rpt_expr::pointer ep = rpt_expr_shift_left::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr SHIFT_RIGHT expr
{
rpt_expr::pointer ep = rpt_expr_shift_right::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr PLUS expr
{
rpt_expr::pointer ep = rpt_expr_plus::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr MINUS expr
{
rpt_expr::pointer ep = rpt_expr_minus::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr JOIN expr
{
rpt_expr::pointer ep = rpt_expr_join::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr LT expr
{
rpt_expr::pointer ep = rpt_expr_lt::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr LE expr
{
rpt_expr::pointer ep = rpt_expr_le::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr GT expr
{
rpt_expr::pointer ep = rpt_expr_gt::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr GE expr
{
rpt_expr::pointer ep = rpt_expr_ge::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr EQ expr
{
rpt_expr::pointer ep = rpt_expr_eq::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr NE expr
{
rpt_expr::pointer ep = rpt_expr_ne::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr IN expr
{
rpt_expr::pointer ep = rpt_expr_in::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr MATCH expr
{
rpt_expr::pointer ep = rpt_expr_match::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr NMATCH expr
{
rpt_expr::pointer ep = rpt_expr_nmatch::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr AND_BIT expr
{
rpt_expr::pointer ep = rpt_expr_and_bit::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr AND_LOGICAL expr
{
rpt_expr::pointer ep = rpt_expr_and_logical::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr OR_BIT expr
{
rpt_expr::pointer ep = rpt_expr_or_bit::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr XOR_BIT expr
{
rpt_expr::pointer ep = rpt_expr_xor_bit::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr OR_LOGICAL expr
{
rpt_expr::pointer ep = rpt_expr_or_logical::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr ASSIGN expr
{
rpt_expr::pointer ep = rpt_expr_assign::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr ASSIGN_PLUS expr
{
rpt_expr::pointer ep = rpt_expr_assign_plus::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr ASSIGN_MINUS expr
{
rpt_expr::pointer ep = rpt_expr_assign_minus::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr ASSIGN_MUL expr
{
rpt_expr::pointer ep = rpt_expr_assign_mul::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr ASSIGN_DIV expr
{
rpt_expr::pointer ep = rpt_expr_assign_div::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr ASSIGN_MOD expr
{
rpt_expr::pointer ep = rpt_expr_assign_mod::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr ASSIGN_POWER expr
{
rpt_expr::pointer ep = rpt_expr_assign_power::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr ASSIGN_JOIN expr
{
rpt_expr::pointer ep = rpt_expr_assign_join::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr ASSIGN_AND_BIT expr
{
rpt_expr::pointer ep = rpt_expr_assign_and_bit::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr ASSIGN_OR_BIT expr
{
rpt_expr::pointer ep = rpt_expr_assign_or_bit::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr ASSIGN_XOR_BIT expr
{
rpt_expr::pointer ep = rpt_expr_assign_xor_bit::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr ASSIGN_SHIFT_LEFT expr
{
rpt_expr::pointer ep = rpt_expr_assign_shift_left::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr ASSIGN_SHIFT_RIGHT expr
{
rpt_expr::pointer ep =
rpt_expr_assign_shift_right::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr COMMA expr
{
rpt_expr::pointer ep = rpt_expr_comma::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
| expr QUESTION expr COLON expr
{
rpt_expr::pointer ep = rpt_expr_if::create(*$1, *$3, *$5);
delete $1;
delete $3;
delete $5;
$$ = new rpt_expr::pointer(ep);
}
;
expr_list_opt
: /* empty */
{
rpt_expr::pointer ep = rpt_expr_list::create();
ep->pos_from_lex();
$$ = new rpt_expr::pointer(ep);
}
| expr_list
{
$$ = $1;
}
;
expr_list
: expr
%prec COMMA
{
rpt_expr::pointer ep = rpt_expr_list::create();
ep->append(*$1);
delete $1;
$$ = new rpt_expr::pointer(ep);
}
| expr_list COMMA expr
{
$$ = $1;
(*$$)->append(*$3);
delete $3;
}
;
struct_list
: /* empty */
{
rpt_expr::pointer ep = rpt_expr_struct::create();
ep->pos_from_lex();
$$ = new rpt_expr::pointer(ep);
}
| struct_list struct_assign
{
$$ = $1;
(*$$)->append(*$2);
delete $2;
}
;
struct_assign
: NAME ASSIGN expr SEMICOLON
{
rpt_expr::pointer ep = rpt_expr_struct_assign::create(*$1, *$3);
delete $1;
delete $3;
$$ = new rpt_expr::pointer(ep);
}
;
/* vim: set ts=8 sw=4 et : */