home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / sun / volume1 / tooltool2.1c / part08 / parse.y
Encoding:
Text File  |  1989-06-06  |  27.9 KB  |  1,012 lines

  1. /************************************************************************/
  2. /*    Copyright 1988 by Chuck Musciano and Harris Corporation        */
  3. /*                                    */
  4. /*    Permission to use, copy, modify, and distribute this software    */
  5. /*    and its documentation for any purpose and without fee is    */
  6. /*    hereby granted, provided that the above copyright notice    */
  7. /*    appear in all copies and that both that copyright notice and    */
  8. /*    this permission notice appear in supporting documentation, and    */
  9. /*    that the name of Chuck Musciano and Harris Corporation not be    */
  10. /*    used in advertising or publicity pertaining to distribution    */
  11. /*    of the software without specific, written prior permission.    */
  12. /*    Chuck Musciano and Harris Corporation make no representations    */
  13. /*    about the suitability of this software for any purpose.  It is    */
  14. /*    provided "as is" without express or implied warranty.        */
  15. /*                                    */
  16. /*    The sale of any product based wholely or in part upon the     */
  17. /*    technology provided by tooltool is strictly forbidden without    */
  18. /*    specific, prior written permission from Harris Corporation.    */
  19. /*    Tooltool technology includes, but is not limited to, the source    */
  20. /*    code, executable binary files, specification language, and    */
  21. /*    sample specification files.                    */
  22. /************************************************************************/
  23.  
  24.  
  25. %{
  26.  
  27. #include    <stdio.h>
  28. #include    <ctype.h>
  29.  
  30. #include    "tooltool.h"
  31.  
  32. PUBLIC    Menu    ttymenu_proc();
  33.  
  34. PRIVATE    int    line_count = 1;
  35. PRIVATE    int    curr_key, curr_key_set;
  36. PRIVATE    g_ptr    curr_gadget = NULL;
  37. PRIVATE    d_ptr    curr_window = NULL;
  38. PRIVATE    char    ungetc = -1;
  39.  
  40. %}
  41.  
  42. %start    tool_spec
  43.  
  44. %union    {a_ptr        aval;
  45.      int        ival;
  46.      char        *cpval;
  47.      cv_ptr        cvval;
  48.      e_ptr        eval;
  49.      g_ptr        gval;
  50.      l_ptr        lval;
  51.      Menu        mval;
  52.      Menu_item    mival;
  53.      double        rval;
  54.     }
  55.  
  56. %token    <cpval>    ICON_STRING ID STRING
  57. %token    <ival>    INTEGER
  58. %token    <rval>    REAL
  59. %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
  60.  
  61. %token        AND ASSIGN_AND ASSIGN_DIVIDE ASSIGN_MINUS ASSIGN_MODULO ASSIGN_OR ASSIGN_PLUS
  62. %token        ASSIGN_TIMES ASSIGN_XOR ASSIGNMENT COLON COMMA COMPLEMENT DECREMENT DIVIDE EQUAL
  63. %token        GREATER GREATER_EQUAL INCREMENT LBRACE LBRACK LEFT_SHIFT LESS LESS_EQUAL
  64. %token        LOGICAL_AND LOGICAL_NOT LOGICAL_OR LPAREN MINUS MODULO NOT_EQUAL OR PLUS
  65. %token        QUESTION RBRACE RBRACK RIGHT_SHIFT RPAREN SEMICOLON TIMES XOR
  66.  
  67. %token        ACTION ALIGN APPLICATION AT BASE BEEP BOTTOM BREAK BUTTON BY CENTER
  68. %token        CHARACTERS CHOICE CLOSE COMPLETION CONTINUE CONTROL CURRENT CYCLE DIALOG DISABLE
  69. %token        DISPLAY ELSE END_BUTTON END_CHOICE END_DIALOG END_GADGETS END_KEY END_KEYS
  70. %token        END_LABEL END_MENU END_MOUSE END_SLIDER END_TEXT EXIT FONT FOR
  71. %token        FUNCTION_KEYS GADGETS HORIZONTAL ICON IF IGNORE INITIAL INITIALIZE
  72. %token        KEY KEYS LABEL LEFT MARK MAXIMUM MENU META MIDDLE MINIMUM MOUSE
  73. %token        NOMARK NORMAL NORMAL_KEYS NOTHING OFF ON OPEN PIXELS POPUP
  74. %token        PROPORTIONAL RAGGED RANGE REMOVE RETAIN RIGHT SEND SHIFT SIZE
  75. %token        SLIDER TEXT TIMER TOP TRIGGER TTYMENU VALUE VERTICAL WHILE WIDTH
  76.  
  77. %type    <aval>    action action_list open close initialize timer
  78. %type    <ival>    size_unit shifts key_name button_name align
  79. %type    <cpval>    label font icon optional_name
  80. %type    <cvval>    choice_list
  81. %type    <eval>    array_ref expr factor optional_expr
  82. %type    <gval>    gadgets gadget_list gadget button_gadget choice_gadget
  83.         label_gadget menu_gadget slider_gadget text_gadget
  84. %type    <lval>    icon_label
  85. %type    <mval>    menu menu_value
  86. %type    <mival>    menu_entry
  87.  
  88. %left    ACTION
  89. %left    ELSE
  90. %left    EXPR
  91. %left    SEMICOLON
  92. %left    ARRAY_REF
  93.  
  94. %right    ASSIGNMENT ASSIGN_AND ASSIGN_DIVIDE ASSIGN_MINUS ASSIGN_MODULO ASSIGN_OR ASSIGN_PLUS ASSIGN_TIMES ASSIGN_XOR
  95. %left    COMMA
  96. %right    QUESTION COLON
  97. %left    LOGICAL_OR
  98. %left    LOGICAL_AND
  99. %left    OR
  100. %left    XOR
  101. %left    AND
  102. %left    EQUAL NOT_EQUAL
  103. %left    LESS LESS_EQUAL GREATER GREATER_EQUAL
  104. %left    LEFT_SHIFT RIGHT_SHIFT
  105. %left    PLUS MINUS
  106. %left    TIMES DIVIDE MODULO
  107. %right    DECREMENT INCREMENT UMINUS COMPLEMENT LOGICAL_NOT
  108. %left    LPAREN RPAREN
  109.  
  110. %%
  111.  
  112. tool_spec    :    APPLICATION STRING
  113.                     { curr_window = tt_base_window; }
  114.             appl_attr gadgets dialogs keys mouse
  115.                     { tt_application = $2;
  116.                       tt_base_window->gadgets = $5;
  117.                       tt_base_window->is_base_frame = TRUE;
  118.                     }
  119.         ;
  120.  
  121. appl_attr    :    empty
  122.         |    appl_attr size
  123.         |    appl_attr position
  124.         |    appl_attr icon
  125.                     { if (tt_icon == NULL)
  126.                          tt_icon = $2;
  127.                       else
  128.                          yyerror("Conflicting application icon specifications");
  129.                     }
  130.         |    appl_attr label
  131.                     { if (curr_window->label == NULL)
  132.                          curr_window->label = $2;
  133.                       else
  134.                          yyerror("Conflicting window label specifications");
  135.                     }
  136.         |    appl_attr font
  137.                     { if (tt_a_font == tt_default_font)
  138.                          tt_a_font = tt_open_font($2);
  139.                       else
  140.                          yyerror("Conflicting application font specifications");
  141.                     }
  142.         |    appl_attr open
  143.                     { if (curr_window->open_action == NULL)
  144.                          curr_window->open_action = $2;
  145.                       else
  146.                          yyerror("Conflicting window opening strings");
  147.                     }
  148.         |    appl_attr close
  149.                     { if (curr_window->close_action == NULL)
  150.                          curr_window->close_action = $2;
  151.                       else
  152.                          yyerror("Conflicting window closing strings");
  153.                     }
  154.         |    appl_attr initialize
  155.                     { if (tt_initial_action == NULL)
  156.                          tt_initial_action = $2;
  157.                       else
  158.                          yyerror("Conflicting initial command strings");
  159.                     }
  160.         |    appl_attr timer
  161.                     { if (tt_timer_action == NULL)
  162.                          tt_timer_action = $2;
  163.                       else
  164.                          yyerror("Conflicting timer command strings");
  165.                     }
  166.         ;
  167.  
  168. size        :    SIZE INTEGER BY INTEGER size_unit
  169.                     { curr_window->rows = $2;
  170.                       curr_window->columns = $4;
  171.                       curr_window->is_chars = $5;
  172.                     }
  173.         ;
  174.  
  175. position    :    AT INTEGER INTEGER
  176.                     { curr_window->win_x = $2;
  177.                       curr_window->win_y = $3;
  178.                     }
  179.         ;
  180.  
  181. size_unit    :    CHARACTERS
  182.                     { $$ = TRUE; }
  183.         |    PIXELS
  184.                     { $$ = FALSE; }
  185.         ;
  186.  
  187. icon        :    ICON STRING
  188.                     { $$ = $2; }
  189.         ;
  190.  
  191. label        :    LABEL STRING
  192.                     { $$ = $2; }
  193.         ;
  194.  
  195. font        :    FONT STRING
  196.                     { $$ = $2; }
  197.         ;
  198.  
  199. open        :    OPEN action
  200.                     { $$ = $2; }
  201.         ;
  202.  
  203. close        :    CLOSE action
  204.                     { $$ = $2; }
  205.         ;
  206.  
  207. initialize    :    INITIALIZE action
  208.                     { $$ = $2; }
  209.         ;
  210.  
  211. timer        :    TIMER action
  212.                     { $$ = $2; }
  213.         ;
  214.  
  215. gadgets        :    empty
  216.                     { $$ = (g_ptr) 0; }
  217.         |    GADGETS gadget_attr gadget_list END_GADGETS
  218.                     { if (curr_window->gadget_pos == G_NOPOS)
  219.                          curr_window->gadget_pos = G_TOP;
  220.                       $$ = $3;
  221.                     }
  222.         ;
  223.  
  224. gadget_attr    :    empty
  225.         |    gadget_attr TOP
  226.                     { if (curr_window->gadget_pos == G_NOPOS)
  227.                          curr_window->gadget_pos = G_TOP;
  228.                       else
  229.                          yyerror("Conflicting gadget position specified");
  230.                     }
  231.         |    gadget_attr BOTTOM
  232.                     { if (curr_window->gadget_pos == G_NOPOS)
  233.                          curr_window->gadget_pos = G_BOTTOM;
  234.                       else
  235.                          yyerror("Conflicting gadget position specified");
  236.                     }
  237.         |    gadget_attr LEFT
  238.                     { if (curr_window->gadget_pos == G_NOPOS)
  239.                          curr_window->gadget_pos = G_LEFT;
  240.                       else
  241.                          yyerror("Conflicting gadget position specified");
  242.                     }
  243.         |    gadget_attr RIGHT
  244.                     { if (curr_window->gadget_pos == G_NOPOS)
  245.                          curr_window->gadget_pos = G_RIGHT;
  246.                       else
  247.                          yyerror("Conflicting gadget position specified");
  248.                     }
  249.         |    gadget_attr PROPORTIONAL
  250.                     { curr_window->proportional = TRUE; }
  251.         |    gadget_attr RAGGED
  252.                     { curr_window->justified = FALSE; }
  253.         |    gadget_attr font
  254.                     { if (curr_window->g_font == tt_default_font)
  255.                          curr_window->g_font = tt_open_font($2);
  256.                       else
  257.                          yyerror("Conflicting gadget font specified");
  258.                     }
  259.         |    gadget_attr align
  260.                     { if (curr_window->g_align == NO_ALIGN)
  261.                          curr_window->g_align = $2;
  262.                       else
  263.                          yyerror("Conflicting gadget alignment specified");
  264.                     }
  265.         ;
  266.  
  267. align        :    ALIGN LEFT
  268.                     { $$ = ALIGN_TOP; }
  269.         |    ALIGN CENTER
  270.                     { $$ = ALIGN_MIDDLE; }
  271.         |    ALIGN RIGHT
  272.                     { $$ = ALIGN_BOTTOM; }
  273.         |    ALIGN TOP
  274.                     { $$ = ALIGN_TOP; }
  275.         |    ALIGN MIDDLE
  276.                     { $$ = ALIGN_MIDDLE; }
  277.         |    ALIGN BOTTOM
  278.                     { $$ = ALIGN_BOTTOM; }
  279.         ;
  280.  
  281. gadget_list    :    empty
  282.                     { $$ = NULL; }
  283.         |    gadget_list gadget
  284.                     { g_ptr    g;
  285.                       
  286.                       if ($1 == NULL)
  287.                          $$ = $2;
  288.                       else {
  289.                          for (g = $1; g->next; g = g->next)
  290.                             ;
  291.                          g->next = $2;
  292.                          $$ = $1;
  293.                          }
  294.                     }
  295.         ;
  296.  
  297. gadget        :    button_gadget
  298.         |    choice_gadget
  299.         |    label_gadget
  300.         |    menu_gadget
  301.         |    slider_gadget
  302.         |    text_gadget
  303.         ;
  304.  
  305. button_gadget    :    BUTTON optional_name
  306.                     { int    i;
  307.                       s_ptr    s;
  308.  
  309.                       curr_gadget = (g_ptr) safe_malloc(sizeof(g_data));
  310.                       curr_gadget->kind = GADGET_BUTTON;
  311.                       curr_gadget->name = NULL;
  312.                       curr_gadget->image = NULL;
  313.                       curr_gadget->x = -1;
  314.                       curr_gadget->next = NULL;
  315.                       for (i = 0; i < MAX_SHIFT_SETS; i++) {
  316.                          curr_gadget->u.but.label[i] = NULL;
  317.                          curr_gadget->u.but.action[i] = NULL;
  318.                          }
  319.                       if ($2 != NULL) {
  320.                          s = tt_find_symbol($2);
  321.                          if (s->kind != SYMBOL_SYMBOL)
  322.                             yyerror("Duplicate name: %s", s->name);
  323.                          s->kind = SYMBOL_GADGET;
  324.                          s->gadget = curr_gadget;
  325.                          }
  326.                     }
  327.             gadget_position value_list value_item END_BUTTON
  328.                     { if (curr_gadget->u.but.label[0] == NULL)
  329.                          yyerror("Every button must have a \"normal\" action");
  330.                       $$ = curr_gadget;
  331.                     }
  332.         ;
  333.  
  334. value_list    :    empty
  335.         |    value_list value_item
  336.         ;
  337.  
  338. value_item    :    shifts icon_label action
  339.                     { if (curr_gadget->u.but.label[$1] != NULL)
  340.                          yyerror("Duplicate button action");
  341.                       curr_gadget->u.but.label[$1] = $2;
  342.                       curr_gadget->u.but.action[$1] = $3;
  343.                     }
  344.         ;
  345.  
  346. shifts        :    empty
  347.                     { $$ = S_NORMAL; }
  348.         |    shifts NORMAL
  349.                     { $$ = $1 | S_NORMAL; }
  350.         |    shifts SHIFT
  351.                     { $$ = $1 | S_SHIFT; }
  352.         |    shifts CONTROL
  353.                     { $$ = $1 | S_CONTROL; }
  354.         |    shifts META
  355.                     { $$ = $1 | S_META; }
  356.         ;
  357.  
  358. choice_gadget    :    CHOICE optional_name
  359.                     { s_ptr    s;
  360.  
  361.                       curr_gadget = (g_ptr) safe_malloc(sizeof(g_data));
  362.                       curr_gadget->kind = GADGET_CHOICE;
  363.                       curr_gadget->name = $2;
  364.                       curr_gadget->image = NULL;
  365.                       curr_gadget->x = -1;
  366.                       curr_gadget->next = NULL;
  367.                       curr_gadget->u.cho.label = NULL;
  368.                       curr_gadget->u.cho.mode = CHOICE_CURRENT;
  369.                       curr_gadget->u.cho.mark = tt_default_mark;
  370.                       curr_gadget->u.cho.nomark = tt_default_nomark;
  371.                       curr_gadget->u.cho.value = NULL;
  372.                       if ($2 != NULL) {
  373.                          s = tt_find_symbol($2);
  374.                          if (s->kind != SYMBOL_SYMBOL)
  375.                             yyerror("Duplicate name: %s", s->name);
  376.                          s->kind = SYMBOL_GADGET;
  377.                          s->gadget = curr_gadget;
  378.                          }
  379.                     }
  380.             choice_attr choice_list END_CHOICE
  381.                     { curr_gadget->u.cho.value = $5;
  382.                       if (curr_gadget->u.cho.mode == CHOICE_CYCLE)
  383.                          if (curr_gadget->u.cho.mark == tt_default_mark)
  384.                             curr_gadget->u.cho.mark = curr_gadget->u.cho.nomark = tt_default_cycle;
  385.                          else
  386.                             curr_gadget->u.cho.nomark = curr_gadget->u.cho.mark;
  387.                       $$ = curr_gadget;
  388.                     }
  389.         ;
  390.  
  391. choice_attr    :    empty
  392.         |    choice_attr DISPLAY CURRENT
  393.                     { curr_gadget->u.cho.mode = CHOICE_CURRENT; }
  394.         |    choice_attr DISPLAY CYCLE
  395.                     { curr_gadget->u.cho.mode = CHOICE_CYCLE; }
  396.         |    choice_attr DISPLAY HORIZONTAL
  397.                     { curr_gadget->u.cho.mode = CHOICE_HORIZONTAL; }
  398.         |    choice_attr DISPLAY VERTICAL
  399.                     { curr_gadget->u.cho.mode = CHOICE_VERTICAL; }
  400.         |    choice_attr MARK icon_label
  401.                     { curr_gadget->u.cho.mark = $3; }
  402.         |    choice_attr NOMARK icon_label
  403.                     { curr_gadget->u.cho.nomark = $3; }
  404.         |    choice_attr LABEL icon_label
  405.                     { curr_gadget->u.cho.label = $3; }
  406.         |    choice_attr AT INTEGER INTEGER
  407.                     { curr_gadget->x = $3;
  408.                       curr_gadget->y = $4;
  409.                     }
  410.         ;
  411.  
  412. choice_list    :    empty
  413.                     { $$ = NULL; }
  414.         |    choice_list icon_label action
  415.                     { cv_ptr curr, head;
  416.                     
  417.                       curr = (cv_ptr) safe_malloc(sizeof(cv_data));
  418.                       curr->label = $2;
  419.                       curr->action = $3;
  420.                       curr->next = NULL;
  421.                       if ($1 == NULL)
  422.                          $$ = curr;
  423.                       else {
  424.                          for (head = $1; head->next; head = head->next)
  425.                             ;
  426.                          head->next = curr;
  427.                          $$ = $1;
  428.                          }
  429.                     }
  430.         ;
  431.  
  432. label_gadget    :    LABEL optional_name
  433.                     { s_ptr    s;
  434.  
  435.                       curr_gadget = (g_ptr) safe_malloc(sizeof(g_data));
  436.                       curr_gadget->kind = GADGET_LABEL;
  437.                       curr_gadget->name = NULL;
  438.                       curr_gadget->image = NULL;
  439.                       curr_gadget->x = -1;
  440.                       curr_gadget->next = NULL;
  441.                       if ($2 != NULL) {
  442.                          s = tt_find_symbol($2);
  443.                          if (s->kind != SYMBOL_SYMBOL)
  444.                             yyerror("Duplicate name: %s", s->name);
  445.                          s->kind = SYMBOL_GADGET;
  446.                          s->gadget = curr_gadget;
  447.                          }
  448.                     }
  449.             gadget_position icon_label END_LABEL
  450.                     { curr_gadget->u.lab.label = $5;
  451.                       $$ = curr_gadget;
  452.                     }
  453.         ;
  454.  
  455. menu_gadget    :    MENU optional_name
  456.                     { s_ptr    s;
  457.  
  458.                       curr_gadget = (g_ptr) safe_malloc(sizeof(g_data));
  459.                       curr_gadget->kind = GADGET_MENU;
  460.                       curr_gadget->name = NULL;
  461.                       curr_gadget->image = NULL;
  462.                       curr_gadget->x = -1;
  463.                       curr_gadget->next = NULL;
  464.                       if ($2 != NULL) {
  465.                          s = tt_find_symbol($2);
  466.                          if (s->kind != SYMBOL_SYMBOL)
  467.                             yyerror("Duplicate name: %s", s->name);
  468.                          s->kind = SYMBOL_GADGET;
  469.                          s->gadget = curr_gadget;
  470.                          }
  471.                     }
  472.             gadget_position icon_label menu_value END_MENU
  473.                     { curr_gadget->u.men.label = $5;
  474.                       curr_gadget->u.men.menu = $6;
  475.                       $$ = curr_gadget;
  476.                     }
  477.         ;
  478.  
  479. menu        :    MENU menu_value END_MENU
  480.                     { $$ = $2; }
  481.         |    TTYMENU
  482.                     { $$ = menu_create(MENU_GEN_PROC, ttymenu_proc, 0); }
  483.         ;
  484.  
  485. menu_value    :    menu_entry
  486.                     { $$ = menu_create(MENU_APPEND_ITEM, $1, 0); }
  487.         |    menu_value menu_entry
  488.                     { 
  489.                       menu_set($1, MENU_APPEND_ITEM, $2, 0);
  490.                       $$ = $1;
  491.                     }
  492.         ;
  493.  
  494. menu_entry    :    icon_label action
  495.                     {
  496.                       if ($1->is_icon)
  497.                          $$ = menu_create_item(MENU_IMAGE_ITEM, $1->image, $2, 0);
  498.                       else
  499.                          $$ = menu_create_item(MENU_STRING_ITEM, $1->label, $2, MENU_FONT, $1->font, 0);
  500.                     }
  501.         |    icon_label menu
  502.                     {
  503.                       if ($1->is_icon)
  504.                          $$ = menu_create_item(MENU_PULLRIGHT_IMAGE, $1->image, $2, 0);
  505.                       else
  506.                          $$ = menu_create_item(MENU_PULLRIGHT_ITEM, $1->label, $2, MENU_FONT, $1->font, 0);
  507.                     }
  508.         ;
  509.  
  510. slider_gadget    :    SLIDER optional_name
  511.                     { s_ptr    s;
  512.                     
  513.                       curr_gadget = (g_ptr) safe_malloc(sizeof(g_data));
  514.                       curr_gadget->kind = GADGET_SLIDER;
  515.                       curr_gadget->name = $2;
  516.                       curr_gadget->image = NULL;
  517.                       curr_gadget->x = -1;
  518.                       curr_gadget->next = NULL;
  519.                       curr_gadget->u.sli.label = NULL;
  520.                       curr_gadget->u.sli.minimum = 0;
  521.                       curr_gadget->u.sli.maximum = 100;
  522.                       curr_gadget->u.sli.initial = 0;
  523.                       curr_gadget->u.sli.value = TRUE;
  524.                       curr_gadget->u.sli.range = TRUE;
  525.                       curr_gadget->u.sli.width = 100;
  526.                       curr_gadget->u.sli.action = NULL;
  527.                       curr_gadget->u.sli.font = curr_window->g_font;
  528.                       if ($2 != NULL) {
  529.                          s = tt_find_symbol($2);
  530.                          if (s->kind != SYMBOL_SYMBOL)
  531.                             yyerror("Duplicate name: %s", s->name);
  532.                          s->kind = SYMBOL_GADGET;
  533.                          s->gadget = curr_gadget;
  534.                          }
  535.                     }
  536.             slider_attr END_SLIDER
  537.                     {
  538.                       if (curr_gadget->u.sli.minimum > curr_gadget->u.sli.maximum)
  539.                          yyerror("Slider maximum must exceed slider minimum");
  540.                       if (curr_gadget->u.sli.initial < curr_gadget->u.sli.minimum ||
  541.                           curr_gadget->u.sli.initial > curr_gadget->u.sli.maximum)
  542.                          yyerror("Slider initial value must in the range [minimum, maximum]");
  543.                       $$ = curr_gadget;
  544.                     }
  545.         ;
  546.  
  547. slider_attr    :    empty
  548.         |    slider_attr ACTION action
  549.                     { curr_gadget->u.sli.action = $3; }
  550.         |    slider_attr FONT STRING
  551.                     { curr_gadget->u.sli.font = tt_open_font($3); }
  552.         |    slider_attr INITIAL INTEGER
  553.                     { curr_gadget->u.sli.initial = $3; }
  554.         |    slider_attr LABEL icon_label
  555.                     { curr_gadget->u.sli.label = $3; }
  556.         |    slider_attr MAXIMUM INTEGER
  557.                     { curr_gadget->u.sli.maximum = $3; }
  558.         |    slider_attr MINIMUM INTEGER
  559.                     { curr_gadget->u.sli.minimum = $3; }
  560.         |    slider_attr RANGE OFF
  561.                     { curr_gadget->u.sli.range = FALSE; }
  562.         |    slider_attr RANGE ON
  563.                     { curr_gadget->u.sli.range = TRUE; }
  564.         |    slider_attr VALUE OFF
  565.                     { curr_gadget->u.sli.value = FALSE; }
  566.         |    slider_attr VALUE ON
  567.                     { curr_gadget->u.sli.value = TRUE; }
  568.         |    slider_attr WIDTH INTEGER
  569.                     { curr_gadget->u.sli.width = $3; }
  570.         |    slider_attr AT INTEGER INTEGER
  571.                     { curr_gadget->x = $3;
  572.                       curr_gadget->y = $4;
  573.                     }
  574.         ;
  575.  
  576. text_gadget    :    TEXT optional_name
  577.                     { s_ptr    s;
  578.  
  579.                       curr_gadget = (g_ptr) safe_malloc(sizeof(g_data));
  580.                       curr_gadget->kind = GADGET_TEXT;
  581.                       curr_gadget->name = $2;
  582.                       curr_gadget->image = NULL;
  583.                       curr_gadget->x = -1;
  584.                       curr_gadget->next = NULL;
  585.                       curr_gadget->u.tex.label = NULL;
  586.                       curr_gadget->u.tex.trigger = "\n\r";
  587.                       curr_gadget->u.tex.completion = "";
  588.                       curr_gadget->u.tex.ignore = tt_expand_ranges("\001-\037");
  589.                       curr_gadget->u.tex.display_len = 80;
  590.                       curr_gadget->u.tex.retain_len = 256;
  591.                       curr_gadget->u.tex.action = NULL;
  592.                       curr_gadget->u.tex.font = curr_window->g_font;
  593.                       curr_window->text_items_exist = TRUE;
  594.                       if ($2 != NULL) {
  595.                          s = tt_find_symbol($2);
  596.                          if (s->kind != SYMBOL_SYMBOL)
  597.                             yyerror("Duplicate name: %s", s->name);
  598.                          s->kind = SYMBOL_GADGET;
  599.                          s->gadget = curr_gadget;
  600.                          }
  601.                     }
  602.             text_attr END_TEXT
  603.                     { $$ = curr_gadget; }
  604.         ;
  605.  
  606. text_attr    :    empty
  607.         |    text_attr ACTION action
  608.                     { curr_gadget->u.tex.action = $3; }
  609.         |    text_attr AT INTEGER INTEGER
  610.                     { curr_gadget->x = $3;
  611.                       curr_gadget->y = $4;
  612.                     }
  613.         |    text_attr COMPLETION STRING
  614.                     { curr_gadget->u.tex.completion = tt_expand_ranges($3); }
  615.         |    text_attr DISPLAY INTEGER
  616.                     { curr_gadget->u.tex.display_len = $3; }
  617.         |    text_attr FONT STRING
  618.                     { curr_gadget->u.tex.font = tt_open_font($3); }
  619.         |    text_attr IGNORE STRING
  620.                     { curr_gadget->u.tex.ignore = tt_expand_ranges($3); }
  621.         |    text_attr LABEL icon_label
  622.                     { curr_gadget->u.tex.label = $3; }
  623.         |    text_attr RETAIN INTEGER
  624.                     { curr_gadget->u.tex.retain_len = $3; }
  625.         |    text_attr TRIGGER STRING
  626.                     { curr_gadget->u.tex.trigger = tt_expand_ranges($3); }
  627.         ;
  628.  
  629. icon_label    :    STRING
  630.                     { $$ = tt_make_label(FALSE, $1, curr_window->g_font, NULL); }
  631.         |    STRING COLON STRING
  632.                     { $$ = tt_make_label(FALSE, $1, tt_open_font($3), NULL); }
  633.         |    ICON_STRING
  634.                     { $$ = tt_make_label(TRUE, NULL, NULL, tt_load_icon($1)); }
  635.         ;
  636.  
  637. optional_name    :    empty
  638.                     { $$ = NULL; }
  639.         |    ID
  640.                     { $$ = $1; }
  641.         ;
  642.  
  643. gadget_position    :    empty
  644.         |    AT INTEGER INTEGER
  645.                     { curr_gadget->x = $2;
  646.                       curr_gadget->y = $3;
  647.                     }
  648.         ;
  649.  
  650. action        :    SEMICOLON
  651.                     { $$ = NULL; }
  652.         |    BEEP SEMICOLON
  653.                     { $$ = tt_make_action(BEEP_OP); }
  654.         |    BREAK SEMICOLON
  655.                     { $$ = tt_make_action(BREAK_OP); }
  656.         |    CLOSE %prec ACTION
  657.                     { $$ = tt_make_action(CLOSE_OP); }
  658.         |    CLOSE SEMICOLON
  659.                     { $$ = tt_make_action(CLOSE_OP); }
  660.         |    CONTINUE SEMICOLON
  661.                     { $$ = tt_make_action(CONTINUE_OP); }
  662.         |    DISPLAY ID SEMICOLON
  663.                     { $$ = tt_make_action(DISPLAY_OP, tt_make_expr(E_SYMBOL, tt_find_symbol($2))); }
  664.         |    EXIT %prec ACTION
  665.                     { $$ = tt_make_action(EXIT_OP); }
  666.         |    EXIT SEMICOLON
  667.                     { $$ = tt_make_action(EXIT_OP); }
  668.         |    expr %prec EXPR
  669.                     { $$ = tt_make_action(($1->op == E_STRING)? SEND_OP : EXPR_OP, $1); }
  670.         |    expr SEMICOLON %prec EXPR
  671.                     { $$ = tt_make_action(($1->op == E_STRING)? SEND_OP : EXPR_OP, $1); }
  672.         |    FOR LPAREN optional_expr SEMICOLON optional_expr SEMICOLON optional_expr RPAREN action
  673.                     { $$ = tt_make_action(FOR_OP, $3, $5, $7, $9); }
  674.         |    IF LPAREN expr RPAREN action %prec ACTION
  675.                     { $$ = tt_make_action(IF_OP, $3, $5, NULL); }
  676.         |    IF LPAREN expr RPAREN action ELSE action %prec ELSE
  677.                     { $$ = tt_make_action(IF_OP, $3, $5, $7); }
  678.         |    LBRACE action_list RBRACE
  679.                     { $$ = $2; }
  680.         |    NOTHING SEMICOLON
  681.                     { $$ = NULL; }
  682.         |    OPEN SEMICOLON
  683.                     { $$ = tt_make_action(OPEN_OP); }
  684.         |    POPUP ID SEMICOLON
  685.                     { $$ = tt_make_action(POPUP_OP, tt_make_expr(E_SYMBOL, tt_find_symbol($2))); }
  686.         |    REMOVE ID SEMICOLON
  687.                     { $$ = tt_make_action(REMOVE_OP, tt_make_expr(E_SYMBOL, tt_find_symbol($2))); }
  688.         |    SEND expr SEMICOLON %prec EXPR
  689.                     { $$ = tt_make_action(SEND_OP, $2); }
  690.         |    WHILE LPAREN expr RPAREN action
  691.                     { $$ = tt_make_action(WHILE_OP, $3, $5); }
  692.         ;
  693.  
  694. action_list    :    empty
  695.                     { $$ = NULL; }
  696.         |    action action_list
  697.                     { a_ptr    a;
  698.  
  699.                       if ($1 == NULL)
  700.                          $$ = $2;
  701.                       else {
  702.                          for (a = $1; a->next != NULL; a = a->next)
  703.                             ;
  704.                          a->next = $2;
  705.                          $$ = $1;
  706.                          }
  707.                     }
  708.         ;
  709.  
  710. optional_expr    :    empty
  711.                     { $$ = NULL; }
  712.         |    expr
  713.         ;
  714.  
  715. expr        :    factor
  716.         |    array_ref ASSIGNMENT expr
  717.                     { if ($1->op == E_FUNC_ID)
  718.                          yyerror("cannot assign to an intrinsic function");
  719.                       $$ = tt_make_expr(E_ASSIGNMENT, $1, $3);
  720.                     }
  721.         |    array_ref ASSIGN_AND expr
  722.                     { if ($1->op == E_FUNC_ID)
  723.                          yyerror("cannot assign to an intrinsic function");
  724.                       $$ = tt_make_expr(E_ASSIGN_AND, $1, $3);
  725.                     }
  726.         |    array_ref ASSIGN_DIVIDE expr
  727.                     { if ($1->op == E_FUNC_ID)
  728.                          yyerror("cannot assign to an intrinsic function");
  729.                       $$ = tt_make_expr(E_ASSIGN_DIVIDE, $1, $3);
  730.                     }
  731.         |    array_ref ASSIGN_MINUS expr
  732.                     { if ($1->op == E_FUNC_ID)
  733.                          yyerror("cannot assign to an intrinsic function");
  734.                       $$ = tt_make_expr(E_ASSIGN_MINUS, $1, $3);
  735.                     }
  736.         |    array_ref ASSIGN_MODULO expr
  737.                     { if ($1->op == E_FUNC_ID)
  738.                          yyerror("cannot assign to an intrinsic function");
  739.                       $$ = tt_make_expr(E_ASSIGN_MODULO, $1, $3);
  740.                     }
  741.         |    array_ref ASSIGN_OR expr
  742.                     { if ($1->op == E_FUNC_ID)
  743.                          yyerror("cannot assign to an intrinsic function");
  744.                       $$ = tt_make_expr(E_ASSIGN_OR, $1, $3);
  745.                     }
  746.         |    array_ref ASSIGN_PLUS expr
  747.                     { if ($1->op == E_FUNC_ID)
  748.                          yyerror("cannot assign to an intrinsic function");
  749.                       $$ = tt_make_expr(E_ASSIGN_PLUS, $1, $3);
  750.                     }
  751.         |    array_ref ASSIGN_TIMES expr
  752.                     { if ($1->op == E_FUNC_ID)
  753.                          yyerror("cannot assign to an intrinsic function");
  754.                       $$ = tt_make_expr(E_ASSIGN_TIMES, $1, $3);
  755.                     }
  756.         |    array_ref ASSIGN_XOR expr
  757.                     { if ($1->op == E_FUNC_ID)
  758.                          yyerror("cannot assign to an intrinsic function");
  759.                       $$ = tt_make_expr(E_ASSIGN_XOR, $1, $3);
  760.                     }
  761.         |    LPAREN expr RPAREN
  762.                     { $$ = tt_make_expr(E_PAREN, $2); }
  763.         |    expr PLUS expr
  764.                     { $$ = tt_make_expr(E_PLUS, $1, $3); }
  765.         |    expr MINUS expr
  766.                     { $$ = tt_make_expr(E_MINUS, $1, $3); }
  767.         |    expr TIMES expr
  768.                     { $$ = tt_make_expr(E_TIMES, $1, $3); }
  769.         |    expr DIVIDE expr
  770.                     { $$ = tt_make_expr(E_DIVIDE, $1, $3); }
  771.         |    expr MODULO expr
  772.                     { $$ = tt_make_expr(E_MODULO, $1, $3); }
  773.         |    expr AND expr
  774.                     { $$ = tt_make_expr(E_AND, $1, $3); }
  775.         |    expr OR expr
  776.                     { $$ = tt_make_expr(E_OR, $1, $3); }
  777.         |    expr XOR expr
  778.                     { $$ = tt_make_expr(E_XOR, $1, $3); }
  779.         |    expr LOGICAL_AND expr
  780.                     { $$ = tt_make_expr(E_LOGICAL_AND, $1, $3); }
  781.         |    expr LOGICAL_OR expr
  782.                     { $$ = tt_make_expr(E_LOGICAL_OR, $1, $3); }
  783.         |    expr LEFT_SHIFT expr
  784.                     { $$ = tt_make_expr(E_LEFT_SHIFT, $1, $3); }
  785.         |    expr RIGHT_SHIFT expr
  786.                     { $$ = tt_make_expr(E_RIGHT_SHIFT, $1, $3); }
  787.         |    expr LESS expr
  788.                     { $$ = tt_make_expr(E_LESS, $1, $3); }
  789.         |    expr LESS_EQUAL expr
  790.                     { $$ = tt_make_expr(E_LESS_EQUAL, $1, $3); }
  791.         |    expr EQUAL expr
  792.                     { $$ = tt_make_expr(E_EQUAL, $1, $3); }
  793.         |    expr GREATER_EQUAL expr
  794.                     { $$ = tt_make_expr(E_GREATER_EQUAL, $1, $3); }
  795.         |    expr GREATER expr
  796.                     { $$ = tt_make_expr(E_GREATER, $1, $3); }
  797.         |    expr NOT_EQUAL expr
  798.                     { $$ = tt_make_expr(E_NOT_EQUAL, $1, $3); }
  799.         |    expr COMMA expr
  800.                     { $$ = tt_make_expr(E_COMMA, $1, $3); }
  801.         |    MINUS expr %prec UMINUS
  802.                     { $$ = tt_make_expr(E_UMINUS, $2); }
  803.         |    COMPLEMENT expr
  804.                     { $$ = tt_make_expr(E_COMPLEMENT, $2); }
  805.         |    LOGICAL_NOT expr
  806.                     { $$ = tt_make_expr(E_LOGICAL_NOT, $2); }
  807.         |    DECREMENT array_ref
  808.                     { if ($2->op == E_FUNC_ID)
  809.                          yyerror("cannot decrement an intrinsic function");
  810.                       $$ = tt_make_expr(E_PREDECREMENT, $2);
  811.                     }
  812.         |    INCREMENT array_ref
  813.                     { if ($2->op == E_FUNC_ID)
  814.                          yyerror("cannot increment an intrinsic function");
  815.                       $$ = tt_make_expr(E_PREINCREMENT, $2);
  816.                     }
  817.         |    array_ref DECREMENT
  818.                     { if ($1->op == E_FUNC_ID)
  819.                          yyerror("cannot decrement an intrinsic function");
  820.                       $$ = tt_make_expr(E_POSTDECREMENT, $1);
  821.                     }
  822.         |    array_ref INCREMENT
  823.                     { if ($1->op == E_FUNC_ID)
  824.                          yyerror("cannot increment an intrinsic function");
  825.                       $$ = tt_make_expr(E_POSTINCREMENT, $1);
  826.                     }
  827.         |    expr QUESTION expr COLON expr
  828.                     { $$ = tt_make_expr(E_QUESTION, $1, $3, $5); }
  829.         ;
  830.  
  831. factor        :    array_ref %prec ARRAY_REF
  832.         |    STRING
  833.                     { $$ = tt_make_expr(E_STRING, $1); }
  834.         |    INTEGER
  835.                     { double temp;
  836.  
  837.                       temp = (double) $1;
  838.                       $$ = tt_make_expr(E_NUMBER, &temp);
  839.                     }
  840.         |    REAL
  841.                     { $$ = tt_make_expr(E_NUMBER, &($1)); }
  842.         ;
  843.  
  844. array_ref    :    ID %prec ARRAY_REF
  845.                     { $$ = tt_make_expr(E_SYMBOL, tt_find_symbol($1)); }
  846.         |    ID LPAREN optional_expr RPAREN %prec LPAREN
  847.                     { f_ptr    func;
  848.  
  849.                       if ((func = tt_is_function($1)) == NULL)
  850.                          yyerror("'%s' is not a valid function name", $1);
  851.                       $$ = tt_make_expr(E_FUNC_ID, func, $3);
  852.                     }
  853.         |    array_ref LBRACK expr RBRACK
  854.                     { $$ = tt_make_expr(E_ARRAY_REF, $1, $3); }
  855.         ;
  856.  
  857. dialogs        :    empty
  858.         |    dialogs dialog_box
  859.         ;
  860.  
  861. dialog_box    :    DIALOG ID
  862.                     { s_ptr    s;
  863.                       
  864.                       curr_window = tt_make_base_window();
  865.                       curr_window->next = tt_base_window->next;
  866.                       tt_base_window->next = curr_window;
  867.                       s = tt_find_symbol($2);
  868.                       if (s->kind == SYMBOL_SYMBOL)
  869.                          s->kind = SYMBOL_DIALOG;
  870.                       else if (s->kind == SYMBOL_GADGET)
  871.                          yyerror("%s: name is already in use as a gadget", $2);
  872.                       else if (s->dialog != NULL)
  873.                          yyerror("%s: name is already in use as a dialog box", $2);
  874.                       s->dialog = curr_window;
  875.                       curr_window->is_open = FALSE;
  876.                     }
  877.             dialog_attr gadgets END_DIALOG
  878.                     { curr_window->gadgets = $5; }
  879.         ;
  880.  
  881. dialog_attr    :    empty
  882.         |    dialog_attr size
  883.         |    dialog_attr position
  884.         |    dialog_attr label
  885.                     { if (curr_window->label == NULL)
  886.                          curr_window->label = $2;
  887.                       else
  888.                          yyerror("Conflicting window label specifications");
  889.                     }
  890.         |    dialog_attr open
  891.                     { if (curr_window->open_action == NULL)
  892.                          curr_window->open_action = $2;
  893.                       else
  894.                          yyerror("Conflicting window opening strings");
  895.                     }
  896.         |    dialog_attr close
  897.                     { if (curr_window->close_action == NULL)
  898.                          curr_window->close_action = $2;
  899.                       else
  900.                          yyerror("Conflicting window closing strings");
  901.                     }
  902.         ;
  903.  
  904.  
  905. keys        :    empty
  906.         |    KEYS key_attr key_list END_KEYS
  907.         ;
  908.  
  909. key_attr    :    empty
  910.         |    key_attr DISABLE NORMAL_KEYS
  911.                     { tt_normal_off = TRUE; }
  912.         |    key_attr DISABLE FUNCTION_KEYS
  913.                     { tt_function_off = TRUE; }
  914.         ;
  915.  
  916. key_list    :    empty
  917.         |    key_list key_entry
  918.         ;
  919.  
  920. key_entry    :    KEY key_name
  921.                     { if ($2 >= L2 && $2 <= L10) {
  922.                          curr_key_set = LEFT_KEY_SET;
  923.                          curr_key = $2 - L2 + 1;
  924.                          }
  925.                       else if ($2 >= F1 && $2 <= F9) {
  926.                          curr_key_set = TOP_KEY_SET;
  927.                          curr_key = $2 - F1;
  928.                          }
  929.                       else {
  930.                          curr_key_set = RIGHT_KEY_SET;
  931.                          curr_key = $2 - R1;
  932.                          }
  933.                     }
  934.             key_value_list END_KEY
  935.         ;
  936.  
  937. key_name    :    L2 | L3 | L4 | L5 | L6 | L7 | L8 | L9 | L10
  938.         |    F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 
  939.         |    R1 | R2 | R3 | R4 | R5 | R6 | R7 | R8 | R9 | R10 | R11 | R12 | R13 | R14 | R15
  940.         ;
  941.  
  942. key_value_list    :    key_value_entry
  943.         |    key_value_list key_value_entry
  944.         ;
  945.  
  946. key_value_entry    :    shifts action
  947.                     { tt_func_keys[curr_key_set][curr_key][$1] = $2; }
  948.         ;
  949.  
  950. mouse        :    empty
  951.         |    MOUSE mouse_attr mouse_list END_MOUSE
  952.         ;
  953.  
  954. mouse_attr    :    empty
  955.         |    BASE INTEGER size_unit
  956.                     { tt_mouse_base = $2;
  957.                       tt_mouse_chars = $3;
  958.                     }
  959.         ;
  960.  
  961. mouse_list    :    empty
  962.         |    mouse_list mouse_entry
  963.         ;
  964.  
  965. mouse_entry    :    BUTTON button_name
  966.                     { curr_key = $2; }
  967.             mouse_values END_BUTTON
  968.         ;
  969.  
  970. button_name    :    LEFT
  971.                     { $$ = MOUSE_LEFT; }
  972.         |    MIDDLE
  973.                     { $$ = MOUSE_CENTER; }
  974.         |    RIGHT
  975.                     { $$ = MOUSE_RIGHT; }
  976.         ;
  977.  
  978. mouse_values    :    empty
  979.         |    mouse_values mouse_value
  980.         ;
  981.  
  982. mouse_value    :    shifts action
  983.                     { tt_mouse[curr_key][$1].defined = MOUSE_STRING;
  984.                       tt_mouse[curr_key][$1].action = $2;
  985.                     }
  986.         |    shifts menu
  987.                     { tt_mouse[curr_key][$1].defined = MOUSE_MENU;
  988.                       tt_mouse[curr_key][$1].menu = $2;
  989.                     }
  990.         ;
  991.  
  992. empty        : ;
  993.  
  994. %%
  995.  
  996. PRIVATE    yyerror(s1, s2, s3, s4, s5, s6, s7)
  997.  
  998. char    *s1, *s2, *s3, *s4, *s5, *s6, *s7;
  999.  
  1000. {
  1001.     fprintf(stderr, "%s: line %d: ", tt_curr_file, line_count - ((ungetc == '\n')? 1 : 0));
  1002.     fprintf(stderr, s1, s2, s3, s4, s5, s6, s7);
  1003.     if (strcmp(s1, "syntax error") == 0)
  1004.        print_last_token();
  1005.     fprintf(stderr, "\n");
  1006.     yyclearin;
  1007.     tt_errors_occured++;
  1008. }
  1009.  
  1010. #include "lex.c"
  1011.  
  1012.