mcgrew@dartagnan.rutgers.edu (Charles Mcgrew) (06/07/89)
Submitted-by: Chuck Musciano <chuck@trantor.harris-atd.com> Posting-number: Volume 1, Issue 27 Archive-name: tooltool2.1c/part08 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 8 (of 13)." # Contents: parse.y # Wrapped by chuck@melmac on Thu Jun 1 10:39:34 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'parse.y' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'parse.y'\" else echo shar: Extracting \"'parse.y'\" \(28618 characters\) sed "s/^X//" >'parse.y' <<'END_OF_FILE' X/************************************************************************/ X/* Copyright 1988 by Chuck Musciano and Harris Corporation */ X/* */ X/* Permission to use, copy, modify, and distribute this software */ X/* and its documentation for any purpose and without fee is */ X/* hereby granted, provided that the above copyright notice */ X/* appear in all copies and that both that copyright notice and */ X/* this permission notice appear in supporting documentation, and */ X/* that the name of Chuck Musciano and Harris Corporation not be */ X/* used in advertising or publicity pertaining to distribution */ X/* of the software without specific, written prior permission. */ X/* Chuck Musciano and Harris Corporation make no representations */ X/* about the suitability of this software for any purpose. It is */ X/* provided "as is" without express or implied warranty. */ X/* */ X/* The sale of any product based wholely or in part upon the */ X/* technology provided by tooltool is strictly forbidden without */ X/* specific, prior written permission from Harris Corporation. */ X/* Tooltool technology includes, but is not limited to, the source */ X/* code, executable binary files, specification language, and */ X/* sample specification files. */ X/************************************************************************/ X X X%{ X X#include <stdio.h> X#include <ctype.h> X X#include "tooltool.h" X XPUBLIC Menu ttymenu_proc(); X XPRIVATE int line_count = 1; XPRIVATE int curr_key, curr_key_set; XPRIVATE g_ptr curr_gadget = NULL; XPRIVATE d_ptr curr_window = NULL; XPRIVATE char ungetc = -1; X X%} X X%start tool_spec X X%union {a_ptr aval; X int ival; X char *cpval; X cv_ptr cvval; X e_ptr eval; X g_ptr gval; X l_ptr lval; X Menu mval; X Menu_item mival; X double rval; X } X X%token <cpval> ICON_STRING ID STRING X%token <ival> INTEGER X%token <rval> REAL X%token <ival> L2 L3 L4 L5 L6 L7 L8 L9 L10 F1 F2 F3 F4 F5 F6 F7 F8 F9 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 X X%token AND ASSIGN_AND ASSIGN_DIVIDE ASSIGN_MINUS ASSIGN_MODULO ASSIGN_OR ASSIGN_PLUS X%token ASSIGN_TIMES ASSIGN_XOR ASSIGNMENT COLON COMMA COMPLEMENT DECREMENT DIVIDE EQUAL X%token GREATER GREATER_EQUAL INCREMENT LBRACE LBRACK LEFT_SHIFT LESS LESS_EQUAL X%token LOGICAL_AND LOGICAL_NOT LOGICAL_OR LPAREN MINUS MODULO NOT_EQUAL OR PLUS X%token QUESTION RBRACE RBRACK RIGHT_SHIFT RPAREN SEMICOLON TIMES XOR X X%token ACTION ALIGN APPLICATION AT BASE BEEP BOTTOM BREAK BUTTON BY CENTER X%token CHARACTERS CHOICE CLOSE COMPLETION CONTINUE CONTROL CURRENT CYCLE DIALOG DISABLE X%token DISPLAY ELSE END_BUTTON END_CHOICE END_DIALOG END_GADGETS END_KEY END_KEYS X%token END_LABEL END_MENU END_MOUSE END_SLIDER END_TEXT EXIT FONT FOR X%token FUNCTION_KEYS GADGETS HORIZONTAL ICON IF IGNORE INITIAL INITIALIZE X%token KEY KEYS LABEL LEFT MARK MAXIMUM MENU META MIDDLE MINIMUM MOUSE X%token NOMARK NORMAL NORMAL_KEYS NOTHING OFF ON OPEN PIXELS POPUP X%token PROPORTIONAL RAGGED RANGE REMOVE RETAIN RIGHT SEND SHIFT SIZE X%token SLIDER TEXT TIMER TOP TRIGGER TTYMENU VALUE VERTICAL WHILE WIDTH X X%type <aval> action action_list open close initialize timer X%type <ival> size_unit shifts key_name button_name align X%type <cpval> label font icon optional_name X%type <cvval> choice_list X%type <eval> array_ref expr factor optional_expr X%type <gval> gadgets gadget_list gadget button_gadget choice_gadget X label_gadget menu_gadget slider_gadget text_gadget X%type <lval> icon_label X%type <mval> menu menu_value X%type <mival> menu_entry X X%left ACTION X%left ELSE X%left EXPR X%left SEMICOLON X%left ARRAY_REF X X%right ASSIGNMENT ASSIGN_AND ASSIGN_DIVIDE ASSIGN_MINUS ASSIGN_MODULO ASSIGN_OR ASSIGN_PLUS ASSIGN_TIMES ASSIGN_XOR X%left COMMA X%right QUESTION COLON X%left LOGICAL_OR X%left LOGICAL_AND X%left OR X%left XOR X%left AND X%left EQUAL NOT_EQUAL X%left LESS LESS_EQUAL GREATER GREATER_EQUAL X%left LEFT_SHIFT RIGHT_SHIFT X%left PLUS MINUS X%left TIMES DIVIDE MODULO X%right DECREMENT INCREMENT UMINUS COMPLEMENT LOGICAL_NOT X%left LPAREN RPAREN X X%% X Xtool_spec : APPLICATION STRING X { curr_window = tt_base_window; } X appl_attr gadgets dialogs keys mouse X { tt_application = $2; X tt_base_window->gadgets = $5; X tt_base_window->is_base_frame = TRUE; X } X ; X Xappl_attr : empty X | appl_attr size X | appl_attr position X | appl_attr icon X { if (tt_icon == NULL) X tt_icon = $2; X else X yyerror("Conflicting application icon specifications"); X } X | appl_attr label X { if (curr_window->label == NULL) X curr_window->label = $2; X else X yyerror("Conflicting window label specifications"); X } X | appl_attr font X { if (tt_a_font == tt_default_font) X tt_a_font = tt_open_font($2); X else X yyerror("Conflicting application font specifications"); X } X | appl_attr open X { if (curr_window->open_action == NULL) X curr_window->open_action = $2; X else X yyerror("Conflicting window opening strings"); X } X | appl_attr close X { if (curr_window->close_action == NULL) X curr_window->close_action = $2; X else X yyerror("Conflicting window closing strings"); X } X | appl_attr initialize X { if (tt_initial_action == NULL) X tt_initial_action = $2; X else X yyerror("Conflicting initial command strings"); X } X | appl_attr timer X { if (tt_timer_action == NULL) X tt_timer_action = $2; X else X yyerror("Conflicting timer command strings"); X } X ; X Xsize : SIZE INTEGER BY INTEGER size_unit X { curr_window->rows = $2; X curr_window->columns = $4; X curr_window->is_chars = $5; X } X ; X Xposition : AT INTEGER INTEGER X { curr_window->win_x = $2; X curr_window->win_y = $3; X } X ; X Xsize_unit : CHARACTERS X { $$ = TRUE; } X | PIXELS X { $$ = FALSE; } X ; X Xicon : ICON STRING X { $$ = $2; } X ; X Xlabel : LABEL STRING X { $$ = $2; } X ; X Xfont : FONT STRING X { $$ = $2; } X ; X Xopen : OPEN action X { $$ = $2; } X ; X Xclose : CLOSE action X { $$ = $2; } X ; X Xinitialize : INITIALIZE action X { $$ = $2; } X ; X Xtimer : TIMER action X { $$ = $2; } X ; X Xgadgets : empty X { $$ = (g_ptr) 0; } X | GADGETS gadget_attr gadget_list END_GADGETS X { if (curr_window->gadget_pos == G_NOPOS) X curr_window->gadget_pos = G_TOP; X $$ = $3; X } X ; X Xgadget_attr : empty X | gadget_attr TOP X { if (curr_window->gadget_pos == G_NOPOS) X curr_window->gadget_pos = G_TOP; X else X yyerror("Conflicting gadget position specified"); X } X | gadget_attr BOTTOM X { if (curr_window->gadget_pos == G_NOPOS) X curr_window->gadget_pos = G_BOTTOM; X else X yyerror("Conflicting gadget position specified"); X } X | gadget_attr LEFT X { if (curr_window->gadget_pos == G_NOPOS) X curr_window->gadget_pos = G_LEFT; X else X yyerror("Conflicting gadget position specified"); X } X | gadget_attr RIGHT X { if (curr_window->gadget_pos == G_NOPOS) X curr_window->gadget_pos = G_RIGHT; X else X yyerror("Conflicting gadget position specified"); X } X | gadget_attr PROPORTIONAL X { curr_window->proportional = TRUE; } X | gadget_attr RAGGED X { curr_window->justified = FALSE; } X | gadget_attr font X { if (curr_window->g_font == tt_default_font) X curr_window->g_font = tt_open_font($2); X else X yyerror("Conflicting gadget font specified"); X } X | gadget_attr align X { if (curr_window->g_align == NO_ALIGN) X curr_window->g_align = $2; X else X yyerror("Conflicting gadget alignment specified"); X } X ; X Xalign : ALIGN LEFT X { $$ = ALIGN_TOP; } X | ALIGN CENTER X { $$ = ALIGN_MIDDLE; } X | ALIGN RIGHT X { $$ = ALIGN_BOTTOM; } X | ALIGN TOP X { $$ = ALIGN_TOP; } X | ALIGN MIDDLE X { $$ = ALIGN_MIDDLE; } X | ALIGN BOTTOM X { $$ = ALIGN_BOTTOM; } X ; X Xgadget_list : empty X { $$ = NULL; } X | gadget_list gadget X { g_ptr g; X X if ($1 == NULL) X $$ = $2; X else { X for (g = $1; g->next; g = g->next) X ; X g->next = $2; X $$ = $1; X } X } X ; X Xgadget : button_gadget X | choice_gadget X | label_gadget X | menu_gadget X | slider_gadget X | text_gadget X ; X Xbutton_gadget : BUTTON optional_name X { int i; X s_ptr s; X X curr_gadget = (g_ptr) safe_malloc(sizeof(g_data)); X curr_gadget->kind = GADGET_BUTTON; X curr_gadget->name = NULL; X curr_gadget->image = NULL; X curr_gadget->x = -1; X curr_gadget->next = NULL; X for (i = 0; i < MAX_SHIFT_SETS; i++) { X curr_gadget->u.but.label[i] = NULL; X curr_gadget->u.but.action[i] = NULL; X } X if ($2 != NULL) { X s = tt_find_symbol($2); X if (s->kind != SYMBOL_SYMBOL) X yyerror("Duplicate name: %s", s->name); X s->kind = SYMBOL_GADGET; X s->gadget = curr_gadget; X } X } X gadget_position value_list value_item END_BUTTON X { if (curr_gadget->u.but.label[0] == NULL) X yyerror("Every button must have a \"normal\" action"); X $$ = curr_gadget; X } X ; X Xvalue_list : empty X | value_list value_item X ; X Xvalue_item : shifts icon_label action X { if (curr_gadget->u.but.label[$1] != NULL) X yyerror("Duplicate button action"); X curr_gadget->u.but.label[$1] = $2; X curr_gadget->u.but.action[$1] = $3; X } X ; X Xshifts : empty X { $$ = S_NORMAL; } X | shifts NORMAL X { $$ = $1 | S_NORMAL; } X | shifts SHIFT X { $$ = $1 | S_SHIFT; } X | shifts CONTROL X { $$ = $1 | S_CONTROL; } X | shifts META X { $$ = $1 | S_META; } X ; X Xchoice_gadget : CHOICE optional_name X { s_ptr s; X X curr_gadget = (g_ptr) safe_malloc(sizeof(g_data)); X curr_gadget->kind = GADGET_CHOICE; X curr_gadget->name = $2; X curr_gadget->image = NULL; X curr_gadget->x = -1; X curr_gadget->next = NULL; X curr_gadget->u.cho.label = NULL; X curr_gadget->u.cho.mode = CHOICE_CURRENT; X curr_gadget->u.cho.mark = tt_default_mark; X curr_gadget->u.cho.nomark = tt_default_nomark; X curr_gadget->u.cho.value = NULL; X if ($2 != NULL) { X s = tt_find_symbol($2); X if (s->kind != SYMBOL_SYMBOL) X yyerror("Duplicate name: %s", s->name); X s->kind = SYMBOL_GADGET; X s->gadget = curr_gadget; X } X } X choice_attr choice_list END_CHOICE X { curr_gadget->u.cho.value = $5; X if (curr_gadget->u.cho.mode == CHOICE_CYCLE) X if (curr_gadget->u.cho.mark == tt_default_mark) X curr_gadget->u.cho.mark = curr_gadget->u.cho.nomark = tt_default_cycle; X else X curr_gadget->u.cho.nomark = curr_gadget->u.cho.mark; X $$ = curr_gadget; X } X ; X Xchoice_attr : empty X | choice_attr DISPLAY CURRENT X { curr_gadget->u.cho.mode = CHOICE_CURRENT; } X | choice_attr DISPLAY CYCLE X { curr_gadget->u.cho.mode = CHOICE_CYCLE; } X | choice_attr DISPLAY HORIZONTAL X { curr_gadget->u.cho.mode = CHOICE_HORIZONTAL; } X | choice_attr DISPLAY VERTICAL X { curr_gadget->u.cho.mode = CHOICE_VERTICAL; } X | choice_attr MARK icon_label X { curr_gadget->u.cho.mark = $3; } X | choice_attr NOMARK icon_label X { curr_gadget->u.cho.nomark = $3; } X | choice_attr LABEL icon_label X { curr_gadget->u.cho.label = $3; } X | choice_attr AT INTEGER INTEGER X { curr_gadget->x = $3; X curr_gadget->y = $4; X } X ; X Xchoice_list : empty X { $$ = NULL; } X | choice_list icon_label action X { cv_ptr curr, head; X X curr = (cv_ptr) safe_malloc(sizeof(cv_data)); X curr->label = $2; X curr->action = $3; X curr->next = NULL; X if ($1 == NULL) X $$ = curr; X else { X for (head = $1; head->next; head = head->next) X ; X head->next = curr; X $$ = $1; X } X } X ; X Xlabel_gadget : LABEL optional_name X { s_ptr s; X X curr_gadget = (g_ptr) safe_malloc(sizeof(g_data)); X curr_gadget->kind = GADGET_LABEL; X curr_gadget->name = NULL; X curr_gadget->image = NULL; X curr_gadget->x = -1; X curr_gadget->next = NULL; X if ($2 != NULL) { X s = tt_find_symbol($2); X if (s->kind != SYMBOL_SYMBOL) X yyerror("Duplicate name: %s", s->name); X s->kind = SYMBOL_GADGET; X s->gadget = curr_gadget; X } X } X gadget_position icon_label END_LABEL X { curr_gadget->u.lab.label = $5; X $$ = curr_gadget; X } X ; X Xmenu_gadget : MENU optional_name X { s_ptr s; X X curr_gadget = (g_ptr) safe_malloc(sizeof(g_data)); X curr_gadget->kind = GADGET_MENU; X curr_gadget->name = NULL; X curr_gadget->image = NULL; X curr_gadget->x = -1; X curr_gadget->next = NULL; X if ($2 != NULL) { X s = tt_find_symbol($2); X if (s->kind != SYMBOL_SYMBOL) X yyerror("Duplicate name: %s", s->name); X s->kind = SYMBOL_GADGET; X s->gadget = curr_gadget; X } X } X gadget_position icon_label menu_value END_MENU X { curr_gadget->u.men.label = $5; X curr_gadget->u.men.menu = $6; X $$ = curr_gadget; X } X ; X Xmenu : MENU menu_value END_MENU X { $$ = $2; } X | TTYMENU X { $$ = menu_create(MENU_GEN_PROC, ttymenu_proc, 0); } X ; X Xmenu_value : menu_entry X { $$ = menu_create(MENU_APPEND_ITEM, $1, 0); } X | menu_value menu_entry X { X menu_set($1, MENU_APPEND_ITEM, $2, 0); X $$ = $1; X } X ; X Xmenu_entry : icon_label action X { X if ($1->is_icon) X $$ = menu_create_item(MENU_IMAGE_ITEM, $1->image, $2, 0); X else X $$ = menu_create_item(MENU_STRING_ITEM, $1->label, $2, MENU_FONT, $1->font, 0); X } X | icon_label menu X { X if ($1->is_icon) X $$ = menu_create_item(MENU_PULLRIGHT_IMAGE, $1->image, $2, 0); X else X $$ = menu_create_item(MENU_PULLRIGHT_ITEM, $1->label, $2, MENU_FONT, $1->font, 0); X } X ; X Xslider_gadget : SLIDER optional_name X { s_ptr s; X X curr_gadget = (g_ptr) safe_malloc(sizeof(g_data)); X curr_gadget->kind = GADGET_SLIDER; X curr_gadget->name = $2; X curr_gadget->image = NULL; X curr_gadget->x = -1; X curr_gadget->next = NULL; X curr_gadget->u.sli.label = NULL; X curr_gadget->u.sli.minimum = 0; X curr_gadget->u.sli.maximum = 100; X curr_gadget->u.sli.initial = 0; X curr_gadget->u.sli.value = TRUE; X curr_gadget->u.sli.range = TRUE; X curr_gadget->u.sli.width = 100; X curr_gadget->u.sli.action = NULL; X curr_gadget->u.sli.font = curr_window->g_font; X if ($2 != NULL) { X s = tt_find_symbol($2); X if (s->kind != SYMBOL_SYMBOL) X yyerror("Duplicate name: %s", s->name); X s->kind = SYMBOL_GADGET; X s->gadget = curr_gadget; X } X } X slider_attr END_SLIDER X { X if (curr_gadget->u.sli.minimum > curr_gadget->u.sli.maximum) X yyerror("Slider maximum must exceed slider minimum"); X if (curr_gadget->u.sli.initial < curr_gadget->u.sli.minimum || X curr_gadget->u.sli.initial > curr_gadget->u.sli.maximum) X yyerror("Slider initial value must in the range [minimum, maximum]"); X $$ = curr_gadget; X } X ; X Xslider_attr : empty X | slider_attr ACTION action X { curr_gadget->u.sli.action = $3; } X | slider_attr FONT STRING X { curr_gadget->u.sli.font = tt_open_font($3); } X | slider_attr INITIAL INTEGER X { curr_gadget->u.sli.initial = $3; } X | slider_attr LABEL icon_label X { curr_gadget->u.sli.label = $3; } X | slider_attr MAXIMUM INTEGER X { curr_gadget->u.sli.maximum = $3; } X | slider_attr MINIMUM INTEGER X { curr_gadget->u.sli.minimum = $3; } X | slider_attr RANGE OFF X { curr_gadget->u.sli.range = FALSE; } X | slider_attr RANGE ON X { curr_gadget->u.sli.range = TRUE; } X | slider_attr VALUE OFF X { curr_gadget->u.sli.value = FALSE; } X | slider_attr VALUE ON X { curr_gadget->u.sli.value = TRUE; } X | slider_attr WIDTH INTEGER X { curr_gadget->u.sli.width = $3; } X | slider_attr AT INTEGER INTEGER X { curr_gadget->x = $3; X curr_gadget->y = $4; X } X ; X Xtext_gadget : TEXT optional_name X { s_ptr s; X X curr_gadget = (g_ptr) safe_malloc(sizeof(g_data)); X curr_gadget->kind = GADGET_TEXT; X curr_gadget->name = $2; X curr_gadget->image = NULL; X curr_gadget->x = -1; X curr_gadget->next = NULL; X curr_gadget->u.tex.label = NULL; X curr_gadget->u.tex.trigger = "\n\r"; X curr_gadget->u.tex.completion = ""; X curr_gadget->u.tex.ignore = tt_expand_ranges("\001-\037"); X curr_gadget->u.tex.display_len = 80; X curr_gadget->u.tex.retain_len = 256; X curr_gadget->u.tex.action = NULL; X curr_gadget->u.tex.font = curr_window->g_font; X curr_window->text_items_exist = TRUE; X if ($2 != NULL) { X s = tt_find_symbol($2); X if (s->kind != SYMBOL_SYMBOL) X yyerror("Duplicate name: %s", s->name); X s->kind = SYMBOL_GADGET; X s->gadget = curr_gadget; X } X } X text_attr END_TEXT X { $$ = curr_gadget; } X ; X Xtext_attr : empty X | text_attr ACTION action X { curr_gadget->u.tex.action = $3; } X | text_attr AT INTEGER INTEGER X { curr_gadget->x = $3; X curr_gadget->y = $4; X } X | text_attr COMPLETION STRING X { curr_gadget->u.tex.completion = tt_expand_ranges($3); } X | text_attr DISPLAY INTEGER X { curr_gadget->u.tex.display_len = $3; } X | text_attr FONT STRING X { curr_gadget->u.tex.font = tt_open_font($3); } X | text_attr IGNORE STRING X { curr_gadget->u.tex.ignore = tt_expand_ranges($3); } X | text_attr LABEL icon_label X { curr_gadget->u.tex.label = $3; } X | text_attr RETAIN INTEGER X { curr_gadget->u.tex.retain_len = $3; } X | text_attr TRIGGER STRING X { curr_gadget->u.tex.trigger = tt_expand_ranges($3); } X ; X Xicon_label : STRING X { $$ = tt_make_label(FALSE, $1, curr_window->g_font, NULL); } X | STRING COLON STRING X { $$ = tt_make_label(FALSE, $1, tt_open_font($3), NULL); } X | ICON_STRING X { $$ = tt_make_label(TRUE, NULL, NULL, tt_load_icon($1)); } X ; X Xoptional_name : empty X { $$ = NULL; } X | ID X { $$ = $1; } X ; X Xgadget_position : empty X | AT INTEGER INTEGER X { curr_gadget->x = $2; X curr_gadget->y = $3; X } X ; X Xaction : SEMICOLON X { $$ = NULL; } X | BEEP SEMICOLON X { $$ = tt_make_action(BEEP_OP); } X | BREAK SEMICOLON X { $$ = tt_make_action(BREAK_OP); } X | CLOSE %prec ACTION X { $$ = tt_make_action(CLOSE_OP); } X | CLOSE SEMICOLON X { $$ = tt_make_action(CLOSE_OP); } X | CONTINUE SEMICOLON X { $$ = tt_make_action(CONTINUE_OP); } X | DISPLAY ID SEMICOLON X { $$ = tt_make_action(DISPLAY_OP, tt_make_expr(E_SYMBOL, tt_find_symbol($2))); } X | EXIT %prec ACTION X { $$ = tt_make_action(EXIT_OP); } X | EXIT SEMICOLON X { $$ = tt_make_action(EXIT_OP); } X | expr %prec EXPR X { $$ = tt_make_action(($1->op == E_STRING)? SEND_OP : EXPR_OP, $1); } X | expr SEMICOLON %prec EXPR X { $$ = tt_make_action(($1->op == E_STRING)? SEND_OP : EXPR_OP, $1); } X | FOR LPAREN optional_expr SEMICOLON optional_expr SEMICOLON optional_expr RPAREN action X { $$ = tt_make_action(FOR_OP, $3, $5, $7, $9); } X | IF LPAREN expr RPAREN action %prec ACTION X { $$ = tt_make_action(IF_OP, $3, $5, NULL); } X | IF LPAREN expr RPAREN action ELSE action %prec ELSE X { $$ = tt_make_action(IF_OP, $3, $5, $7); } X | LBRACE action_list RBRACE X { $$ = $2; } X | NOTHING SEMICOLON X { $$ = NULL; } X | OPEN SEMICOLON X { $$ = tt_make_action(OPEN_OP); } X | POPUP ID SEMICOLON X { $$ = tt_make_action(POPUP_OP, tt_make_expr(E_SYMBOL, tt_find_symbol($2))); } X | REMOVE ID SEMICOLON X { $$ = tt_make_action(REMOVE_OP, tt_make_expr(E_SYMBOL, tt_find_symbol($2))); } X | SEND expr SEMICOLON %prec EXPR X { $$ = tt_make_action(SEND_OP, $2); } X | WHILE LPAREN expr RPAREN action X { $$ = tt_make_action(WHILE_OP, $3, $5); } X ; X Xaction_list : empty X { $$ = NULL; } X | action action_list X { a_ptr a; X X if ($1 == NULL) X $$ = $2; X else { X for (a = $1; a->next != NULL; a = a->next) X ; X a->next = $2; X $$ = $1; X } X } X ; X Xoptional_expr : empty X { $$ = NULL; } X | expr X ; X Xexpr : factor X | array_ref ASSIGNMENT expr X { if ($1->op == E_FUNC_ID) X yyerror("cannot assign to an intrinsic function"); X $$ = tt_make_expr(E_ASSIGNMENT, $1, $3); X } X | array_ref ASSIGN_AND expr X { if ($1->op == E_FUNC_ID) X yyerror("cannot assign to an intrinsic function"); X $$ = tt_make_expr(E_ASSIGN_AND, $1, $3); X } X | array_ref ASSIGN_DIVIDE expr X { if ($1->op == E_FUNC_ID) X yyerror("cannot assign to an intrinsic function"); X $$ = tt_make_expr(E_ASSIGN_DIVIDE, $1, $3); X } X | array_ref ASSIGN_MINUS expr X { if ($1->op == E_FUNC_ID) X yyerror("cannot assign to an intrinsic function"); X $$ = tt_make_expr(E_ASSIGN_MINUS, $1, $3); X } X | array_ref ASSIGN_MODULO expr X { if ($1->op == E_FUNC_ID) X yyerror("cannot assign to an intrinsic function"); X $$ = tt_make_expr(E_ASSIGN_MODULO, $1, $3); X } X | array_ref ASSIGN_OR expr X { if ($1->op == E_FUNC_ID) X yyerror("cannot assign to an intrinsic function"); X $$ = tt_make_expr(E_ASSIGN_OR, $1, $3); X } X | array_ref ASSIGN_PLUS expr X { if ($1->op == E_FUNC_ID) X yyerror("cannot assign to an intrinsic function"); X $$ = tt_make_expr(E_ASSIGN_PLUS, $1, $3); X } X | array_ref ASSIGN_TIMES expr X { if ($1->op == E_FUNC_ID) X yyerror("cannot assign to an intrinsic function"); X $$ = tt_make_expr(E_ASSIGN_TIMES, $1, $3); X } X | array_ref ASSIGN_XOR expr X { if ($1->op == E_FUNC_ID) X yyerror("cannot assign to an intrinsic function"); X $$ = tt_make_expr(E_ASSIGN_XOR, $1, $3); X } X | LPAREN expr RPAREN X { $$ = tt_make_expr(E_PAREN, $2); } X | expr PLUS expr X { $$ = tt_make_expr(E_PLUS, $1, $3); } X | expr MINUS expr X { $$ = tt_make_expr(E_MINUS, $1, $3); } X | expr TIMES expr X { $$ = tt_make_expr(E_TIMES, $1, $3); } X | expr DIVIDE expr X { $$ = tt_make_expr(E_DIVIDE, $1, $3); } X | expr MODULO expr X { $$ = tt_make_expr(E_MODULO, $1, $3); } X | expr AND expr X { $$ = tt_make_expr(E_AND, $1, $3); } X | expr OR expr X { $$ = tt_make_expr(E_OR, $1, $3); } X | expr XOR expr X { $$ = tt_make_expr(E_XOR, $1, $3); } X | expr LOGICAL_AND expr X { $$ = tt_make_expr(E_LOGICAL_AND, $1, $3); } X | expr LOGICAL_OR expr X { $$ = tt_make_expr(E_LOGICAL_OR, $1, $3); } X | expr LEFT_SHIFT expr X { $$ = tt_make_expr(E_LEFT_SHIFT, $1, $3); } X | expr RIGHT_SHIFT expr X { $$ = tt_make_expr(E_RIGHT_SHIFT, $1, $3); } X | expr LESS expr X { $$ = tt_make_expr(E_LESS, $1, $3); } X | expr LESS_EQUAL expr X { $$ = tt_make_expr(E_LESS_EQUAL, $1, $3); } X | expr EQUAL expr X { $$ = tt_make_expr(E_EQUAL, $1, $3); } X | expr GREATER_EQUAL expr X { $$ = tt_make_expr(E_GREATER_EQUAL, $1, $3); } X | expr GREATER expr X { $$ = tt_make_expr(E_GREATER, $1, $3); } X | expr NOT_EQUAL expr X { $$ = tt_make_expr(E_NOT_EQUAL, $1, $3); } X | expr COMMA expr X { $$ = tt_make_expr(E_COMMA, $1, $3); } X | MINUS expr %prec UMINUS X { $$ = tt_make_expr(E_UMINUS, $2); } X | COMPLEMENT expr X { $$ = tt_make_expr(E_COMPLEMENT, $2); } X | LOGICAL_NOT expr X { $$ = tt_make_expr(E_LOGICAL_NOT, $2); } X | DECREMENT array_ref X { if ($2->op == E_FUNC_ID) X yyerror("cannot decrement an intrinsic function"); X $$ = tt_make_expr(E_PREDECREMENT, $2); X } X | INCREMENT array_ref X { if ($2->op == E_FUNC_ID) X yyerror("cannot increment an intrinsic function"); X $$ = tt_make_expr(E_PREINCREMENT, $2); X } X | array_ref DECREMENT X { if ($1->op == E_FUNC_ID) X yyerror("cannot decrement an intrinsic function"); X $$ = tt_make_expr(E_POSTDECREMENT, $1); X } X | array_ref INCREMENT X { if ($1->op == E_FUNC_ID) X yyerror("cannot increment an intrinsic function"); X $$ = tt_make_expr(E_POSTINCREMENT, $1); X } X | expr QUESTION expr COLON expr X { $$ = tt_make_expr(E_QUESTION, $1, $3, $5); } X ; X Xfactor : array_ref %prec ARRAY_REF X | STRING X { $$ = tt_make_expr(E_STRING, $1); } X | INTEGER X { double temp; X X temp = (double) $1; X $$ = tt_make_expr(E_NUMBER, &temp); X } X | REAL X { $$ = tt_make_expr(E_NUMBER, &($1)); } X ; X Xarray_ref : ID %prec ARRAY_REF X { $$ = tt_make_expr(E_SYMBOL, tt_find_symbol($1)); } X | ID LPAREN optional_expr RPAREN %prec LPAREN X { f_ptr func; X X if ((func = tt_is_function($1)) == NULL) X yyerror("'%s' is not a valid function name", $1); X $$ = tt_make_expr(E_FUNC_ID, func, $3); X } X | array_ref LBRACK expr RBRACK X { $$ = tt_make_expr(E_ARRAY_REF, $1, $3); } X ; X Xdialogs : empty X | dialogs dialog_box X ; X Xdialog_box : DIALOG ID X { s_ptr s; X X curr_window = tt_make_base_window(); X curr_window->next = tt_base_window->next; X tt_base_window->next = curr_window; X s = tt_find_symbol($2); X if (s->kind == SYMBOL_SYMBOL) X s->kind = SYMBOL_DIALOG; X else if (s->kind == SYMBOL_GADGET) X yyerror("%s: name is already in use as a gadget", $2); X else if (s->dialog != NULL) X yyerror("%s: name is already in use as a dialog box", $2); X s->dialog = curr_window; X curr_window->is_open = FALSE; X } X dialog_attr gadgets END_DIALOG X { curr_window->gadgets = $5; } X ; X Xdialog_attr : empty X | dialog_attr size X | dialog_attr position X | dialog_attr label X { if (curr_window->label == NULL) X curr_window->label = $2; X else X yyerror("Conflicting window label specifications"); X } X | dialog_attr open X { if (curr_window->open_action == NULL) X curr_window->open_action = $2; X else X yyerror("Conflicting window opening strings"); X } X | dialog_attr close X { if (curr_window->close_action == NULL) X curr_window->close_action = $2; X else X yyerror("Conflicting window closing strings"); X } X ; X X Xkeys : empty X | KEYS key_attr key_list END_KEYS X ; X Xkey_attr : empty X | key_attr DISABLE NORMAL_KEYS X { tt_normal_off = TRUE; } X | key_attr DISABLE FUNCTION_KEYS X { tt_function_off = TRUE; } X ; X Xkey_list : empty X | key_list key_entry X ; X Xkey_entry : KEY key_name X { if ($2 >= L2 && $2 <= L10) { X curr_key_set = LEFT_KEY_SET; X curr_key = $2 - L2 + 1; X } X else if ($2 >= F1 && $2 <= F9) { X curr_key_set = TOP_KEY_SET; X curr_key = $2 - F1; X } X else { X curr_key_set = RIGHT_KEY_SET; X curr_key = $2 - R1; X } X } X key_value_list END_KEY X ; X Xkey_name : L2 | L3 | L4 | L5 | L6 | L7 | L8 | L9 | L10 X | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 X | R1 | R2 | R3 | R4 | R5 | R6 | R7 | R8 | R9 | R10 | R11 | R12 | R13 | R14 | R15 X ; X Xkey_value_list : key_value_entry X | key_value_list key_value_entry X ; X Xkey_value_entry : shifts action X { tt_func_keys[curr_key_set][curr_key][$1] = $2; } X ; X Xmouse : empty X | MOUSE mouse_attr mouse_list END_MOUSE X ; X Xmouse_attr : empty X | BASE INTEGER size_unit X { tt_mouse_base = $2; X tt_mouse_chars = $3; X } X ; X Xmouse_list : empty X | mouse_list mouse_entry X ; X Xmouse_entry : BUTTON button_name X { curr_key = $2; } X mouse_values END_BUTTON X ; X Xbutton_name : LEFT X { $$ = MOUSE_LEFT; } X | MIDDLE X { $$ = MOUSE_CENTER; } X | RIGHT X { $$ = MOUSE_RIGHT; } X ; X Xmouse_values : empty X | mouse_values mouse_value X ; X Xmouse_value : shifts action X { tt_mouse[curr_key][$1].defined = MOUSE_STRING; X tt_mouse[curr_key][$1].action = $2; X } X | shifts menu X { tt_mouse[curr_key][$1].defined = MOUSE_MENU; X tt_mouse[curr_key][$1].menu = $2; X } X ; X Xempty : ; X X%% X XPRIVATE yyerror(s1, s2, s3, s4, s5, s6, s7) X Xchar *s1, *s2, *s3, *s4, *s5, *s6, *s7; X X{ X fprintf(stderr, "%s: line %d: ", tt_curr_file, line_count - ((ungetc == '\n')? 1 : 0)); X fprintf(stderr, s1, s2, s3, s4, s5, s6, s7); X if (strcmp(s1, "syntax error") == 0) X print_last_token(); X fprintf(stderr, "\n"); X yyclearin; X tt_errors_occured++; X} X X#include "lex.c" X END_OF_FILE if test 28618 -ne `wc -c <'parse.y'`; then echo shar: \"'parse.y'\" unpacked with wrong size! fi # end of 'parse.y' fi echo shar: End of archive 8 \(of 13\). cp /dev/null ark8isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 13 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 Chuck Musciano ARPA : chuck@trantor.harris-atd.com Harris Corporation Usenet: ...!uunet!x102a!trantor!chuck PO Box 37, MS 3A/1912 AT&T : (407) 727-6131 Melbourne, FL 32902 FAX : (407) 727-{5118,5227,4004}