📄 parser.y
字号:
/*Copyright (c) 2000, Red Hat, Inc.This file is part of Source-Navigator.Source-Navigator is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public License as publishedby the Free Software Foundation; either version 2, or (at your option)any later version.Source-Navigator is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNUGeneral Public License for more details.You should have received a copy of the GNU General Public License alongwith Source-Navigator; see the file COPYING. If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330, Boston,MA 02111-1307, USA.*//* * parse.y * * Copyright (C) 1998 Cygnus Solutions * * Description: * A GNU Bison grammar for the CHILL programming language. * * Almost directly translated from Per Bothner's two-pass recursive descent * parser that forms GNU CHILL. */%{#include <assert.h>#include <stdlib.h>#include <string.h>#include <tcl.h>#include "common.h"#include "symtab.h"#include "emit.h"static char brackets[] = "()";/* Should we emit information about procedure calls and variables when encountered inside an expr? This will mostly be set to 1, but there are some situations when this should be set to 0. */static int emit = 0;%}%union { struct punctuation punct; struct blockregion block; struct identifier id; struct identifierlist * idlist; struct kword keyword; struct datatype type; struct attribute attrib; struct sig signature;}%token <punct> ';'%token <attrib> DYNAMIC IN OUT INOUT LOC%token <type> ACCESS ARRAY BIN BOOLS BUFFER CHARS EVENT POWERSET RANGE READ REF ROW%token <type> SET STRUCT TEXT%token <keyword> MODULE REGION SPEC END%token AFTER ALL AND ANDIF ASSERT AT%token BASED BEG BODY BY%token CASE CAUSE CONTEXT CONTINUE CYCLE%token DCL DELAY DO DOWN %token ELSE ELSIF ESAC EVER EXCEPTIONS EXIT%token FI FOR FORBID%token GENERAL GOTO GRANT%token IF INIT INLINE %token MOD %token NEWMODE NONREF NOPACK NOT%token OD OF ON OR ORIF%token PACK POS PREFIXED PRIORITY PROC PROCESS%token RECEIVE RECURSIVE REM REMOTE RESULT RETURN RETURNS %token SEIZE SEND SIGNAL SIMPLE START STATIC STEP STOP SYN SYNMODE%token THEN THIS TIMEOUT TO%token UP%token VARYING%token WHILE WITH%token XOR%token BITLITERAL BOOLITERAL INTLITERAL STRINGLITERAL CHARLITERAL %token EMPTYLITERAL FLOATLITERAL%token <id> NAME%token ASSIGN LESSTHANEQ GREATERTHANEQ NOTEQ LEFTTUPLE RIGHTTUPLE ARROW%token DOUBLESOLIDUS EXPONENT%type <id> name_string, opt_name_string, set_list_element, variable%type <idlist> def_occ_list, set_list, param_list, variable_list%type <type> mode, opt_result_spec, index_mode, procedure_mode, structure_mode%type <type> param%type <signature> procedure_definition, process_definition%type <attrib> param_attr, opt_loc%type <block> modulion, spec_module%%program: program { set_module_name(NULL); } modulion { emit_module(NULL, $3); }| program NAME ':' { set_module_name($2.name); } modulion { emit_module(&$2, $5); }| program { set_spec_module_name(NULL); } spec_module { emit_spec_module(NULL, $3); }| program NAME ':' { set_spec_module_name($2.name); } spec_module { emit_spec_module(&$2, $5); }| /* an empty translation unit */;/* According to gcc/ch/parse.c, we can still parse multi-dimension cases using the single-dimension syntax. */case_action: CASE expr_list OF opt_range_list case_alternative_list ESAC| CASE expr_list OF opt_range_list case_alternative_list ELSE opt_actions ESAC;opt_range_list: range_list ';'| /* empty */;range_list: name_string {}| range_list ',' name_string;case_alternative_list: case_alternative| case_alternative_list case_alternative;case_alternative: case_label_specification ':' opt_actions;/* End of case action stuff. */def_occ_list: NAME { $$ = ckalloc(sizeof(struct identifierlist)); memcpy($$, &$1, sizeof(struct identifier)); $$->next = NULL; }| def_occ_list ',' NAME { $$ = ckalloc(sizeof(struct identifierlist)); memcpy($$, &$3, sizeof(struct identifier)); $$->next = $1; };delay_case_action: DELAY CASE dcase_event_superlist ESAC| DELAY CASE SET expr ';' dcase_event_superlist ESAC| DELAY CASE SET expr ';' PRIORITY expr ';' dcase_event_superlist ESAC;dcase_event_superlist: delay_case_event_list dcase_event_superlist| action dcase_event_superlist| /* empty */;modulion: MODULE body END opt_handler opt_name_string ';' { $$.startline = $1.line; $$.startcol = $1.startcol; $$.endline = $6.line; $$.endcol = $6.endcol; }| REGION body END opt_handler opt_name_string ';' { $$.startline = $1.line; $$.startcol = $1.startcol; $$.endline = $6.line; $$.endcol = $6.endcol; };delay_case_event_list: '(' expr_list ')' ':';expr_list: expr| expr ',' expr_list;field: CASE OF variant_alternative_list ESAC| CASE OF variant_alternative_list ELSE ESAC| CASE OF variant_alternative_list ELSE variant_field_list ESAC| CASE def_occ_list OF variant_alternative_list ESAC| CASE def_occ_list OF variant_alternative_list ELSE ESAC| CASE def_occ_list OF variant_alternative_list ELSE variant_field_list ESAC| fixed_field;variant_field_list: fixed_field| variant_field_list ',' fixed_field;variant_alternative_list: variant_alternative| variant_alternative_list ',' variant_alternative;receive_spec: '(' NAME ')' ':'| '(' NAME IN expr_list ')' ':';signal_definition: NAME { }| NAME '=' '(' mode_list ')' { }| NAME TO name_string { }| NAME '=' '(' mode_list ')' TO name_string { };mode_list: mode { }| mode_list ',' mode { };receive_spec_list: receive_spec receive_spec_list| action receive_spec_list| /* empty */;opt_varying: VARYING| /* empty */;opt_handler: handler| /* empty */;handler: ON on_alternatives END| ON on_alternatives ELSE opt_actions END;on_exception_list: '(' name_string_list ')' ':';end: opt_handler opt_name_string ';';args: /* empty */| arglist;arglist: expr| args ',' expr;action: other_actions end| ';' { };other_actions: AFTER expr IN opt_actions TIMEOUT opt_actions END| AFTER expr DELAY IN opt_actions TIMEOUT opt_actions END| ASSERT expr| AT primval IN opt_actions TIMEOUT opt_actions END| BEG body END| case_action| CAUSE name_string| CONTINUE expr| CYCLE expr IN opt_actions END| DELAY expr opt_prio_expr| delay_case_action| do_action| EXIT name_string| GOTO name_string| IF expr then_clause FI| IF expr then_clause else_clause FI| RECEIVE CASE receive_spec_list opt_else_actions ESAC| RECEIVE CASE SET NAME ';' receive_spec opt_else_actions ESAC| RESULT expr| RETURN opt_expr| SEND name_string opt_with_expr opt_to_expr opt_prio_expr| SEND name_string '(' expr_list ')' opt_with_expr opt_to_expr opt_prio_expr| START name_string '(' args ')' { emit_xref_procedure($2.name, $2.line); }| START name_string '(' args ')' SET NAME { emit_xref_procedure($2.name, $2.line); }| STOP;opt_expr: expr| /* empty */;opt_else_actions: ELSE opt_actions;grant_stmt: rename_clauses| postfix_list opt_prefix_clause;opt_result_spec: RETURNS '(' mode ')' { $$ = $3; }| RETURNS '(' mode LOC ')' { $$ = $3; }| RETURNS '(' mode LOC DYNAMIC ')' { $$ = $3; }| RETURNS '(' mode NONREF LOC ')' { $$ = $3; }| RETURNS '(' mode NONREF LOC DYNAMIC ')' { $$ = $3; }| /* empty */ { $$.text = NULL; }; procedure_mode: PROC '(' ')' opt_result_spec opt_except opt_recursive { $$.text = SN_StrDup("PROC"); }| PROC '(' proc_mode_list ')' opt_result_spec opt_except opt_recursive { $$.text = SN_StrDup("PROC"); };proc_mode_list: mode param_attr { }| proc_mode_list ',' mode param_attr { }; opt_procedureattr: GENERAL opt_recursive| SIMPLE opt_recursive| INLINE opt_recursive| opt_recursive;opt_recursive: RECURSIVE| /* empty */;rename_clauses: rename_clause| rename_clauses ',' rename_clause;rename_clause: '(' opt_name_string ARROW opt_name_string ')' '!' postfix;seize_stmt: rename_clauses| postfix_list opt_prefix_clause;opt_with_expr: WITH expr| /* empty */;opt_to_expr: TO expr| /* empty */;opt_prio_expr: PRIORITY expr| /* empty */;set_list: set_list_element { $$ = ckalloc(sizeof(struct identifierlist)); memcpy($$, &$1, sizeof(struct identifier)); $$->next = NULL; }| set_list ',' set_list_element { $$ = ckalloc(sizeof(struct identifierlist)); memcpy($$, &$3, sizeof(struct identifier)); $$->next = $1; };set_list_element: NAME { $$ = $1; }| NAME '=' expr { $$ = $1; };signal_definition_stmt: signal_definition| signal_definition_stmt ',' signal_definition;spec_module: SPEC MODULE spec_definitions END opt_name_string ';' { $$.startline = $1.line; $$.startcol = $1.startcol; $$.endline = $6.line; $$.endcol = $6.endcol; };spec_definitions: spec_definitions definition| spec_definitions NAME ':' PROC { set_proc_name($2.name); } procedure_definition| spec_definitions NAME ':' PROCESS { set_process_name($2.name); } process_definition| /* empty */;structure_mode: STRUCT '(' fields ')' { $$ = $1; };fields: field| fields ',' field;fixed_field: def_occ_list mode opt_layout { /* for now */ };primval: INTLITERAL| BITLITERAL| BOOLITERAL| CHARLITERAL| EMPTYLITERAL| FLOATLITERAL| STRINGLITERAL| THIS| tuple;opt_args: /* empty */| opt_args '(' args ')' ;opt_dot: /* empty */| '.';variable: NAME { $$ = $1; $$.type = simple; }| NAME '(' args ')' { $$ = $1; $$.type = call; }| NAME '(' args ')' '(' args ')' opt_args { $$ = $1; $$.type = array; /* multidimensional array */ } | NAME '(' expr ':' expr ')' { $$ = $1; $$.type = array; /* slice */ }| NAME '(' expr UP expr ')' { $$ = $1; $$.type = array; /* slice */ }| ARROW opt_dot NAME { $$ = $3; $$.type = simple; }| ARROW opt_dot NAME '(' args ')' opt_args { $$ = $3; $$.type = array; }| ARROW opt_dot NAME '(' expr ':' expr ')' { $$ = $3; $$.type = array; /* slice */ }| ARROW opt_dot NAME '(' expr UP expr ')' { $$ = $3; $$.type = array; /* slice */ }| variable '.' NAME| variable '.' NAME '(' args ')' opt_args| variable '.' NAME '(' expr ':' expr ')'| variable '.' NAME '(' expr UP expr ')'| variable ARROW opt_dot NAME| variable ARROW opt_dot NAME '(' args ')' opt_args| variable ARROW opt_dot NAME '(' expr ':' expr ')'| variable ARROW opt_dot NAME '(' expr UP expr ')';operand7: primval| variable { if (with_active()) { if (get_with_scope() == NULL) {#ifdef DEBUG printf("WITH: into scope %s\n", $1.name);#endif set_with_scope($1.name); } } else if (emit) { if ($1.type == call) { emit_xref_procedure($1.name, $1.line); } else { emit_xref_variable($1.name, $1.line); } } }| '(' operand0 ')' | '(' operand0 ')' primval; operand6: NOT operand7| '-' operand7| operand7;operand5: operand5 EXPONENT operand6| operand6;operand4: operand4 '*' operand5| operand4 '/' operand5| operand4 MOD operand5| operand4 REM operand5| operand5;operand3: operand3 '+' operand4| operand3 '-' operand4| operand3 DOUBLESOLIDUS operand4| operand4; operand2: operand2 IN operand3| operand2 '>' operand3| operand2 GREATERTHANEQ operand3| operand2 '<' operand3| operand2 LESSTHANEQ operand3| operand2 '=' operand3| operand2 NOTEQ operand3| operand3;operand1: operand1 AND operand2| operand1 ANDIF operand2| operand2;operand0: operand0 OR operand1| operand0 XOR operand1| operand0 ORIF operand1| operand1;expr: if_expr| case_expr| operand0;dyadic_operator: '+' | '-' | '/' | '*' | MOD | REM | DOUBLESOLIDUS | AND | OR | XOR;opt_layout: layout| /* empty */;layout: PACK| NOPACK| POS pos
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -