Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!aramis.rutgers.edu!dartagnan.rutgers.edu!mcgrew From: mcgrew@dartagnan.rutgers.edu (Charles Mcgrew) Newsgroups: comp.sources.sun Subject: v01i027: Tooltool - a suntools user interface builder, Part08/13 Message-ID: Date: 7 Jun 89 04:22:08 GMT Organization: Rutgers Univ., New Brunswick, N.J. Lines: 1058 Approved: mcgrew@aramis.rutgers.edu Submitted-by: Chuck Musciano 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 '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 X#include 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 ICON_STRING ID STRING X%token INTEGER X%token REAL X%token 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 action action_list open close initialize timer X%type size_unit shifts key_name button_name align X%type label font icon optional_name X%type choice_list X%type array_ref expr factor optional_expr X%type gadgets gadget_list gadget button_gadget choice_gadget X label_gadget menu_gadget slider_gadget text_gadget X%type icon_label X%type menu menu_value X%type 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}