⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parse.y

📁 早期freebsd实现
💻 Y
字号:
/* parse.y *//* * Adapted from rc grammar, v10 manuals, volume 2. */%{#include "rc.h"#ifndef lint#define lint		/* hush up gcc -Wall, leave out the dumb sccsid's. */#endifstatic Node *star, *nolist;Node *parsetree;	/* not using yylval because bison declares it as an auto */%}%token ANDAND BACKBACK BANG CASE COUNT DUP ELSE END FLAT FN FOR IF IN%token OROR PIPE REDIR SREDIR SUB SUBSHELL SWITCH TWIDDLE WHILE WORD HUH%left WHILE ')' ELSE%left ANDAND OROR '\n'%left BANG SUBSHELL%left PIPE%right '$' %left SUB/**/%union {	struct Node *node;	struct Redir redir;	struct Pipe pipe;	struct Dup dup;	struct Word word;	char *keyword;}%type <redir> REDIR SREDIR%type <pipe> PIPE%type <dup> DUP%type <word> WORD%type <keyword> keyword%type <node> assign body brace case cbody cmd cmdsa cmdsan comword epilog	     first line nlwords paren redir sword simple iftail word words%start rc%%rc	: line end		{ parsetree = $1; YYACCEPT; }	| error end		{ yyerrok; parsetree = NULL; YYABORT; }/* an rc line may end in end-of-file as well as newline, e.g., rc -c 'ls' */end	: END	/* EOF */	{ if (!heredoc(1)) YYABORT; } /* flag error if there is a heredoc in the queue */	| '\n'			{ if (!heredoc(0)) YYABORT; } /* get heredoc on \n *//* a cmdsa is a command followed by ampersand or newline (used in "line" and "body") */cmdsa	: cmd ';'	| cmd '&'		{ $$ = ($1 != NULL ? mk(nNowait,$1) : $1); }/* a line is a single command, or a command terminated by ; or & followed by a line (recursive) */line	: cmd	| cmdsa line		{ $$ = ($1 != NULL ? mk(nBody,$1,$2) : $2); }/* a body is like a line, only commands may also be terminated by newline */body	: cmd	| cmdsan body		{ $$ = ($1 == NULL ? $2 : $2 == NULL ? $1 : mk(nBody,$1,$2)); }cmdsan	: cmdsa	| cmd '\n'		{ $$ = $1; if (!heredoc(0)) YYABORT; } /* get h.d. on \n */brace	: '{' body '}'		{ $$ = $2; }paren	: '(' body ')'		{ $$ = $2; }assign	: first '=' word	{ $$ = mk(nAssign,$1,$3); }epilog	:			{ $$ = NULL; }	| redir epilog		{ $$ = mk(nEpilog,$1,$2); }/* a redirection is a dup (e.g., >[1=2]) or a file redirection. (e.g., > /dev/null) */redir	: DUP			{ $$ = mk(nDup,$1.type,$1.left,$1.right); }	| REDIR word		{ $$ = mk(nRedir,$1.type,$1.fd,$2);				  if ($1.type == rHeredoc && !qdoc($2, $$)) YYABORT; /* queue heredocs up */				}	| SREDIR word		{ $$ = mk(nRedir,$1.type,$1.fd,$2);				  if ($1.type == rHeredoc && !qdoc($2, $$)) YYABORT; /* queue heredocs up */				}case	: CASE words ';'	 		{ $$ = mk(nCase, $2); }	| CASE words '\n'	 		{ $$ = mk(nCase, $2); }cbody	: cmd					{ $$ = mk(nCbody, $1, NULL); }	| case cbody				{ $$ = mk(nCbody, $1, $2); }	| cmdsan cbody				{ $$ = mk(nCbody, $1, $2); }iftail	: cmd		%prec ELSE	| brace ELSE optnl cmd			{ $$ = mk(nElse,$1,$4); }cmd	: /* empty */	%prec WHILE		{ $$ = NULL; }	| simple	| brace epilog				{ $$ = mk(nBrace,$1,$2); }	| IF paren optnl iftail			{ $$ = mk(nIf,$2,$4); }	| FOR '(' word IN words ')' optnl cmd	{ $$ = mk(nForin,$3,$5,$8); }	| FOR '(' word ')' optnl cmd		{ $$ = mk(nForin,$3,star,$6); }	| WHILE paren optnl cmd			{ $$ = mk(nWhile,$2,$4); }	| SWITCH '(' word ')' optnl '{' cbody '}' { $$ = mk(nSwitch,$3,$7); }	| TWIDDLE optcaret word words		{ $$ = mk(nMatch,$3,$4); }	| cmd ANDAND optnl cmd			{ $$ = mk(nAndalso,$1,$4); }	| cmd OROR optnl cmd			{ $$ = mk(nOrelse,$1,$4); } 	| cmd PIPE optnl cmd			{ $$ = mk(nPipe,$2.left,$2.right,$1,$4); }	| redir cmd	%prec BANG		{ $$ = ($2 != NULL ? mk(nPre,$1,$2) : $1); }	| assign cmd	%prec BANG		{ $$ = ($2 != NULL ? mk(nPre,$1,$2) : $1); }	| BANG optcaret cmd			{ $$ = mk(nBang,$3); }	| SUBSHELL optcaret cmd			{ $$ = mk(nSubshell,$3); }	| FN words brace			{ $$ = mk(nNewfn,$2,$3); }	| FN words				{ $$ = mk(nRmfn,$2); }optcaret : /* empty */	| '^'simple	: first	| simple word			{ $$ = ($2 != NULL ? mk(nArgs,$1,$2) : $1); }	| simple redir			{ $$ = mk(nArgs,$1,$2); }first	: comword	| first '^' sword		{ $$ = mk(nConcat,$1,$3); }sword	: comword	| keyword			{ $$ = mk(nWord,$1, NULL); }word	: sword	| word '^' sword		{ $$ = mk(nConcat,$1,$3); }comword	: '$' sword			{ $$ = mk(nVar,$2); }	| '$' sword SUB words ')'	{ $$ = mk(nVarsub,$2,$4); }	| COUNT sword			{ $$ = mk(nCount,$2); }	| FLAT sword			{ $$ = mk(nFlat, $2); }	| '`' sword			{ $$ = mk(nBackq,nolist,$2); }	| '`' brace			{ $$ = mk(nBackq,nolist,$2); }	| BACKBACK word	brace		{ $$ = mk(nBackq,$2,$3); }	| BACKBACK word	sword		{ $$ = mk(nBackq,$2,$3); }	| '(' nlwords ')'		{ $$ = $2; }	| REDIR brace			{ $$ = mk(nNmpipe,$1.type,$1.fd,$2); }	| WORD				{ $$ = ($1.w[0] == '\'') ? mk(nQword, $1.w+1, NULL) : mk(nWord,$1.w, $1.m); }keyword	: FOR		{ $$ = "for"; }	| IN		{ $$ = "in"; }	| WHILE		{ $$ = "while"; }	| IF		{ $$ = "if"; }	| SWITCH	{ $$ = "switch"; }	| FN		{ $$ = "fn"; }	| ELSE		{ $$ = "else"; }	| CASE		{ $$ = "case"; }	| TWIDDLE	{ $$ = "~"; }	| BANG		{ $$ = "!"; }	| SUBSHELL	{ $$ = "@"; }words	:		{ $$ = NULL; }	| words word	{ $$ = ($1 != NULL ? ($2 != NULL ? mk(nLappend,$1,$2) : $1) : $2); }nlwords :		{ $$ = NULL; }	| nlwords '\n'	| nlwords word	{ $$ = ($1 != NULL ? ($2 != NULL ? mk(nLappend,$1,$2) : $1) : $2); }optnl	: /* empty */	| optnl '\n'%%void initparse() {	star = treecpy(mk(nVar,mk(nWord,"*",NULL)), ealloc);	nolist = treecpy(mk(nVar,mk(nWord,"ifs",NULL)), ealloc);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -