📄 grammar.y
字号:
%{/*- * Copyright (c) 1982, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)grammar.y 8.1 (Berkeley) 6/6/93";#endif /* not lint *//* * yacc grammar for debugger commands */#include "defs.h"#include "command.h"#include "sym.h"#include "symtab.h"#include "tree.h"#include "process.h"#include "source.h"%}%term ALIAS ASSIGN CALL CHFILE%term CONT DUMP EDIT%term GRIPE HELP LIST NEXT%term QUIT REMAKE PRINT%term RUN SH SOURCE%term STATUS STEP%term STOP STOPI TRACE TRACEI%term DELETE%term WHATIS WHICH WHERE%term XI XD%term AT IN IF%term FILENAME%term INT REAL NAME STRING%term DIV MOD%term AND OR NOT%binary '<' '=' '>' IN%left '+' '-' OR '|'%left UNARYSIGN%left '*' '/' DIV MOD AND '&'%left NOT%union { SYM *y_sym; NODE *y_node; int y_int; OP y_op; long y_long; double y_real; char *y_string; BOOLEAN y_bool;};%type <y_int> trace TRACE TRACEI stop STOP STOPI%type <y_long> INT%type <y_real> REAL%type <y_op> addop mulop relop%type <y_string> STRING FILENAME SH opt_filename%type <y_sym> NAME%type <y_node> command rcommand what where opt_arglist opt_cond%type <y_node> exp_list exp boolean_exp term constant%type <y_node> line_list line_number address_list%%input: input command_nl{ prompt();}| /* empty */;command_nl: command_line '\n'| '\n';/* * There are two kinds of commands, those that can be redirected * and those that can't. */command_line: command{ eval($1);}| rcommand{ eval($1);}| rcommand '>' FILENAME{ setout($3); eval($1); unsetout();}| SH{ shell($1);}| run args{ run();};run: RUN{ arginit();};args: arg args| /* empty */;arg: FILENAME{ newarg($1);}| '<' FILENAME{ inarg($2);}| '>' FILENAME{ outarg($2);};command: ASSIGN term exp{ $$ = build(O_ASSIGN, $2, $3);}| CHFILE opt_filename{ $$ = build(O_CHFILE, $2);}| CONT{ $$ = build(O_CONT);}| LIST line_list{ $$ = build(O_LIST, $2);}| LIST NAME{ $$ = build(O_LIST, build(O_NAME, $2));}| NEXT{ $$ = build(O_NEXT);}| PRINT exp_list{ $$ = build(O_PRINT, $2);}| QUIT{ quit(0);}| STEP{ $$ = build(O_STEP);}| stop where opt_cond{ $$ = build($1, NIL, $2, $3);}| stop what opt_cond{ $$ = build($1, $2, NIL, $3);}| stop IF boolean_exp{ $$ = build($1, NIL, NIL, $3);}| trace what where opt_cond{ $$ = build($1, $2, $3, $4);}| trace where opt_cond{ $$ = build($1, NIL, $2, $3);}| trace what opt_cond{ $$ = build($1, $2, NIL, $3);}| trace opt_cond{ $$ = build($1, NIL, NIL, $2);}| DELETE INT{ $$ = build(O_DELETE, $2);}| WHATIS term{ $$ = build(O_WHATIS, $2);}| WHICH NAME{ $$ = build(O_WHICH, $2);}| WHERE{ $$ = build(O_WHERE);}| XI address_list{ $$ = build(O_XI, $2);}| XD address_list{ $$ = build(O_XD, $2);};rcommand: ALIAS FILENAME opt_filename{ $$ = build(O_ALIAS, $2, $3);}| ALIAS{ $$ = build(O_ALIAS, NIL, NIL);}| CALL term opt_arglist{ $$ = build(O_CALL, $2, $3);}| EDIT opt_filename{ $$ = build(O_EDIT, $2);}| DUMP{ $$ = build(O_DUMP);}| GRIPE{ $$ = build(O_GRIPE);}| HELP{ $$ = build(O_HELP);}| REMAKE{ $$ = build(O_REMAKE);}| SOURCE FILENAME{ $$ = build(O_SOURCE, $2);}| STATUS{ $$ = build(O_STATUS);};trace: TRACE{ $$ = O_TRACE;}| TRACEI{ $$ = O_TRACEI;};stop: STOP{ $$ = O_STOP;}| STOPI{ $$ = O_STOPI;};what: exp| FILENAME line_number{ $$ = build(O_QLINE, $1, $2);};where: IN term{ $$ = $2;}| AT line_number{ $$ = build(O_QLINE, cursource, $2);}| AT FILENAME line_number{ $$ = build(O_QLINE, $2, $3);};opt_filename: /* empty */{ $$ = NIL;}| FILENAME;opt_arglist: /* empty */{ $$ = NIL;}| '(' exp_list ')'{ $$ = $2;};line_list: /* empty */{ NODE *first, *last; first = build(O_LCON, (long) 1); last = build(O_LCON, (long) lastlinenum); $$ = build(O_COMMA, first, last);}| line_number{ $$ = build(O_COMMA, $1, $1);}| line_number ',' line_number{ $$ = build(O_COMMA, $1, $3);};line_number: INT{ $$ = build(O_LCON, $1);}| '$'{ $$ = build(O_LCON, (long) lastlinenum);};address_list: exp{ $$ = build(O_COMMA, $1, $1);}| exp ',' exp{ $$ = build(O_COMMA, $1, $3);};opt_cond: /* empty */{ $$ = NIL;}| IF boolean_exp{ $$ = $2;};exp_list: exp{ $$ = build(O_COMMA, $1, NIL);}| exp ',' exp_list{ $$ = build(O_COMMA, $1, $3);};exp: term{ $$ = build(O_RVAL, $1);}| term '(' exp_list ')'{ $$ = build(O_CALL, $1, $3);}| constant| '+' exp %prec UNARYSIGN{ $$ = $2;}| '-' exp %prec UNARYSIGN{ $$ = build(O_NEG, $2);}| exp addop exp %prec '+'{ $$ = build($2, $1, $3);}| exp mulop exp %prec '*'{ $$ = build($2, $1, $3);}| exp relop exp %prec '<'{ $$ = build($2, $1, $3);}| '(' exp ')'{ $$ = $2;};boolean_exp: exp{ chkboolean($$ = $1);};term: NAME{ $$ = build(O_NAME, $1);}| AT{ SYM *s; s = st_lookup(symtab, "at"); if (s == NIL) { error("\"at\" is not defined"); } $$ = build(O_NAME, s);}| term '[' exp_list ']'{ $$ = subscript($1, $3);}| term '.' NAME{ $$ = dot($1, $3);}| term '^'{ $$ = build(O_INDIR, $1);};constant: INT{ $$ = build(O_LCON, $1);}| REAL{ $$ = build(O_FCON, $1);}| STRING{ $$ = build(O_SCON, $1);};addop: '+'{ $$ = O_ADD;}| '-'{ $$ = O_SUB;}| OR{ $$ = O_OR;}| '|'{ $$ = O_OR;};mulop: '*'{ $$ = O_MUL;}| '/'{ $$ = O_DIVF;}| DIV{ $$ = O_DIV;}| MOD{ $$ = O_MOD;}| AND{ $$ = O_AND;}| '&'{ $$ = O_AND;};relop: '<'{ $$ = O_LT;}| '<' '='{ $$ = O_LE;}| '>'{ $$ = O_GT;}| '>' '='{ $$ = O_GE;}| '='{ $$ = O_EQ;}| '<' '>'{ $$ = O_NE;};%%/* * parser error handling */yyerror(s)char *s;{ if (strcmp(s, "syntax error") == 0) { error("bad command syntax"); } else { error(s); }}/* * In recovering from an error we gobble input up to a newline. */gobble(){ register int t; if (!nlflag) { while ((t = yylex()) != '\n' && t != 0); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -