📄 parse.c
字号:
parse_modulion (label) tree label;{ tree module_name; label = set_module_name (label); module_name = push_module (label, 0); FORWARD_TOKEN(); push_action (); parse_body(); expect(END, "expected END here"); parse_opt_handler (); parse_opt_end_label_semi_colon (label); find_granted_decls (); pop_module ();}static voidparse_spec_module (label) tree label;{ int save_ignoring = ignoring; push_module (set_module_name (label), 1); ignoring = pass == 2; FORWARD_TOKEN(); /* SKIP SPEC */ expect (MODULE, "expected 'MODULE' here"); while (parse_definition (1)) { } if (parse_action ()) error ("action not allowed in SPEC MODULE"); expect(END, "expected END here"); parse_opt_end_label_semi_colon (label); find_granted_decls (); pop_module (); ignoring = save_ignoring;}/* Matches: <name_string> ( "," <name_string> )* Returns either a single IDENTIFIER_NODE, or a chain (TREE_LIST) of IDENTIFIER_NODES. (Since a single identifier is the common case, we avoid wasting space (twice, once for each pass) with extra TREE_LIST nodes in that case.) (Will not return NULL_TREE even if ignoring is true.) */static treeparse_defining_occurrence_list (){ tree chain = NULL_TREE; tree name = parse_defining_occurrence (); if (name == NULL_TREE) { error("missing defining occurrence"); return NULL_TREE; } if (! check_token (COMMA)) return name; chain = build_tree_list (NULL_TREE, name); for (;;) { name = parse_defining_occurrence (); if (name == NULL) { error ("bad defining occurrence following ','"); break; } chain = tree_cons (NULL_TREE, name, chain); if (! check_token (COMMA)) break; } return nreverse (chain);}static voidparse_mode_definition (is_newmode) int is_newmode;{ tree mode, names; int save_ignoring = ignoring; ignoring = pass == 2; names = parse_defining_occurrence_list (); expect (EQL, "missing '=' in mode definition"); mode = parse_mode (); if (names == NULL_TREE || TREE_CODE (names) == TREE_LIST) { for ( ; names != NULL_TREE; names = TREE_CHAIN (names)) push_modedef (names, mode, is_newmode); } else push_modedef (names, mode, is_newmode); ignoring = save_ignoring;}voidparse_mode_definition_statement (is_newmode) int is_newmode;{ FORWARD_TOKEN (); /* skip SYNMODE or NEWMODE */ parse_mode_definition (is_newmode); while (PEEK_TOKEN () == COMMA) { FORWARD_TOKEN (); parse_mode_definition (is_newmode); } parse_semi_colon ();}static voidparse_synonym_definition (){ tree expr = NULL_TREE; tree names = parse_defining_occurrence_list (); tree mode = parse_opt_mode (); if (! expect (EQL, "missing '=' in synonym definition")) mode = error_mark_node; else { if (mode) expr = parse_untyped_expr (); else expr = parse_expression (); } if (names == NULL_TREE || TREE_CODE (names) == TREE_LIST) { for ( ; names != NULL_TREE; names = TREE_CHAIN (names)) push_syndecl (names, mode, expr); } else push_syndecl (names, mode, expr);}static voidparse_synonym_definition_statement(){ int save_ignoring= ignoring; ignoring = pass == 2; require (SYN); parse_synonym_definition (); while (PEEK_TOKEN () == COMMA) { FORWARD_TOKEN (); parse_synonym_definition (); } ignoring = save_ignoring; parse_semi_colon ();}/* Attempts to match: "(" <exception list> ")" ":". Return NULL_TREE on failure, and non-NULL on success. On success, if pass 1, return a TREE_LIST of IDENTIFIER_NODEs. */static treeparse_on_exception_list (){ tree name; tree list = NULL_TREE; int tok1 = PEEK_TOKEN (); int tok2 = PEEK_TOKEN1 (); /* This requires a lot of look-ahead, because we cannot easily a priori distinguish an exception-list from an expression. */ if (tok1 != LPRN || tok2 != NAME) { if (tok1 == NAME && tok2 == COLON && pass == 1) error ("missing '(' in exception list"); return 0; } require (LPRN); name = parse_name_string (); if (PEEK_TOKEN () == RPRN && PEEK_TOKEN1 () == COLON) { /* Matched: '(' <name_string> ')' ':' */ FORWARD_TOKEN (); FORWARD_TOKEN (); return pass == 1 ? build_tree_list (NULL_TREE, name) : name; } if (PEEK_TOKEN() == COMMA) { if (pass == 1) list = build_tree_list (NULL_TREE, name); while (check_token (COMMA)) { tree old_names = list; name = parse_name_string (); if (pass == 1) { for ( ; old_names != NULL_TREE; old_names = TREE_CHAIN (old_names)) { if (TREE_VALUE (old_names) == name) { error ("ON exception names must be unique"); goto continue_parsing; } } list = tree_cons (NULL_TREE, name, list); continue_parsing: ; } } if (! check_token (RPRN) || ! check_token(COLON)) error ("syntax error in exception list"); return pass == 1 ? nreverse (list) : name; } /* Matched: '(' name_string but it doesn't match the syntax of an exception list. It could be the beginning of an expression, so back up. */ pushback_token (NAME, name); pushback_token (LPRN, 0); return NULL_TREE;}static voidparse_on_alternatives (){ for (;;) { tree except_list = parse_on_exception_list (); if (except_list != NULL) chill_handle_on_labels (except_list); else if (parse_action ()) expand_exit_needed = 1; else break; }}static treeparse_opt_handler (){ if (! check_token (ON)) { POP_UNUSED_ON_CONTEXT; return NULL_TREE; } if (check_token (END)) { pedwarn ("empty ON-condition"); POP_UNUSED_ON_CONTEXT; return NULL_TREE; } if (! ignoring) { chill_start_on (); expand_exit_needed = 0; } if (PEEK_TOKEN () != ELSE) { parse_on_alternatives (); if (! ignoring && expand_exit_needed) expand_exit_something (); } if (check_token (ELSE)) { chill_start_default_handler (); label = NULL_TREE; parse_opt_actions (); if (! ignoring) { emit_line_note (input_filename, lineno); expand_exit_something (); } } expect (END, "missing 'END' after"); if (! ignoring) chill_finish_on (); POP_USED_ON_CONTEXT; return integer_zero_node; }static voidparse_loc_declaration (in_spec_module) int in_spec_module;{ tree names = parse_defining_occurrence_list (); int save_ignoring = ignoring; int is_static, lifetime_bound; tree mode, init_value = NULL_TREE; int loc_decl = 0; ignoring = pass == 2; mode = parse_mode (); ignoring = save_ignoring; is_static = check_token (STATIC); if (check_token (BASED)) { expect(LPRN, "BASED must be followed by (NAME)"); do_based_decls (names, mode, parse_name_string ()); expect(RPRN, "BASED must be followed by (NAME)"); return; } if (check_token (LOC)) { /* loc-identity declaration */ if (pass == 1) mode = build_chill_reference_type (mode); loc_decl = 1; } lifetime_bound = check_token (INIT); if (lifetime_bound && loc_decl) { if (pass == 1) error ("INIT not allowed at loc-identity declaration"); lifetime_bound = 0; } if (PEEK_TOKEN () == ASGN || PEEK_TOKEN() == EQL) { save_ignoring = ignoring; ignoring = pass == 1; if (PEEK_TOKEN() == EQL) { if (pass == 1) error ("'=' used where ':=' is required"); } FORWARD_TOKEN(); if (! lifetime_bound) push_handler (); init_value = parse_untyped_expr (); if (in_spec_module) { error ("initialization is not allowed in spec module"); init_value = NULL_TREE; } if (! lifetime_bound) parse_opt_handler (); ignoring = save_ignoring; } if (init_value == NULL_TREE && loc_decl && pass == 1) error ("loc-identity declaration without initialisation"); do_decls (names, mode, is_static || global_bindings_p () /* the variable becomes STATIC if all_static_flag is set and current functions doesn't have the RECURSIVE attribute */ || (all_static_flag && !CH_DECL_RECURSIVE (current_function_decl)), lifetime_bound, init_value, in_spec_module); /* Free any temporaries we made while initializing the decl. */ free_temp_slots ();}static voidparse_declaration_statement (in_spec_module) int in_spec_module;{ int save_ignoring = ignoring; ignoring = pass == 2; require (DCL); parse_loc_declaration (in_spec_module); while (PEEK_TOKEN () == COMMA) { FORWARD_TOKEN (); parse_loc_declaration (in_spec_module); } ignoring = save_ignoring; parse_semi_colon ();}treeparse_optforbid (){ if (check_token (FORBID) == 0) return NULL_TREE; if (check_token (ALL)) return ignoring ? NULL_TREE : build_int_2 (-1, -1);#if 0 if (check_token (LPRN)) { tree list = parse_forbidlist (); expect (RPRN, "missing ')' after FORBID list"); return list; }#endif error ("bad syntax following FORBID"); return NULL_TREE;}/* Matches: <grant postfix> or <seize postfix> Returns: A (singleton) TREE_LIST. */treeparse_postfix (grant_or_seize) enum terminal grant_or_seize;{ tree name = parse_opt_name_string (1); tree forbid = NULL_TREE; if (name == NULL_TREE) { error ("expected a postfix name here"); name = error_mark_node; } if (grant_or_seize == GRANT) forbid = parse_optforbid (); return build_tree_list (forbid, name);}treeparse_postfix_list (grant_or_seize) enum terminal grant_or_seize;{ tree list = parse_postfix (grant_or_seize); while (check_token (COMMA)) list = chainon (list, parse_postfix (grant_or_seize)); return list;}voidparse_rename_clauses (grant_or_seize) enum terminal grant_or_seize;{ for (;;) { tree rename_old_prefix, rename_new_prefix, postfix; require (LPRN); rename_old_prefix = parse_opt_name_string (0); expect (ARROW, "missing '->' in rename clause"); rename_new_prefix = parse_opt_name_string (0); expect (RPRN, "missing ')' in rename clause"); expect ('!', "missing '!' in rename clause"); postfix = parse_postfix (grant_or_seize); if (grant_or_seize == GRANT) chill_grant (rename_old_prefix, rename_new_prefix, TREE_VALUE (postfix), TREE_PURPOSE (postfix)); else chill_seize (rename_old_prefix, rename_new_prefix, TREE_VALUE (postfix)); if (PEEK_TOKEN () != COMMA) break; FORWARD_TOKEN (); if (PEEK_TOKEN () != LPRN) { error ("expected another rename clause"); break; } }}static treeparse_opt_prefix_clause (){ if (check_token (PREFIXED) == 0) return NULL_TREE; return build_prefix_clause (parse_opt_name_string (0));}voidparse_grant_statement (){ require (GRANT); if (PEEK_TOKEN () == LPRN) parse_rename_clauses (GRANT); else { tree window = parse_postfix_list (GRANT); tree new_prefix = parse_opt_prefix_clause (); tree t; for (t = window; t; t = TREE_CHAIN (t)) chill_grant (NULL_TREE, new_prefix, TREE_VALUE (t), TREE_PURPOSE (t)); }}voidparse_seize_statement (){ require (SEIZE); if (PEEK_TOKEN () == LPRN) parse_rename_clauses (SEIZE); else { tree seize_window = parse_postfix_list (SEIZE); tree old_prefix = parse_opt_prefix_clause (); tree t; for (t = seize_window; t; t = TREE_CHAIN (t)) chill_seize (old_prefix, NULL_TREE, TREE_VALUE (t)); }}/* In pass 1, this returns a TREE_LIST, one node for each parameter. In pass 2, we get a list of PARM_DECLs chained together. In either case, the list is in reverse order. */static treeparse_param_name_list (){ tree list = NULL_TREE; do { tree new_link; tree name = parse_defining_occurrence (); if (name == NULL_TREE) { error ("syntax error in parameter name list"); return list; } if (pass == 1) new_link = build_tree_list (NULL_TREE, name); /* else if (current_module->is_spec_module) ; nothing */ else /* pass == 2 */ { new_link = make_node (PARM_DECL); DECL_NAME (new_link) = name; DECL_ASSEMBLER_NAME (new_link) = name; } TREE_CHAIN (new_link) = list; list = new_link; } while (check_token (COMMA)); return list;}static treeparse_param_attr (){ tree attr; switch (PEEK_TOKEN ()) { case PARAMATTR: /* INOUT is returned here */ attr = PEEK_TREE (); FORWARD_TOKEN (); return attr; case IN: FORWARD_TOKEN (); return ridpointers[(int) RID_IN]; case LOC: FORWARD_TOKEN (); return ridpointers[(int) RID_LOC];#if 0 case DYNAMIC: FORWARD_TOKEN (); return ridpointers[(int) RID_DYNAMIC];#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -