diff --git a/src/language.yacc b/src/language.yacc index 7c3718dbe121179b4fbb5c1ae1c227169bf7bf79..f4453374ed07ea55c7565cef217a1a6afffa162c 100644 --- a/src/language.yacc +++ b/src/language.yacc @@ -171,7 +171,7 @@ /* This is the grammar definition of Pike. */ #include "global.h" -RCSID("$Id: language.yacc,v 1.76 1998/04/14 19:17:43 grubba Exp $"); +RCSID("$Id: language.yacc,v 1.77 1998/04/15 00:54:18 grubba Exp $"); #ifdef HAVE_MEMORY_H #include <memory.h> #endif @@ -322,6 +322,7 @@ int yylex(YYSTYPE *yylval); %type <n> continue %type <n> default %type <n> do +%type <n> safe_expr0 %type <n> expr00 %type <n> expr01 %type <n> expr1 @@ -339,6 +340,7 @@ int yylex(YYSTYPE *yylval); %type <n> local_name_list %type <n> local_name_list2 %type <n> low_idents +%type <n> safe_lvalue %type <n> lvalue %type <n> lvalue_list %type <n> low_lvalue_list @@ -453,7 +455,7 @@ import: modifiers F_IMPORT idents ';' | modifiers F_IMPORT error ';' { yyerrok; } ; -constant_name: F_IDENTIFIER '=' expr0 +constant_name: F_IDENTIFIER '=' safe_expr0 { int tmp; /* This can be made more lenient in the future */ @@ -482,8 +484,8 @@ constant_name: F_IDENTIFIER '=' expr0 if($3) free_node($3); free_node($1); } - | bad_identifier '=' expr0 { if ($3) free_node($3); } - | error '=' expr0 { if ($3) free_node($3); } + | bad_identifier '=' safe_expr0 { if ($3) free_node($3); } + | error '=' safe_expr0 { if ($3) free_node($3); } ; constant_list: constant_name @@ -616,9 +618,8 @@ def: modifiers type_or_error optional_stars F_IDENTIFIER { YYSTYPE foo; foo.number = 0; - YYBACKUP('}', foo); reset_type_stack(); - yyerrok; + YYBACKUP('}', foo); } ; @@ -944,21 +945,13 @@ new_local_name2: F_IDENTIFIER free_node($1); } | bad_identifier { $$=mkintnode(0); } - | F_IDENTIFIER '=' expr0 + | F_IDENTIFIER '=' safe_expr0 { add_local_name($1->u.sval.u.string, $<n>0->u.sval.u.string); $$=mknode(F_ASSIGN,$3, mklocalnode(islocal($1->u.sval.u.string))); free_node($1); } - | bad_identifier '=' expr0 { $$=$3; } - | F_IDENTIFIER '=' error - { - /* Just ignore the assignment */ - add_local_name($1->u.sval.u.string, $<n>0->u.sval.u.string); - $$=mknode(F_ASSIGN,mkintnode(0),mklocalnode(islocal($1->u.sval.u.string))); - free_node($1); - yyerrok; - } + | bad_identifier '=' safe_expr0 { $$=$3; } ; @@ -1011,9 +1004,9 @@ statement: unused2 ';' { $$=$1; } { YYSTYPE foo; foo.number = 0; - YYBACKUP('}', foo); reset_type_stack(); - yyerrok; + yyerror("Missing ';'."); + YYBACKUP('}', foo); } | ';' { $$=0; } ; @@ -1182,14 +1175,28 @@ optional_else_part: { $$=0; } | F_ELSE statement { $$=$2; } ; +safe_lvalue: lvalue + | error { $$=0 } + ; + +safe_expr0: expr0 + | error { $$=mkintnode(0); } + ; + foreach: F_FOREACH { $<number>$=compiler_frame->current_number_of_locals; } - '(' expr0 ',' lvalue ')' statement + '(' safe_expr0 ',' safe_lvalue ')' statement { - $$=mknode(F_FOREACH, mknode(F_VAL_LVAL,$4,$6),$8); - $$->line_number=$1; + if ($6) { + $$=mknode(F_FOREACH, mknode(F_VAL_LVAL,$4,$6),$8); + $$->line_number=$1; + } else { + /* Error in lvalue */ + free_node($4); + $$=$8; + } pop_local_variables($<number>2); } ; @@ -1344,10 +1351,24 @@ m_expr_list: { $$=0; } ; m_expr_list2: assoc_pair - | m_expr_list2 ',' assoc_pair { $$=mknode(F_ARG_LIST,$1,$3); } + | m_expr_list2 ',' assoc_pair + { + if ($3) { + $$=mknode(F_ARG_LIST,$1,$3); + } else { + /* Error in assoc_pair */ + $$=$1; + } + } + | m_expr_list2 ',' error + { + $$=$1; + } ; -assoc_pair: expr0 ':' expr1 { $$=mknode(F_ARG_LIST,$1,$3); } ; +assoc_pair: expr0 ':' expr1 { $$=mknode(F_ARG_LIST,$1,$3); } + | expr0 ':' error { free_node($1); $$=0; } + ; expr1: expr2 | expr1 F_LOR expr1 { $$=mknode(F_LOR,$1,$3); } @@ -1368,6 +1389,24 @@ expr1: expr2 | expr1 '*' expr1 { $$=mkopernode("`*",$1,$3); } | expr1 '%' expr1 { $$=mkopernode("`%",$1,$3); } | expr1 '/' expr1 { $$=mkopernode("`/",$1,$3); } + | expr1 F_LOR error { $$=$1; } + | expr1 F_LAND error { $$=$1; } + | expr1 '|' error { $$=$1; } + | expr1 '^' error { $$=$1; } + | expr1 '&' error { $$=$1; } + | expr1 F_EQ error { $$=$1; } + | expr1 F_NE error { $$=$1; } + | expr1 '>' error { $$=$1; } + | expr1 F_GE error { $$=$1; } + | expr1 '<' error { $$=$1; } + | expr1 F_LE error { $$=$1; } + | expr1 F_LSH error { $$=$1; } + | expr1 F_RSH error { $$=$1; } + | expr1 '+' error { $$=$1; } + | expr1 '-' error { $$=$1; } + | expr1 '*' error { $$=$1; } + | expr1 '%' error { $$=$1; } + | expr1 '/' error { $$=$1; } ; expr2: expr3 @@ -1682,7 +1721,7 @@ string: F_STRING */ bad_identifier: - F_INLINE + F_INLINE { yyerror("inline is a reserved word."); } | F_LOCAL { yyerror("local is a reserved word."); }