📄 gram.y
字号:
/* $Header: gram.y 88/08/09 09:08:42 Xusr Exp $ *//* * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. * * All Rights Reserved * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of Digital Equipment * Corporation not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * * * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. *//* * MODIFICATION HISTORY * * 000 -- M. Gancarz, DEC Ultrix Engineering Group * 001 -- Loretta Guarino Reid, DEC Ultrix Engineering Group * Western Software Lab. Convert to X11. */%{#ifndef lintstatic char *sccsid = "@(#)gram.y 3.8 1/24/86";#endif#include "uwm.h"/* * Values returned by complex expression parser. */#define C_STRING 1 /* IsString. */#define C_MENU 2 /* IsMenu. */#define C_MAP 3 /* IsMap. */#define C_MENUMAP 4 /* IsMenuMap. */static int ki; /* Keyword index. */static int bkmask; /* Button/key mask. */static int cmask; /* Context mask. */static char msg[BUFSIZ]; /* Error message buffer. */static char *menu_name; /* Menu name. */static MenuInfo *menu_info; /* Menu info. */static MenuLine *ml_ptr; /* Temporary menu line pointer. */static char *hcolors[4]; /* Color values used in menu hdrs. */static char *mcolors[2]; /* Color values used in menus. */MenuLink *menu_link; /* Temporary menu link pointer. */char *strconcat(char*,char*);MenuLine *AllocMenuLine(void);MenuLine *StashMenuLine(int, char*);MenuInfo *stashmenuinfo(char*, MenuLine*, char*[]);MenuLink *stashmenulink(MenuInfo*);MenuLine *appendmenuline(MenuLine*, MenuLine*);MenuLink *appendmenulink(MenuLink*, MenuLink*);%}%union { char *sval; int ival; short shval; struct _menuline *mlval; struct _menuinfo *mival; char **cval;}%token NL%token <sval> STRING%token <ival> COMMENT%type <ival> keyword%type <ival> compexpr%type <ival> keyexpr%type <ival> kmask%type <ival> contexpr%type <ival> contmask%type <ival> buttmodexpr%type <ival> buttmodifier%type <ival> buttexpr%type <sval> menuname%type <sval> strings%type <sval> color%type <cval> color2%type <cval> color4%type <mlval> menuexpr%type <mlval> menulist%type <mlval> menuline%type <mlval> menuaction%% /* beginning of rules section */input: | input command | input error command { yyerrok; } ;command: boolvar term | expr term | COMMENT { Lineno++; } | term ;term: NL { Lineno++; } | ';' ;expr: keyword '=' compexpr { switch (KeywordTable[$1].type) { case IsString: if ($3 == C_STRING) { strcpy(KeywordTable[$1].sptr, yylval.sval); } else { yyerror("illegal construct"); } free(yylval.sval); break; case IsNumeric: if ($3 == C_STRING) { *(KeywordTable[$1].nptr) = y_atoi(yylval.sval); } else yyerror("illegal construct"); free(yylval.sval); break; case IsBoolTrue: case IsBoolFalse: yyerror("illegal value assignment"); break; case IsQuitFunction: case IsFunction: if ($3 == C_MAP) { bindtofunc($1, bkmask, cmask, NULL); } else yyerror("illegal construct"); break; case IsDownFunction: if (bkmask & ButtonUp) { sprintf(msg, "cannot bind %s to button up", KeywordTable[$1].name); yyerror(msg); } if ($3 == C_MAP) { bindtofunc($1, bkmask, cmask, NULL); } else yyerror("illegal construct"); break; case IsMenuMap: if (bkmask & ButtonUp) { sprintf(msg, "cannot bind %s to button up", KeywordTable[$1].name); yyerror(msg); } if ($3 == C_MENUMAP) { bindtofunc($1, bkmask, cmask, menu_name); } else yyerror("illegal construct"); break; case IsMenu: if ($3 == C_MENU) { menu_info = stashmenuinfo(menu_name, ml_ptr, hcolors); menu_link = stashmenulink(menu_info); Menus = appendmenulink(Menus, menu_link); } else yyerror("illegal menu construct"); break; default: yyerror("internal binding error"); break; } } ;compexpr: keyexpr ':' contexpr ':' buttexpr { $$ = C_MAP; bkmask = $1 | $5; cmask = $3; } | keyexpr ':' contexpr ':' buttexpr ':' menuname { $$ = C_MENUMAP; bkmask = $1 | $5; cmask = $3; menu_name = $7; } | STRING color4 menuexpr { $$ = C_MENU; menu_name = $1; ml_ptr = $3; } | STRING { $$ = C_STRING; } ;boolvar: STRING { ki = keywordlookup(yylval.sval); switch (KeywordTable[ki].type) { case IsBoolTrue: *(KeywordTable[ki].bptr) = TRUE; break; case IsBoolFalse: *(KeywordTable[ki].bptr) = FALSE; break; case IsParser: (*KeywordTable[ki].fptr)(); break; default: yyerror("keyword error"); } } ;keyword: STRING { $$ = keywordlookup(yylval.sval); } ;keyexpr: /* empty */ { $$ = 0; } | kmask { $$ = $1; } | kmask '|' kmask { $$ = $1 | $3; } ;contexpr: /* empty */ { $$ = ROOT | WINDOW | ICON; } | contmask { $$ = $1; } | contmask '|' contmask { $$ = $1 | $3; } | contmask '|' contmask '|' contmask { $$ = $1 | $3 | $5; } ;buttexpr: buttmodexpr { $$ = CheckButtonState($1); } ;kmask: STRING { $$ = keyexprlookup(yylval.sval); }contmask: STRING { $$ = contexprlookup(yylval.sval); }buttmodexpr: buttmodifier { $$ = $1; } | buttmodexpr buttmodifier { $$ = $1 | $2; } ;buttmodifier: STRING { $$ = buttexprlookup(yylval.sval); } ;menuname: STRING { $$ = $1; } ;menuexpr: '{' menulist '}' { $$ = $2; } ;menulist: menuline { $$ = $1; } | menulist menuline { $$ = appendmenuline($1, $2); } | menulist COMMENT { Lineno++; $$ = $1; } | COMMENT { Lineno++; $$ = NULL; } | term { $$ = NULL; } | menulist term { $$ = $1; } | error term { $$ = NULL; yyerrok; } ;menuline: strings ':' color2 menuaction term { $4->name = $1; $4->foreground = mcolors[0]; $4->background = mcolors[1]; $$ = $4; } ;menuaction: STRING { ki = keywordlookup(yylval.sval); if ((ki != -1) && (KeywordTable[ki].type != IsFunction) && (KeywordTable[ki].type != IsQuitFunction) && (KeywordTable[ki].type != IsDownFunction)) { sprintf(msg, "menu action \"%s\" not a function", KeywordTable[ki].name); yyerror(msg); } ml_ptr = AllocMenuLine(); if (KeywordTable[ki].type == IsQuitFunction) ml_ptr->type = IsImmFunction; else ml_ptr->type = IsUwmFunction; ml_ptr->func = KeywordTable[ki].fptr; $$ = ml_ptr; } | STRING ':' menuname { ki = keywordlookup($1); if (ki != -1 && KeywordTable[ki].type != IsMenuMap) { sprintf(msg, "menu action \"%s\" not a menu function", KeywordTable[ki].name); yyerror(msg); } ml_ptr = AllocMenuLine(); ml_ptr->type = IsMenuFunction; ml_ptr->text = $3; $$ = ml_ptr; } | '!' strings { $$ = StashMenuLine(IsShellCommand, $2); } | '^' strings { $$ = StashMenuLine(IsTextNL, $2); } | '|' strings { $$ = StashMenuLine(IsText, $2); } ;strings: STRING { $$ = yylval.sval; } | strings STRING { $$ = strconcat($1, $2); } ;color4: '(' color ':' color ':' color ':' color ')' { hcolors[0] = $2; hcolors[1] = $4; hcolors[2] = $6; hcolors[3] = $8; $$ = hcolors; } | /* empty */ { hcolors[0] = NULL; hcolors[1] = NULL; hcolors[2] = NULL; hcolors[3] = NULL; $$ = hcolors; } ;color2: '(' color ':' color ')' ':' { mcolors[0] = $2; mcolors[1] = $4; $$ = mcolors; } | /* empty */ { mcolors[0] = NULL; mcolors[1] = NULL; $$ = mcolors; } ;color: STRING { $$ = yylval.sval; } | /* empty */ { $$ = NULL; } ;%%/* * Look up a string in the keyword table and return its index, else * return -1. */keywordlookup(string)char *string;{ int i; for (i = 0; KeywordTable[i].name; i++) { if (!strcmp(KeywordTable[i].name, string)) { free(string); return(i); } } sprintf(msg,"keyword error: \"%s\"", string); yyerror(msg); free(string); return(-1);}/* * Look up a string in the key expression table and return its mask, else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -