From 629b35f209d63d42f8ab3a3c2e5c180dc242d728 Mon Sep 17 00:00:00 2001 From: redbrain Date: Mon, 26 Jul 2010 01:55:21 +0100 Subject: [PATCH] re working to conform to python 2.5 grammar --- gcc/python/grammar.txt | 488 ++++++++++++++++++++++++++++++++++ gcc/python/lang-specs.h | 2 +- gcc/python/lexer.l | 8 +- gcc/python/parser.y | 675 ++++++++++++++++++------------------------------ 4 files changed, 747 insertions(+), 426 deletions(-) create mode 100644 gcc/python/grammar.txt rewrite gcc/python/parser.y (71%) diff --git a/gcc/python/grammar.txt b/gcc/python/grammar.txt new file mode 100644 index 00000000000..0475e29818f --- /dev/null +++ b/gcc/python/grammar.txt @@ -0,0 +1,488 @@ + +identifier ::= + (letter|"_") (letter | digit | "_")* + +letter ::= + lowercase | uppercase + +lowercase ::= + "a"..."z" + +uppercase ::= + "A"..."Z" + +digit ::= + "0"..."9" + +stringliteral ::= + [stringprefix](shortstring | longstring) + +stringprefix ::= + "r" | "u" | "ur" | "R" | "U" | "UR" | "Ur" | "uR" + +shortstring ::= + "'" shortstringitem* "'" + | '"' shortstringitem* '"' + +longstring ::= + "'''" longstringitem* "'''" + | '"""' longstringitem* '"""' + +shortstringitem ::= + shortstringchar | escapeseq + +longstringitem ::= + longstringchar | escapeseq + +shortstringchar ::= + + +longstringchar ::= + + +escapeseq ::= + "\" + +longinteger ::= + integer ("l" | "L") + +integer ::= + decimalinteger | octinteger | hexinteger + +decimalinteger ::= + nonzerodigit digit* | "0" + +octinteger ::= + "0" octdigit+ + +hexinteger ::= + "0" ("x" | "X") hexdigit+ + +nonzerodigit ::= + "1"..."9" + +octdigit ::= + "0"..."7" + +hexdigit ::= + digit | "a"..."f" | "A"..."F" + +floatnumber ::= + pointfloat | exponentfloat + +pointfloat ::= + [intpart] fraction | intpart "." + +exponentfloat ::= + (intpart | pointfloat) + exponent + +intpart ::= + digit+ + +fraction ::= + "." digit+ + +exponent ::= + ("e" | "E") ["+" | "-"] digit+ + +imagnumber ::= (floatnumber | intpart) ("j" | "J") + +atom ::= + identifier | literal | enclosure + +enclosure ::= + parenth_form | list_display + | generator_expression | dict_display + | string_conversion | yield_atom + +literal ::= + stringliteral | integer | longinteger + | floatnumber | imagnumber + +parenth_form ::= + "(" [expression_list] ")" + +list_display ::= + "[" [expression_list | list_comprehension] "]" + +list_comprehension ::= + expression list_for + +list_for ::= + "for" target_list "in" old_expression_list + [list_iter] + +old_expression_list ::= + old_expression + [("," old_expression)+ [","]] + +list_iter ::= + list_for | list_if + +list_if ::= + "if" old_expression [list_iter] + +generator_expression ::= + "(" expression genexpr_for ")" + +genexpr_for ::= + "for" target_list "in" or_test + [genexpr_iter] + +genexpr_iter ::= + genexpr_for | genexpr_if + +genexpr_if ::= + "if" old_expression [genexpr_iter] + +dict_display ::= + "\{" [key_datum_list] "\}" + +key_datum_list ::= + key_datum ("," key_datum)* [","] + +key_datum ::= + expression ":" expression + +string_conversion ::= + "`" expression_list "`" + +yield_atom ::= + "(" yield_expression ")" + +yield_expression ::= + "yield" [expression_list] + +primary ::= + atom | attributeref + | subscription | slicing | call + +attributeref ::= + primary "." identifier + +subscription ::= + primary "[" expression_list "]" + +slicing ::= + simple_slicing | extended_slicing + +simple_slicing ::= + primary "[" short_slice "]" + +extended_slicing ::= + primary "[" slice_list "]" + +slice_list ::= + slice_item ("," slice_item)* [","] + +slice_item ::= + expression | proper_slice | ellipsis + +proper_slice ::= + short_slice | long_slice + +short_slice ::= + [lower_bound] ":" [upper_bound] + +long_slice ::= + short_slice ":" [stride] + +lower_bound ::= + expression + +upper_bound ::= + expression + +stride ::= + expression + +ellipsis ::= + "..." + +call ::= + primary "(" [argument_list [","] + | expression genexpr_for] ")" + +argument_list ::= + positional_arguments ["," keyword_arguments] + ["," "*" expression] + ["," "**" expression] + | keyword_arguments ["," "*" expression] + ["," "**" expression] + | "*" expression ["," "**" expression] + | "**" expression + +positional_arguments ::= + expression ("," expression)* + +keyword_arguments ::= + keyword_item ("," keyword_item)* + +keyword_item ::= + identifier "=" expression + +power ::= + primary ["**" u_expr] + +u_expr ::= + power | "-" u_expr + | "+" u_expr | "\~" u_expr + +m_expr ::= + u_expr | m_expr "*" u_expr + | m_expr "//" u_expr + | m_expr "/" u_expr + | m_expr "\%" u_expr + +a_expr ::= + m_expr | a_expr "+" m_expr + | a_expr "-" m_expr + +shift_expr ::= + a_expr + | shift_expr ( "<<" | ">>" ) a_expr + +and_expr ::= + shift_expr | and_expr "\;SPMamp;" shift_expr + +xor_expr ::= + and_expr | xor_expr "\textasciicircum" and_expr + +or_expr ::= + xor_expr | or_expr "|" xor_expr + +comparison ::= + or_expr ( comp_operator or_expr )* + +comp_operator ::= + "<" | ">" | "==" | ">=" | "<=" | "<>" | "!=" + | "is" ["not"] | ["not"] "in" + +expression ::= + conditional_expression | lambda_form + +old_expression ::= + or_test | old_lambda_form + +conditional_expression ::= + or_test ["if" or_test "else" expression] + +or_test ::= + and_test | or_test "or" and_test + +and_test ::= + not_test | and_test "and" not_test + +not_test ::= + comparison | "not" not_test + +lambda_form ::= + "lambda" [parameter_list]: expression + +old_lambda_form ::= + "lambda" [parameter_list]: old_expression + +expression_list ::= + expression ( "," expression )* [","] + +simple_stmt ::= expression_stmt + | assert_stmt + | assignment_stmt + | augmented_assignment_stmt + | pass_stmt + | del_stmt + | print_stmt + | return_stmt + | yield_stmt + | raise_stmt + | break_stmt + | continue_stmt + | import_stmt + | global_stmt + | exec_stmt + +expression_stmt ::= + expression_list + +assert_stmt ::= + "assert" expression ["," expression] + +assignment_stmt ::= + (target_list "=")+ + (expression_list | yield_expression) + +target_list ::= + target ("," target)* [","] + +target ::= + identifier + | "(" target_list ")" + | "[" target_list "]" + | attributeref + | subscription + | slicing + +augmented_assignment_stmt ::= + target augop + (expression_list | yield_expression) + +augop ::= + "+=" | "-=" | "*=" | "/=" | "\%=" | "**=" + | ">>=" | "<<=" | "\&=" | "\textasciicircum=" | "|=" + +pass_stmt ::= + "pass" + +del_stmt ::= + "del" target_list + +print_stmt ::= + "print" ([expression ("," expression)* [","] + | ">>" expression + [("," expression)+ [","]) + +return_stmt ::= + "return" [expression_list] + +yield_stmt ::= + yield_expression + +raise_stmt ::= + "raise" [expression ["," expression + ["," expression]]] + +break_stmt ::= + "break" + +continue_stmt ::= + "continue" + +import_stmt ::= + "import" module ["as" name] + ( "," module ["as" name] )* + | "from" relative_module "import" identifier + ["as" name] + ( "," identifier ["as" name] )* + | "from" relative_module "import" "(" + identifier ["as" name] + ( "," identifier ["as" name] )* [","] ")" + | "from" module "import" "*" + +module ::= + (identifier ".")* identifier + +relative_module ::= + "."* module | "."+ + +name ::= + identifier + +global_stmt ::= + "global" identifier ("," identifier)* + +exec_stmt ::= + "exec" or_expr + ["in" expression ["," expression]] + +compound_stmt ::= + if_stmt + | while_stmt + | for_stmt + | try_stmt + | with_stmt + | funcdef + | classdef + +suite ::= + stmt_list NEWLINE + | NEWLINE INDENT statement+ DEDENT + +statement ::= + stmt_list NEWLINE | compound_stmt + +stmt_list ::= + simple_stmt (";" simple_stmt)* [";"] + +if_stmt ::= + "if" expression ":" suite + ( "elif" expression ":" suite )* + ["else" ":" suite] + +while_stmt ::= + "while" expression ":" suite + ["else" ":" suite] + +for_stmt ::= + "for" target_list "in" expression_list + ":" suite + ["else" ":" suite] + +try_stmt ::= try1_stmt | try2_stmt + +try1_stmt ::= + "try" ":" suite + ("except" [expression + ["," target]] ":" suite)+ + ["else" ":" suite] + ["finally" ":" suite] + +try2_stmt ::= + "try" ":" suite + "finally" ":" suite + +with_stmt ::= + "with" expression ["as" target] ":" suite + +funcdef ::= + [decorators] "def" funcname "(" [parameter_list] ")" + ":" suite + +decorators ::= + decorator+ + +decorator ::= + "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE + +dotted_name ::= + identifier ("." identifier)* + +parameter_list ::= + (defparameter ",")* + (~~"*" identifier [, "**" identifier] + | "**" identifier + | defparameter [","] ) + +defparameter ::= + parameter ["=" expression] + +sublist ::= + parameter ("," parameter)* [","] + +parameter ::= + identifier | "(" sublist ")" + +funcname ::= + identifier + +classdef ::= + "class" classname [inheritance] ":" + suite + +inheritance ::= + "(" [expression_list] ")" + +classname ::= + identifier + +file_input ::= + (NEWLINE | statement)* + +interactive_input ::= + [stmt_list] NEWLINE | compound_stmt NEWLINE + +eval_input ::= + expression_list NEWLINE* + +input_input ::= + expression_list NEWLINE diff --git a/gcc/python/lang-specs.h b/gcc/python/lang-specs.h index 0901bbf40b2..73482ca9291 100644 --- a/gcc/python/lang-specs.h +++ b/gcc/python/lang-specs.h @@ -15,7 +15,7 @@ along with GCC; see the file COPYING3. If not see . */ {".py", "@py", 0, 1, 0}, -{"@py", "gpy1 %i %(cc1_options) %{I*} %{L*} %D %{!fsyntax-only:%(invoke_as)}", +{"@py", "gpy1 %i %(cc1_options) %D %{!fsyntax-only:%(invoke_as)}", 0, 1, 0}, diff --git a/gcc/python/lexer.l b/gcc/python/lexer.l index b752976f52b..fc47967d9fd 100644 --- a/gcc/python/lexer.l +++ b/gcc/python/lexer.l @@ -93,6 +93,7 @@ else { return ELSE; } "-" { return '-'; } "/" { return '/'; } "*" { return '*'; } +"|" { return "|"; } "==" { return EQUAL; } @@ -104,6 +105,7 @@ else { return ELSE; } "or" { return OR; } "and" { return AND; } +"not" { return NOT; } {qstring} { yylval.string= xstrdup( (yytext+1) ); @@ -133,7 +135,11 @@ else { return ELSE; } return IDENTIFIER; } -[\n] { return DELIMITER; } +[\n] { return NEWLINE; } +[\t] { return INDENT; } +[\b] { return DEDENT; } + +. %% diff --git a/gcc/python/parser.y b/gcc/python/parser.y dissimilarity index 71% index 0f76847a708..c16ba737676 100644 --- a/gcc/python/parser.y +++ b/gcc/python/parser.y @@ -1,424 +1,251 @@ -%{ -/* 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 -. */ - -#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 "vec.h" - -#include "gpy.h" -#include "symbols.h" -#include "opcodes.def" -#include "line-map.h" - -#include -#include - -static VEC( gpy_sym,gc ) * gpy_symbol_stack; - -extern int yylineno; - -extern int yylex( void ); -extern void yyerror( const char * ); -%} - -%union { - char *string; - long int integer; - gpy_symbol_obj *symbol; -} - -%error-verbose - -%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 IF "if" -%token ELIF "elif" -%token ELSE "else" - -%token EQUAL "==" -%token NOT_EQUAL "!=" -%token LESS "<" -%token LESS_EQUAL "<=" -%token GREATER ">" -%token GREATER_EQUAL ">=" -%token OR "or" -%token AND "and" - -%token DELIMITER -%token NONE -%token IDENTIFIER -%token STRING -%token INTEGER - -%type expr -%type expression -%type symbol_accessor -%type function -%type loop_while -%type accessor -%type decl -%type primary -%type procedure -%type statement_block -%type parameter -%type parameters -%type parameter_list -%type key_return -%type arguments -%type argument_list -%type arbitrary_call -%type list_symbol - -%left '-' '+' -%left '*' '/' -%left LESS LESS_EQUAL -%left GREATER GREATER_EQUAL -%left NOT_EQUAL EQUAL -%left AND OR -%right '^' '=' -%nonassoc UMINUS - -%% - -declarations: - | declarations decl - { - gpy_process_decl( $2 ); - } - | error - { - fatal_error("malformed declaration!\n"); - } - ; - -decl: expression DELIMITER - | loop_while - | function - | key_return DELIMITER - ; - -key_return: RETURN expression - { - gpy_symbol_obj *sym; - Gpy_Symbol_Init( sym ); - - sym->type = KEY_RETURN; - sym->op_a_t = TYPE_SYMBOL; - - sym->op_a.symbol_table= $2; - $$= sym; - } - ; - -function: DEF IDENTIFIER '(' parameters ')' ':' '{' procedure '}' - { - gpy_symbol_obj *sym; - Gpy_Symbol_Init( sym ); - - sym->identifier= $2; - sym->type= STRUCTURE_FUNCTION_DEF; - sym->op_a_t= TYPE_SYMBOL; - sym->op_b_t= TYPE_PARAMETERS; - - sym->op_a.symbol_table = $8; - sym->op_b.symbol_table = $4; - $$= sym; - } - | DEF IDENTIFIER '(' ')' ':' '{' procedure '}' - { - gpy_symbol_obj *sym; - Gpy_Symbol_Init( sym ); - - sym->identifier = $2; - sym->type = STRUCTURE_FUNCTION_DEF; - sym->op_a_t = TYPE_SYMBOL; - sym->op_b_t = TYPE_SYMBOL_NIL; - - sym->op_a.symbol_table= $7; - $$= sym; - } - ; - -loop_while: WHILE expression ':' '{' procedure '}' - { - $$ = NULL; - } - ; - -expression: expr - ; - -procedure: statement_block - { - $$ = VEC_pop( gpy_sym, gpy_symbol_stack ); - } - ; - -statement_block: statement_block decl - { - $1->next = $2; - $$ = $2; - } - | decl - { - VEC_safe_push( gpy_sym, gc, - gpy_symbol_stack, $1 ); - $$ = $1; - } - ; - -expr: symbol_accessor '=' expr - { - gpy_symbol_obj* sym; - Gpy_Symbol_Init( sym ); - - sym->exp= OP_EXPRESS; - sym->type= OP_ASSIGN_EVAL; - sym->op_a_t= TYPE_SYMBOL; - sym->op_b_t= TYPE_SYMBOL; - - sym->op_a.symbol_table= $1; - sym->op_b.symbol_table= $3; - $$= sym; - - debug("accessor = expr!\n"); - } - | expr '+' expr - { - gpy_symbol_obj* sym; - Gpy_Symbol_Init( sym ); - - sym->exp= OP_EXPRESS; - sym->type= OP_BIN_ADDITION; - sym->op_a_t= TYPE_SYMBOL; - sym->op_b_t= TYPE_SYMBOL; - - sym->op_a.symbol_table= $1; - sym->op_b.symbol_table= $3; - $$= sym; - debug("expr + expr!\n"); - } - | expr '-' expr - { - gpy_symbol_obj* sym; - Gpy_Symbol_Init( sym ); - - sym->exp= OP_EXPRESS; - sym->type= OP_BIN_SUBTRACTION; - sym->op_a_t= TYPE_SYMBOL; - sym->op_b_t= TYPE_SYMBOL; - - sym->op_a.symbol_table= $1; - sym->op_b.symbol_table= $3; - $$= sym; - } - | expr '*' expr - { - gpy_symbol_obj* sym; - Gpy_Symbol_Init( sym ); - - sym->exp= OP_EXPRESS; - sym->type= OP_BIN_MULTIPLY; - sym->op_a_t= TYPE_SYMBOL; - sym->op_b_t= TYPE_SYMBOL; - - sym->op_a.symbol_table= $1; - sym->op_b.symbol_table= $3; - $$= sym; - } - | expr '/' expr - { - gpy_symbol_obj* sym; - Gpy_Symbol_Init( sym ); - - sym->exp= OP_EXPRESS; - sym->type= OP_BIN_DIVIDE; - sym->op_a_t= TYPE_SYMBOL; - sym->op_b_t= TYPE_SYMBOL; - - sym->op_a.symbol_table= $1; - sym->op_b.symbol_table= $3; - $$= sym; - } - | expr EQUAL expr - | expr NOT_EQUAL expr - | expr LESS expr - | expr LESS_EQUAL expr - | expr GREATER expr - | expr GREATER_EQUAL expr - | expr AND expr - | expr OR expr - | '(' expr ')' - { - $$ = $2; - } - | primary - ; - -symbol_accessor: IDENTIFIER - { - gpy_symbol_obj * sym; - Gpy_Symbol_Init( sym ); - - sym->type= SYMBOL_REFERENCE; - sym->op_a_t= TYPE_STRING; - - sym->op_a.string= $1; - $$= sym; - } - ; - -accessor: symbol_accessor - | arbitrary_call - ; - -arbitrary_call: IDENTIFIER '(' arguments ')' - { - gpy_symbol_obj *sym= NULL; - Gpy_Symbol_Init( sym ); - - sym->exp = OP_EXPRESS; - sym->type= OP_CALL_GOTO; - - sym->op_a_t= TYPE_STRING; - sym->op_b_t= TYPE_ARGUMENTS; - - sym->op_a.string= $1; - sym->op_b.symbol_table= $3; - $$= sym; - } - | IDENTIFIER '(' ')' - { - gpy_symbol_obj *sym = NULL; - Gpy_Symbol_Init( sym ); - - sym->exp = OP_EXPRESS; - sym->type = OP_CALL_GOTO; - - sym->op_a_t = TYPE_STRING; - sym->op_a.string = $1; - $$= sym; - } - ; - -parameter: IDENTIFIER - { - gpy_symbol_obj *sym; - Gpy_Symbol_Init( sym ); - - sym->type= TYPE_PARAMETER; - sym->op_a_t= TYPE_STRING; - - sym->op_a.string= $1; - $$= sym; - } - ; - -parameters: parameter_list - { - $$ = VEC_pop( gpy_sym, gpy_symbol_stack ); - } - ; - -parameter_list: parameter_list ',' parameter - { - $1->next = $3; - $$ = $3; - } - | parameter - { - VEC_safe_push( gpy_sym, gc, - gpy_symbol_stack, $1 ); - $$ = $1; - } - ; - -arguments: argument_list - { - $$ = VEC_pop( gpy_sym, gpy_symbol_stack ); - } - ; - -argument_list: argument_list ',' expression - { - $1->next = $3; - } - | expression - { - VEC_safe_push( gpy_sym, gc, - gpy_symbol_stack, $1 ); - $$ = $1; - } - ; - -list_symbol: '[' argument_list ']' - { - $$ = NULL; - } - ; - -primary: accessor - | list_symbol - | INTEGER - { - gpy_symbol_obj *sym; - Gpy_Symbol_Init( sym ); - - sym->type= SYMBOL_PRIMARY; - sym->op_a_t= TYPE_INTEGER; - - sym->op_a.integer= $1; - $$= sym; - } - | NONE - { - gpy_symbol_obj *sym; - Gpy_Symbol_Init( sym ); - $$= sym; - } - ; - -%% - -void yyerror( const char *msg ) -{ - error( "syntax error :: line %i:'%s'\n", - yylineno, msg ); -} +%{ +/* 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 "vec.h" + +#include "gpy.h" +#include "symbols.h" +#include "opcodes.def" +#include "line-map.h" + +#include +#include + +static VEC( gpy_sym,gc ) * gpy_symbol_stack; + +extern int yylineno; + +extern int yylex( void ); +extern void yyerror( const char * ); +%} + +%union { + char *string; + long int integer; + gpy_symbol_obj *symbol; +} + +%error-verbose + +%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 IF "if" +%token ELIF "elif" +%token ELSE "else" + +%token EQUAL "==" +%token NOT_EQUAL "!=" +%token LESS "<" +%token LESS_EQUAL "<=" +%token GREATER ">" +%token GREATER_EQUAL ">=" +%token OR "or" +%token AND "and" + +%token NEWLINE +%token INDENT +%token DEDENT + +%token NONE +%token IDENTIFIER +%token STRING +%token INTEGER + +%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 suite +%type suite_statement_list +%type indent_stmt + +%start declarations + +%left '-' '+' +%left '*' '/' +%left LESS LESS_EQUAL +%left GREATER GREATER_EQUAL +%left NOT_EQUAL EQUAL +%left AND OR +%right '^' '=' +%nonassoc UMINUS + +%% + +declarations: declarations statement + { + if( $2 ) + gpy_process_decl( $2 ); + } + | NEWLINE + ; + +compound_stmt: funcdef + ; + +funcdef: DEF IDENTIFIER "(" ")" ":" suite + { $$=NULL; } + ; + +suite: stmt_list NEWLINE + { $$=NULL; } + | NEWLINE suite_statement_list DEDENT + { $$=NULL; } + ; + +suite_statement_list: suite_statement_list indent_stmt + | indent_stmt + { $$=NULL; } + ; + +indent_stmt: INDENT statement + { $$=NULL; } + ; + +statement: stmt_list NEWLINE + | compound_stmt + ; + +stmt_list: stmt_list ";" simple_stmt + | simple_stmt + ; + +simple_stmt: assignment_stmt + ; + +expression_stmt: expression_list + ; + +assignment_stmt: target_list "=" expression_list + ; + +target_list: target_list "," target + | target + ; + +target: IDENTIFIER + { $$=NULL; } + ; + +expression_list: expression_list "," expression + | expression + ; + +expression: conditional_expression + ; + +conditional_expression: or_test ["if" or_test "else" expression] + +or_test: and_test + | or_test OR and_test + ; + +and_test: not_test + | and_test AND not_test + ; + +not_test: comparison + | NOT not_test + ; + +u_expr: power + | "-" u_expr + | "+" u_expr + ; + +m_expr: u_expr + | m_expr "*" u_expr + | m_expr "/" u_expr + ; + +a_expr: m_expr + | a_expr "+" m_expr + | a_expr "-" m_expr + ; + +shift_expr: a_expr + ; + +and_expr: shift_expr + | and_expr "\;SPMamp;" shift_expr + ; + +xor_expr: and_expr + | xor_expr "\textasciicircum" and_expr + ; + +or_expr: xor_expr + | or_expr "|" xor_expr + ; + +comparison_comp: comp_operator or_expr + ; + +comparison_list: comparison_list comparison_comp + | comparison_comp + ; + +comparison: or_expr + | or_expr comparison_list + ; + +comp_operator: "<" + | ">" + | "==" + | ">=" + | "<=" + ; +%% + +void yyerror( const char *msg ) +{ + error( "syntax error :: line %i:'%s'\n", + yylineno, msg ); +} -- 2.11.4.GIT