Branch: Tag:

1998-04-13

1998-04-13 12:51:09 by Henrik Grubbström (Grubba) <grubba@grubba.org>

Improved error handling.

Rev: src/language.yacc:1.74

171:   /* This is the grammar definition of Pike. */      #include "global.h" - RCSID("$Id: language.yacc,v 1.73 1998/04/10 23:23:08 grubba Exp $"); + RCSID("$Id: language.yacc,v 1.74 1998/04/13 12:51:09 grubba Exp $");   #ifdef HAVE_MEMORY_H   #include <memory.h>   #endif
195:   #define YYMAXDEPTH 1000      #ifdef DEBUG + #ifndef YYDEBUG + /* May also be defined by machine.h */   #define YYDEBUG 1 -  + #endif /* YYDEBUG */   #endif      
285:   %type <number> modifier   %type <number> modifier_list   %type <number> modifiers + %type <number> opt_string_type   %type <number> optional_dot_dot_dot   %type <number> optional_stars    - /* The following symbos return type information */ + /* The following symbols return type information */      %type <n> cast   %type <n> simple_type
355:   %type <n> low_program_ref   %%    - all: program; + all: program +  ;      program: program def optional_semi_colon -  +  | error { yyerrok; }    | /* empty */    ;   
380:    ;      optional_rename_inherit: ':' F_IDENTIFIER { $$=$2; } +  | ':' bad_identifier { $$=0; }    | { $$=0; }    ;   
427:    pop_n_elems(1);    free_node($3);    } +  | modifiers F_INHERIT low_program_ref error ';' +  { +  free_node($3); yyerrok; +  } +  | modifiers F_INHERIT error ';' { yyerrok; }    ;      import: modifiers F_IMPORT idents ';'
436:    use_module(sp-1);    pop_stack();    } +  | modifiers F_IMPORT error ';' { yyerrok; }    ;      constant_name: F_IDENTIFIER '=' expr0
467:    if($3) free_node($3);    free_node($1);    } +  | bad_identifier '=' expr0 { if ($3) free_node($3); }    ;      constant_list: constant_name
474:    ;      constant: modifiers F_CONSTANT constant_list ';' {} +  | modifiers F_CONSTANT error ';' { yyerrok; }    ;      block_or_semi: block
500:    if(!compiler_frame->previous ||    !compiler_frame->previous->current_type)    { -  yyerror("Internal compiler fault"); +  yyerror("Internal compiler fault.");    copy_shared_string(compiler_frame->current_type,    mixed_type_string);    }else{
564:    if(!compiler_frame->variable[e].name ||    !compiler_frame->variable[e].name->len)    { -  my_yyerror("Missing name for argument %d",e); +  my_yyerror("Missing name for argument %d.",e);    }    }   
578:    free_node($4);    free_node($<n>9);    } +  | modifiers type_or_error optional_stars bad_identifier +  '(' arguments ')' block_or_semi +  { +  free_string(pop_type()); +  }    | modifiers type_or_error name_list ';' {}    | inheritance {}    | import {}    | constant {}    | class { free_node($1); } -  | error ';' { yyerrok; } +  | error ';'    {    reset_type_stack(); -  +  yyerrok;   /* if(num_parse_error>5) YYACCEPT; */    }    ;
595:    ;      optional_identifier: F_IDENTIFIER +  | bad_identifier { $$=0 }    | /* empty */ { $$=0; }    ;   
726:      type3: F_INT_ID { push_type(T_INT); }    | F_FLOAT_ID { push_type(T_FLOAT); } -  | F_STRING_ID { push_type(T_STRING); } +     | F_PROGRAM_ID { push_type(T_PROGRAM); }    | F_VOID_ID { push_type(T_VOID); }    | F_MIXED_ID { push_type(T_MIXED); } -  +  | F_STRING_ID opt_string_type { push_type(T_STRING); }    | F_OBJECT_ID opt_object_type { push_type(T_OBJECT); }    | F_MAPPING_ID opt_mapping_type { push_type(T_MAPPING); }    | F_ARRAY_ID opt_array_type { push_type(T_ARRAY); }
737:    | F_FUNCTION_ID opt_function_type { push_type(T_FUNCTION); }    ;    + opt_string_type: /* Empty */ { $$=1; } +  | '(' F_NUMBER ')' +  { +  if ($2 != 1) yyerror("Wide strings are not supported."); +  $$=1; +  } +    opt_object_type: /* Empty */ { push_type_int(0); push_type(0); }    | '(' program_ref ')'    {
745:    {    push_type_int(p->id);    }else{ -  yyerror("Not a valid program specifier"); +  yyerror("Not a valid program specifier.");    push_type_int(0);    }    pop_n_elems(2);
840:    free_string(type);    free_node($2);    } +  | optional_stars bad_identifier {}    | optional_stars F_IDENTIFIER '='    {    struct pike_string *type;
857:    mkidentifiernode($<number>4))));    free_node($2);    } +  | optional_stars bad_identifier '=' expr0 +  { +  free_node($4); +  }    ;      
868:    $$=mknode(F_ASSIGN,mkintnode(0),mklocalnode(islocal($2->u.sval.u.string)));    free_node($2);    } +  | optional_stars bad_identifier {}    | optional_stars F_IDENTIFIER '=' expr0    {    push_finished_type($<n>0->u.sval.u.string);
876:    $$=mknode(F_ASSIGN,$4,mklocalnode(islocal($2->u.sval.u.string)));    free_node($2);    } +  | optional_stars bad_identifier '=' expr0 +  { +  free_node($4); +  } +  | optional_stars F_IDENTIFIER '=' error +  { +  free_node($2); +  /* No yyerok here since we aren't done yet. */ +  }    ;      new_local_name2: F_IDENTIFIER
884:    $$=mknode(F_ASSIGN,mkintnode(0),mklocalnode(islocal($1->u.sval.u.string)));    free_node($1);    } +  | bad_identifier { $$=mkintnode(0); }    | F_IDENTIFIER '=' 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; +  }    ;      
905:    ;      failsafe_block: block -  | error { $$=0; } +  | error { $$=0; yyerrok }    ;      
1026:    free_string(s);    $1|=ID_PRIVATE | ID_INLINE;    } +  /* fprintf(stderr, "LANGUAGE.YACC: CLASS start\n"); */    if(compiler_pass==1)    {    low_start_new_program(0, $3->u.sval.u.string, $1);
1066:    else    p=end_program();    +  /* fprintf(stderr, "LANGUAGE.YACC: CLASS end\n"); */ +     $$=mkidentifiernode(isidentifier($3->u.sval.u.string));       if(!p)
1075:       free_node($3);    check_tree($$,0); -  +     }    ;   
1214:      expr0: expr01    | expr4 '=' expr0 { $$=mknode(F_ASSIGN,$3,$1); } +  | expr4 '=' error { $$=$1; reset_type_stack(); yyerrok; }    | '[' low_lvalue_list ']' '=' expr0 { $$=mknode(F_ASSIGN,$5,mknode(F_ARRAY_LVALUE,$2,0)); }    | expr4 assign expr0 { $$=mknode($2,$1,$3); } -  | '[' low_lvalue_list ']' assign expr0 { $$=mknode(F_ASSIGN,mknode(F_ARRAY_LVALUE,$2,0),$5); } -  | error assign expr01 { $$=0; reset_type_stack(); yyerrok; } +  | expr4 assign error { $$=$1; reset_type_stack(); yyerrok; } +  | '[' low_lvalue_list ']' assign expr0 { $$=mknode($4,mknode(F_ARRAY_LVALUE,$2,0),$5); } +  | '[' low_lvalue_list error ']' { $$=$2; reset_type_stack(); yyerrok; } + /* | error { $$=0; reset_type_stack(); } */    ;      expr01: expr1 { $$ = $1; }
1307:    | class    | idents    | expr4 '(' expr_list ')' { $$=mkapplynode($1,$3); } +  | expr4 '(' error ')' { $$=mkapplynode($1, NULL); yyerrok; }    | expr4 '[' expr0 ']' { $$=mknode(F_INDEX,$1,$3); }    | expr4 '[' comma_expr_or_zero F_DOT_DOT comma_expr_or_maxint ']'    {    $$=mknode(F_RANGE,$1,mknode(F_ARG_LIST,$3,$5));    } -  +  | expr4 '[' error ']' { $$=$1; yyerrok; }    | '(' comma_expr2 ')' { $$=$2; }    | '(' '{' expr_list '}' ')'    { $$=mkefuncallnode("aggregate",$3); }
1319:    { $$=mkefuncallnode("aggregate_mapping",$3); };    | F_MULTISET_START expr_list F_MULTISET_END    { $$=mkefuncallnode("aggregate_multiset",$2); } +  | '(' error ')' { yyerrok; }    | expr4 F_ARROW F_IDENTIFIER    {    $$=mknode(F_ARROW,$1,$3);    } -  +  | expr4 F_ARROW bad_identifier {}    ;      idents: low_idents
1334:    copy_shared_string(last_identifier, $3->u.sval.u.string);    free_node($3);    } +  | idents '.' bad_identifier {}    ;      low_idents: F_IDENTIFIER
1356:    DECLARE_CYCLIC();    if(BEGIN_CYCLIC(last_identifier, lex.current_file))    { -  my_yyerror("Recursive module dependency in %s",last_identifier->str); +  my_yyerror("Recursive module dependency in %s.", +  last_identifier->str);    }else{    SET_CYCLIC_RET(1);    ref_push_string(last_identifier);
1410:    free_node(tmp2);    free_node($3);    } +  | F_PREDEF F_COLON_COLON bad_identifier +  { +  $$=mkintnode(0); +  }    | F_IDENTIFIER F_COLON_COLON F_IDENTIFIER    {    $$=reference_inherited_identifier($1->u.sval.u.string,
1425:    free_node($1);    free_node($3);    } +  | F_IDENTIFIER F_COLON_COLON bad_identifier +  { +  $$=$1; +  }    | F_COLON_COLON F_IDENTIFIER    {    int e,i;
1450:    }    free_node($2);    } +  | F_COLON_COLON bad_identifier +  { +  $$=mkintnode(0); +  }    ;      comma_expr_or_zero: /* empty */ { $$=mkintnode(0); }
1493:    } ;      catch_arg: '(' comma_expr ')' { $$=$2; } +  | '(' error ')' { $$=mkintnode(0); yyerrok; }    | block    ;   
1543:    }    ;    + /* +  * Some error-handling +  */ +  + bad_identifier : bad_def_identifier +  | F_INLINE +  { yyerror("inline is a reserved word."); } +  | F_LOCAL +  { yyerror("local is a reserved word."); } +  | F_NO_MASK +  { yyerror("nomask is a reserved word."); } +  | F_PREDEF +  { yyerror("predef is a reserved word."); } +  | F_PRIVATE +  { yyerror("private is a reserved word."); } +  | F_PROTECTED +  { yyerror("protected is a reserved word."); } +  | F_PUBLIC +  { yyerror("public is a reserved word."); } +  | F_STATIC +  { yyerror("static is a reserved word."); } +  | F_ARRAY_ID +  { yyerror("array is a reserved word."); } +  | F_FLOAT_ID +  { yyerror("float is a reserved word.");} +  | F_INT_ID +  { yyerror("int is a reserved word."); } +  | F_MAPPING_ID +  { yyerror("mapping is a reserved word."); } +  | F_MULTISET_ID +  { yyerror("multiset is a reserved word."); } +  | F_STRING_ID +  { yyerror("string is a reserved word."); } +  | F_VOID_ID +  { yyerror("void is a reserved word."); } +  ; +  + bad_def_identifier +  : F_DO +  { yyerror("do is a reserved word."); } +  | F_ELSE +  { yyerror("else is a reserved word."); } +  | F_RETURN +  { yyerror("return is a reserved word."); } +  | F_CONSTANT +  { yyerror("constant is a reserved word."); } +  | F_IMPORT +  { yyerror("import is a reserved word."); } +  | F_INHERIT +  { yyerror("inherit is a reserved word."); } +  | F_CLASS +  { yyerror("class is a reserved word."); } +  | F_CATCH +  { yyerror("catch is a reserved word."); } +  | F_GAUGE +  { yyerror("gauge is a reserved word."); } +  | F_LAMBDA +  { yyerror("lambda is a reserved word."); } +  | F_SSCANF +  { yyerror("sscanf is a reserved word."); } +  | F_SIZEOF +  { yyerror("sizeof is a reserved word."); } +  | F_SWITCH +  { yyerror("switch is a reserved word."); } +  | F_TYPEOF +  { yyerror("typeof is a reserved word."); } +  | F_BREAK +  { yyerror("break is a reserved word."); } +  | F_CASE +  { yyerror("case is a reserved word."); } +  | F_CONTINUE +  { yyerror("continue is a reserved word."); } +  | F_DEFAULT +  { yyerror("default is a reserved word."); } +  | F_FOR +  { yyerror("for is a reserved word."); } +  | F_FOREACH +  { yyerror("foreach is a reserved word."); } +  | F_IF +  { yyerror("if is a reserved word."); } +  ; +  +  +    %%      void yyerror(char *str)
1555:    fatal("Stack error (underflow)\n");   #endif    -  if (num_parse_error > 5) return; +  if (num_parse_error > 10) return;    num_parse_error++;    cumulative_parse_error++;   
1582:    reference_shared_string(str);    if (compiler_frame->current_number_of_locals == MAX_LOCAL)    { -  yyerror("Too many local variables"); +  yyerror("Too many local variables.");    }else {    compiler_frame->variable[compiler_frame->current_number_of_locals].type = type;    compiler_frame->variable[compiler_frame->current_number_of_locals].name = str;