%{
/* This file is part of GCC.
GCC 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, or (at your option) any later
version.
GCC 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 GCC; see the file COPYING3. If not see
. */
/* Grammar largely bassed on
* - http://docs.python.org/release/2.5.2/ref/grammar.txt
*/
#include "config.h"
#include "system.h"
#include "ansidecl.h"
#include "coretypes.h"
#include "opts.h"
#include "tree.h"
#include "gimple.h"
#include "toplev.h"
#include "debug.h"
#include "options.h"
#include "flags.h"
#include "convert.h"
#include "diagnostic-core.h"
#include "langhooks.h"
#include "langhooks-def.h"
#include "target.h"
#include
#include
#include "vec.h"
#include "hashtab.h"
#include "gpython.h"
#include "py-dot.h"
#include "py-vec.h"
#include "py-tree.h"
static VEC(gpydot,gc) * gpy_symbol_stack;
extern int yylineno;
//yydebug = 1;
extern int yylex( void );
extern void yyerror( const char * );
%}
%union {
char * string;
long int integer;
gpy_dot_tree_t * symbol;
}
%error-verbose
%start declarations
%token CLASS "class"
%token DEF "def"
%token BREAK "break"
%token CONTINUE "continue"
%token RETURN "return"
%token FOR "for"
%token WHILE "while"
%token IN "in"
%token PRINT "print"
%token EXCEPT "except"
%token FINALLY "finally"
%token TRY "try"
%token AS "as"
%token ASSERT "assert"
%token DEL "del"
%token EXEC "exec"
%token FROM "from"
%token GLOBAL "global"
%token IMPORT "import"
%token IS "is"
%token LAMBDA "lambda"
%token PASS "pass"
%token RAISE "raise"
%token WITH "with"
%token YIELD "yield"
%token IF "if"
%token ELIF "elif"
%token ELSE "else"
%token OR "or"
%token AND "and"
%token NOT "not"
%token V_TRUE "True"
%token V_FALSE "False"
%token NEWLINE
%token INDENT
%token DEDENT
%token EQUAL_EQUAL
%token NOT_EQUAL
%token LESS
%token GREATER
%token LESS_EQUAL
%token GREATER_EQUAL
%token NONE
%token IDENTIFIER
%token STRING
%token INTEGER
%token DOUBLE
%type statement
%type compound_stmt
%type stmt_list
%type simple_stmt
%type expression_stmt
%type assignment_stmt
%type target_list
%type target
%type expression_list
%type funcdef
%type classdef
%type suite
%type suite_statement_list
%type indent_stmt
%type literal
%type m_expr
%type a_expr
%type u_expr
%type atom
%type primary
%type expression
%type conditional_expression
%type call
%type shift_expr
%type comparison
%type decl
%type argument_list
%type argument_list_stmt
%type parameter_list
%type parameter_list_stmt
%type print_stmt
%type funcname
%type classname
%left '-' '+'
%left '*' '/'
%right '='
%nonassoc UMINUS
%%
declarations:
| declarations decl
{
if( $2 )
{
debug ("passing decl <%p> type <0x%x>!\n",
(void*)$2, DOT_TYPE($2) );
gpy_stmt_process_decl ($2);
}
}
;
decl: NEWLINE
{ $$ = NULL; }
| statement
;
compound_stmt: funcdef
| classdef
;
classdef: CLASS classname ':' suite
{
gpy_dot_tree_t *dot = dot_build_class_decl ($2, $4);
$$ = dot;
}
;
classname: IDENTIFIER
{ $$ = dot_build_identifier ($1); }
;
funcname: IDENTIFIER
{ $$ = dot_build_identifier ($1); }
;
parameter_list_stmt:
{ $$ = NULL; }
| parameter_list
{ $$ = VEC_pop (gpydot, gpy_symbol_stack); }
;
parameter_list: parameter_list ',' target
{
DOT_CHAIN($1) = $3;
$$ = $3;
}
| target
{
VEC_safe_push (gpydot, gc,
gpy_symbol_stack, $1);
$$ = $1;
}
;
funcdef: DEF funcname '(' parameter_list_stmt ')' ':' suite
{
gpy_dot_tree_t *dot = dot_build_func_decl ($2, $4, $7);
$$ = dot;
}
;
suite: stmt_list NEWLINE
| NEWLINE INDENT suite_statement_list DEDENT
{
$$ = VEC_pop (gpydot, gpy_symbol_stack);
printf("poping suite!\n");
}
;
suite_statement_list: suite_statement_list indent_stmt
{
DOT_CHAIN($1) = $2;
$$ = $2;
}
| indent_stmt
{
VEC_safe_push (gpydot, gc,
gpy_symbol_stack, $1);
$$ = $1;
}
;
indent_stmt: statement
;
statement: stmt_list NEWLINE
| compound_stmt
;
stmt_list: simple_stmt
;
simple_stmt: assignment_stmt
| expression_stmt
| print_stmt
;
argument_list_stmt:
{ $$ = NULL; }
| argument_list
{ $$ = VEC_pop (gpydot, gpy_symbol_stack); }
;
argument_list: argument_list ',' expression
{
DOT_CHAIN($1) = $3;
$$ = $3;
}
| expression
{
VEC_safe_push (gpydot, gc,
gpy_symbol_stack, $1);
$$ = $1;
}
;
print_stmt: PRINT argument_list_stmt
{
gpy_dot_tree_t *dot = dot_build_decl1 (D_PRINT_STMT, $2);
$$ = dot;
}
;
expression_stmt: expression_list
;
assignment_stmt: target_list '=' expression_list
{
gpy_dot_tree_t *dot = dot_build_decl2 (D_MODIFY_EXPR, $1, $3);
$$ = dot;
}
;
target_list: target
;
target: IDENTIFIER
{
gpy_dot_tree_t *dot = dot_build_identifier ($1);
$$ = dot;
}
;
expression_list: expression
;
expression: conditional_expression
;
conditional_expression: comparison
;
u_expr: primary
;
m_expr: u_expr
| m_expr '*' u_expr
{
gpy_dot_tree_t *dot = dot_build_decl2 (D_MULT_EXPR, $1, $3);
$$ = dot;
}
| m_expr '/' u_expr
{
gpy_dot_tree_t *dot = dot_build_decl2 (D_DIVD_EXPR, $1, $3);
$$ = dot;
}
;
a_expr: m_expr
| a_expr '+' m_expr
{
gpy_dot_tree_t *dot = dot_build_decl2 (D_ADD_EXPR, $1, $3);
$$ = dot;
}
| a_expr '-' m_expr
{
gpy_dot_tree_t *dot = dot_build_decl2 (D_MINUS_EXPR, $1, $3);
$$ = dot;
}
;
shift_expr: a_expr
;
comparison: shift_expr
;
literal: INTEGER
{
gpy_dot_tree_t *dot = dot_build_integer ($1);
$$ = dot;
}
| STRING
{
gpy_dot_tree_t *dot = dot_build_string ($1);
$$ = dot;
}
;
atom: target
| literal
;
call: IDENTIFIER '(' argument_list_stmt ')'
{
gpy_dot_tree_t *dot = dot_build_decl2 (D_CALL_EXPR,
dot_build_identifier($1),
$3);
$$ = dot;
}
;
primary: atom
| call
;
%%
void yyerror( const char *msg )
{
error( "%s at line %i\n", msg, yylineno );
}