%{ /* 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-il-dot.h" #include "py-il-tree.h" #include "py-vec.h" #if !defined(YYLLOC_DEFAULT) # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (N) \ { \ (Current).line = YYRHSLOC(Rhs, 1).line; \ (Current).column = YYRHSLOC(Rhs, 1).column; \ } \ else \ { \ (Current).line = YYRHSLOC(Rhs, 0).line; \ (Current).column = YYRHSLOC(Rhs, 0).column; \ } \ while (0) #endif static VEC(gpydot,gc) * gpy_symbol_stack; extern int yylineno; extern int yylex (void); extern void yyerror (const char *); %} %union { char * string; long int integer; gpy_dot_tree_t * symbol; } %debug /* Locations will be added later to add debugging information */ %locations %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 attributeref %type ident %type funcname %type classname %left '-' '+' %left '*' '/' %right '=' %nonassoc UMINUS %% declarations: /* epsilon */ | declarations decl { if ($2) { gpy_dot_pass_manager_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 ',' ident { DOT_CHAIN($1) = $3; $$ = $3; } | ident { 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; } | attributeref ; ident: IDENTIFIER { $$ = dot_build_identifier ($1); } ; attributeref: primary '.' ident { $$ = dot_build_decl2 (D_ATTRIB_REF, $1, $3); } ; 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: ident | literal ; call: primary '(' argument_list_stmt ')' { gpy_dot_tree_t *dot = dot_build_decl2 (D_CALL_EXPR, $1, $3); $$ = dot; } ; primary: atom | call | attributeref ; %% void yyerror( const char *msg ) { error( "%s at line %i\n", msg, yylineno ); }