/[bison]/bison/tests/existing.at
ViewVC logotype

Diff of /bison/tests/existing.at

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.4 by eggert, Sun Dec 29 01:59:40 2002 UTC revision 1.5 by eggert, Fri Apr 18 05:10:58 2003 UTC
# Line 1  Line 1 
1  # Exercising Bison on actual grammars.                   -*- Autotest -*-  # Exercising Bison on actual grammars.                   -*- Autotest -*-
2  # Copyright (C) 2002 Free Software Foundation, Inc.  
3    # Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003
4    # Free Software Foundation, Inc.
5    
6  # This program is free software; you can redistribute it and/or modify  # This program is free software; you can redistribute it and/or modify
7  # it under the terms of the GNU General Public License as published by  # it under the terms of the GNU General Public License as published by
# Line 1207  State 427 conflicts: 9 shift/reduce, 2 r Line 1209  State 427 conflicts: 9 shift/reduce, 2 r
1209  ]])  ]])
1210    
1211  AT_CLEANUP  AT_CLEANUP
1212    
1213    
1214    ## ----------------- ##
1215    ## GNU pic Grammar.  ##
1216    ## ----------------- ##
1217    
1218    AT_SETUP([GNU pic Grammar])
1219    
1220    # GNU pic, part of groff.
1221    
1222    # Bison once reported shift/reduce conflicts that it shouldn't have.
1223    
1224    AT_DATA([[input.y]],
1225    [[%union {
1226            char *str;
1227            int n;
1228            double x;
1229            struct { double x, y; } pair;
1230            struct { double x; char *body; } if_data;
1231            struct { char *str; const char *filename; int lineno; } lstr;
1232            struct { double *v; int nv; int maxv; } dv;
1233            struct { double val; int is_multiplicative; } by;
1234            place pl;
1235            object *obj;
1236            corner crn;
1237            path *pth;
1238            object_spec *spec;
1239            saved_state *pstate;
1240            graphics_state state;
1241            object_type obtype;
1242    }
1243    
1244    %token <str> LABEL
1245    %token <str> VARIABLE
1246    %token <x> NUMBER
1247    %token <lstr> TEXT
1248    %token <lstr> COMMAND_LINE
1249    %token <str> DELIMITED
1250    %token <n> ORDINAL
1251    %token TH
1252    %token LEFT_ARROW_HEAD
1253    %token RIGHT_ARROW_HEAD
1254    %token DOUBLE_ARROW_HEAD
1255    %token LAST
1256    %token UP
1257    %token DOWN
1258    %token LEFT
1259    %token RIGHT
1260    %token BOX
1261    %token CIRCLE
1262    %token ELLIPSE
1263    %token ARC
1264    %token LINE
1265    %token ARROW
1266    %token MOVE
1267    %token SPLINE
1268    %token HEIGHT
1269    %token RADIUS
1270    %token WIDTH
1271    %token DIAMETER
1272    %token FROM
1273    %token TO
1274    %token AT
1275    %token WITH
1276    %token BY
1277    %token THEN
1278    %token SOLID
1279    %token DOTTED
1280    %token DASHED
1281    %token CHOP
1282    %token SAME
1283    %token INVISIBLE
1284    %token LJUST
1285    %token RJUST
1286    %token ABOVE
1287    %token BELOW
1288    %token OF
1289    %token THE
1290    %token WAY
1291    %token BETWEEN
1292    %token AND
1293    %token HERE
1294    %token DOT_N
1295    %token DOT_E    
1296    %token DOT_W
1297    %token DOT_S
1298    %token DOT_NE
1299    %token DOT_SE
1300    %token DOT_NW
1301    %token DOT_SW
1302    %token DOT_C
1303    %token DOT_START
1304    %token DOT_END
1305    %token DOT_X
1306    %token DOT_Y
1307    %token DOT_HT
1308    %token DOT_WID
1309    %token DOT_RAD
1310    %token SIN
1311    %token COS
1312    %token ATAN2
1313    %token LOG
1314    %token EXP
1315    %token SQRT
1316    %token K_MAX
1317    %token K_MIN
1318    %token INT
1319    %token RAND
1320    %token SRAND
1321    %token COPY
1322    %token THRU
1323    %token TOP
1324    %token BOTTOM
1325    %token UPPER
1326    %token LOWER
1327    %token SH
1328    %token PRINT
1329    %token CW
1330    %token CCW
1331    %token FOR
1332    %token DO
1333    %token IF
1334    %token ELSE
1335    %token ANDAND
1336    %token OROR
1337    %token NOTEQUAL
1338    %token EQUALEQUAL
1339    %token LESSEQUAL
1340    %token GREATEREQUAL
1341    %token LEFT_CORNER
1342    %token RIGHT_CORNER
1343    %token NORTH
1344    %token SOUTH
1345    %token EAST
1346    %token WEST
1347    %token CENTER
1348    %token END
1349    %token START
1350    %token RESET
1351    %token UNTIL
1352    %token PLOT
1353    %token THICKNESS
1354    %token FILL
1355    %token COLORED
1356    %token OUTLINED
1357    %token SHADED
1358    %token ALIGNED
1359    %token SPRINTF
1360    %token COMMAND
1361    
1362    %left '.'
1363    
1364    /* this ensures that plot 17 "%g" parses as (plot 17 "%g") */
1365    %left PLOT
1366    %left TEXT SPRINTF
1367    
1368    /* give text adjustments higher precedence than TEXT, so that
1369    box "foo" above ljust == box ("foo" above ljust)
1370    */
1371    
1372    %left LJUST RJUST ABOVE BELOW
1373    
1374    %left LEFT RIGHT
1375    /* Give attributes that take an optional expression a higher
1376    precedence than left and right, so that eg `line chop left'
1377    parses properly. */
1378    %left CHOP SOLID DASHED DOTTED UP DOWN FILL COLORED OUTLINED
1379    %left LABEL
1380    
1381    %left VARIABLE NUMBER '(' SIN COS ATAN2 LOG EXP SQRT K_MAX K_MIN INT RAND SRAND LAST
1382    %left ORDINAL HERE '`'
1383    
1384    %left BOX CIRCLE ELLIPSE ARC LINE ARROW SPLINE '[' /* ] */
1385    
1386    /* these need to be lower than '-' */
1387    %left HEIGHT RADIUS WIDTH DIAMETER FROM TO AT THICKNESS
1388    
1389    /* these must have higher precedence than CHOP so that `label %prec CHOP'
1390    works */
1391    %left DOT_N DOT_E DOT_W DOT_S DOT_NE DOT_SE DOT_NW DOT_SW DOT_C
1392    %left DOT_START DOT_END TOP BOTTOM LEFT_CORNER RIGHT_CORNER
1393    %left UPPER LOWER NORTH SOUTH EAST WEST CENTER START END
1394    
1395    %left ','
1396    %left OROR
1397    %left ANDAND
1398    %left EQUALEQUAL NOTEQUAL
1399    %left '<' '>' LESSEQUAL GREATEREQUAL
1400    
1401    %left BETWEEN OF
1402    %left AND
1403    
1404    %left '+' '-'
1405    %left '*' '/' '%'
1406    %right '!'
1407    %right '^'
1408    
1409    %type <x> expr any_expr text_expr
1410    %type <by> optional_by
1411    %type <pair> expr_pair position_not_place
1412    %type <if_data> simple_if
1413    %type <obj> nth_primitive
1414    %type <crn> corner
1415    %type <pth> path label_path relative_path
1416    %type <pl> place label element element_list middle_element_list
1417    %type <spec> object_spec
1418    %type <pair> position
1419    %type <obtype> object_type
1420    %type <n> optional_ordinal_last ordinal
1421    %type <str> until
1422    %type <dv> sprintf_args
1423    %type <lstr> text print_args print_arg
1424    
1425    %%
1426    
1427    top:
1428            optional_separator
1429            | element_list
1430                    {
1431                      if (olist.head)
1432                        print_picture(olist.head);
1433                    }
1434            ;
1435    
1436    
1437    element_list:
1438            optional_separator middle_element_list optional_separator
1439                    { $$ = $2; }
1440            ;
1441    
1442    middle_element_list:
1443            element
1444                    { $$ = $1; }
1445            | middle_element_list separator element
1446                    { $$ = $1; }
1447            ;
1448    
1449    optional_separator:
1450            /* empty */
1451            | separator
1452            ;
1453    
1454    separator:
1455            ';'
1456            | separator ';'
1457            ;
1458    
1459    placeless_element:
1460            VARIABLE '=' any_expr
1461                    {
1462                      define_variable($1, $3);
1463                      a_delete $1;
1464                    }
1465            | VARIABLE ':' '=' any_expr
1466                    {
1467                      place *p = lookup_label($1);
1468                      if (!p) {
1469                        lex_error("variable `%1' not defined", $1);
1470                        YYABORT;
1471                      }
1472                      p->obj = 0;
1473                      p->x = $4;
1474                      p->y = 0.0;
1475                      a_delete $1;
1476                    }
1477            | UP
1478                    { current_direction = UP_DIRECTION; }
1479            | DOWN
1480                    { current_direction = DOWN_DIRECTION; }
1481            | LEFT
1482                    { current_direction = LEFT_DIRECTION; }
1483            | RIGHT
1484                    { current_direction = RIGHT_DIRECTION; }
1485            | COMMAND_LINE
1486                    {
1487                      olist.append(make_command_object($1.str, $1.filename,
1488                                                       $1.lineno));
1489                    }
1490            | COMMAND print_args
1491                    {
1492                      olist.append(make_command_object($2.str, $2.filename,
1493                                                       $2.lineno));
1494                    }
1495            | PRINT print_args
1496                    {
1497                      fprintf(stderr, "%s\n", $2.str);
1498                      a_delete $2.str;
1499                      fflush(stderr);
1500                    }
1501            | SH
1502                    { delim_flag = 1; }
1503              DELIMITED
1504                    {
1505                      delim_flag = 0;
1506                      if (safer_flag)
1507                        lex_error("unsafe to run command `%1'", $3);
1508                      else
1509                        system($3);
1510                      a_delete $3;
1511                    }
1512            | COPY TEXT
1513                    {
1514                      if (yychar < 0)
1515                        do_lookahead();
1516                      do_copy($2.str);
1517                      // do not delete the filename
1518                    }
1519            | COPY TEXT THRU
1520                    { delim_flag = 2; }
1521              DELIMITED
1522                    { delim_flag = 0; }
1523              until
1524                    {
1525                      if (yychar < 0)
1526                        do_lookahead();
1527                      copy_file_thru($2.str, $5, $7);
1528                      // do not delete the filename
1529                      a_delete $5;
1530                      a_delete $7;
1531                    }
1532            | COPY THRU
1533                    { delim_flag = 2; }
1534              DELIMITED
1535                    { delim_flag = 0; }
1536              until
1537                    {
1538                      if (yychar < 0)
1539                        do_lookahead();
1540                      copy_rest_thru($4, $6);
1541                      a_delete $4;
1542                      a_delete $6;
1543                    }
1544            | FOR VARIABLE '=' expr TO expr optional_by DO
1545                    { delim_flag = 1; }
1546              DELIMITED
1547                    {
1548                      delim_flag = 0;
1549                      if (yychar < 0)
1550                        do_lookahead();
1551                      do_for($2, $4, $6, $7.is_multiplicative, $7.val, $10);
1552                    }
1553            | simple_if
1554                    {
1555                      if (yychar < 0)
1556                        do_lookahead();
1557                      if ($1.x != 0.0)
1558                        push_body($1.body);
1559                      a_delete $1.body;
1560                    }
1561            | simple_if ELSE
1562                    { delim_flag = 1; }
1563              DELIMITED
1564                    {
1565                      delim_flag = 0;
1566                      if (yychar < 0)
1567                        do_lookahead();
1568                      if ($1.x != 0.0)
1569                        push_body($1.body);
1570                      else
1571                        push_body($4);
1572                      a_delete $1.body;
1573                      a_delete $4;
1574                    }
1575            | reset_variables
1576            | RESET
1577                    { define_variable("scale", 1.0); }
1578            ;
1579    
1580    reset_variables:
1581            RESET VARIABLE
1582                    {
1583                      reset($2);
1584                      a_delete $2;
1585                    }
1586            | reset_variables VARIABLE
1587                    {
1588                      reset($2);
1589                      a_delete $2;
1590                    }
1591            | reset_variables ',' VARIABLE
1592                    {
1593                      reset($3);
1594                      a_delete $3;
1595                    }
1596            ;
1597    
1598    print_args:
1599            print_arg
1600                    { $$ = $1; }
1601            | print_args print_arg
1602                    {
1603                      $$.str = new char[strlen($1.str) + strlen($2.str) + 1];
1604                      strcpy($$.str, $1.str);
1605                      strcat($$.str, $2.str);
1606                      a_delete $1.str;
1607                      a_delete $2.str;
1608                      if ($1.filename) {
1609                        $$.filename = $1.filename;
1610                        $$.lineno = $1.lineno;
1611                      }
1612                      else if ($2.filename) {
1613                        $$.filename = $2.filename;
1614                        $$.lineno = $2.lineno;
1615                      }
1616                    }
1617            ;
1618    
1619    print_arg:
1620            expr                                                    %prec ','
1621                    {
1622                      $$.str = new char[GDIGITS + 1];
1623                      sprintf($$.str, "%g", $1);
1624                      $$.filename = 0;
1625                      $$.lineno = 0;
1626                    }
1627            | text
1628                    { $$ = $1; }
1629            | position                                              %prec ','
1630                    {
1631                      $$.str = new char[GDIGITS + 2 + GDIGITS + 1];
1632                      sprintf($$.str, "%g, %g", $1.x, $1.y);
1633                      $$.filename = 0;
1634                      $$.lineno = 0;
1635                    }
1636            ;
1637    
1638    simple_if:
1639            IF any_expr THEN
1640                    { delim_flag = 1; }
1641            DELIMITED
1642                    {
1643                      delim_flag = 0;
1644                      $$.x = $2;
1645                      $$.body = $5;
1646                    }
1647            ;
1648    
1649    until:
1650            /* empty */
1651                    { $$ = 0; }
1652            | UNTIL TEXT
1653                    { $$ = $2.str; }
1654            ;
1655            
1656    any_expr:
1657            expr
1658                    { $$ = $1; }
1659            | text_expr
1660                    { $$ = $1; }
1661            ;
1662            
1663    text_expr:
1664            text EQUALEQUAL text
1665                    {
1666                      $$ = strcmp($1.str, $3.str) == 0;
1667                      a_delete $1.str;
1668                      a_delete $3.str;
1669                    }
1670            | text NOTEQUAL text
1671                    {
1672                      $$ = strcmp($1.str, $3.str) != 0;
1673                      a_delete $1.str;
1674                      a_delete $3.str;
1675                    }
1676            | text_expr ANDAND text_expr
1677                    { $$ = ($1 != 0.0 && $3 != 0.0); }
1678            | text_expr ANDAND expr
1679                    { $$ = ($1 != 0.0 && $3 != 0.0); }
1680            | expr ANDAND text_expr
1681                    { $$ = ($1 != 0.0 && $3 != 0.0); }
1682            | text_expr OROR text_expr
1683                    { $$ = ($1 != 0.0 || $3 != 0.0); }
1684            | text_expr OROR expr
1685                    { $$ = ($1 != 0.0 || $3 != 0.0); }
1686            | expr OROR text_expr
1687                    { $$ = ($1 != 0.0 || $3 != 0.0); }
1688            | '!' text_expr
1689                    { $$ = ($2 == 0.0); }
1690            ;
1691    
1692    
1693    optional_by:
1694            /* empty */
1695                    {
1696                      $$.val = 1.0;
1697                      $$.is_multiplicative = 0;
1698                    }
1699            | BY expr
1700                    {
1701                      $$.val = $2;
1702                      $$.is_multiplicative = 0;
1703                    }
1704            | BY '*' expr
1705                    {
1706                      $$.val = $3;
1707                      $$.is_multiplicative = 1;
1708                    }
1709            ;
1710    
1711    element:
1712            object_spec
1713                    {
1714                      $$.obj = $1->make_object(&current_position,
1715                                               &current_direction);
1716                      if ($$.obj == 0)
1717                        YYABORT;
1718                      delete $1;
1719                      if ($$.obj)
1720                        olist.append($$.obj);
1721                      else {
1722                        $$.x = current_position.x;
1723                        $$.y = current_position.y;
1724                      }
1725                    }
1726            | LABEL ':' optional_separator element
1727                    {
1728                      $$ = $4;
1729                      define_label($1, & $$);
1730                      a_delete $1;
1731                    }
1732            | LABEL ':' optional_separator position_not_place
1733                    {
1734                      $$.obj = 0;
1735                      $$.x = $4.x;
1736                      $$.y = $4.y;
1737                      define_label($1, & $$);
1738                      a_delete $1;
1739                    }
1740            | LABEL ':' optional_separator place
1741                    {
1742                      $$ = $4;
1743                      define_label($1, & $$);
1744                      a_delete $1;
1745                    }
1746            | '{'
1747                    {
1748                      $<state>$.x = current_position.x;
1749                      $<state>$.y = current_position.y;
1750                      $<state>$.dir = current_direction;
1751                    }
1752              element_list '}'
1753                    {
1754                      current_position.x = $<state>2.x;
1755                      current_position.y = $<state>2.y;
1756                      current_direction = $<state>2.dir;
1757                    }
1758              optional_element
1759                    {
1760                      $$ = $3;
1761                    }
1762            | placeless_element
1763                    {
1764                      $$.obj = 0;
1765                      $$.x = current_position.x;
1766                      $$.y = current_position.y;
1767                    }
1768            ;
1769    
1770    optional_element:
1771            /* empty */
1772                    {}
1773            | element
1774                    {}
1775            ;
1776    
1777    object_spec:
1778            BOX
1779                    { $$ = new object_spec(BOX_OBJECT); }
1780            | CIRCLE
1781                    { $$ = new object_spec(CIRCLE_OBJECT); }
1782            | ELLIPSE
1783                    { $$ = new object_spec(ELLIPSE_OBJECT); }
1784            | ARC
1785                    {
1786                      $$ = new object_spec(ARC_OBJECT);
1787                      $$->dir = current_direction;
1788                    }
1789            | LINE
1790                    {
1791                      $$ = new object_spec(LINE_OBJECT);
1792                      lookup_variable("lineht", & $$->segment_height);
1793                      lookup_variable("linewid", & $$->segment_width);
1794                      $$->dir = current_direction;
1795                    }
1796            | ARROW
1797                    {
1798                      $$ = new object_spec(ARROW_OBJECT);
1799                      lookup_variable("lineht", & $$->segment_height);
1800                      lookup_variable("linewid", & $$->segment_width);
1801                      $$->dir = current_direction;
1802                    }
1803            | MOVE
1804                    {
1805                      $$ = new object_spec(MOVE_OBJECT);
1806                      lookup_variable("moveht", & $$->segment_height);
1807                      lookup_variable("movewid", & $$->segment_width);
1808                      $$->dir = current_direction;
1809                    }
1810            | SPLINE
1811                    {
1812                      $$ = new object_spec(SPLINE_OBJECT);
1813                      lookup_variable("lineht", & $$->segment_height);
1814                      lookup_variable("linewid", & $$->segment_width);
1815                      $$->dir = current_direction;
1816                    }
1817            | text                                                  %prec TEXT
1818                    {
1819                      $$ = new object_spec(TEXT_OBJECT);
1820                      $$->text = new text_item($1.str, $1.filename, $1.lineno);
1821                    }
1822            | PLOT expr
1823                    {
1824                      $$ = new object_spec(TEXT_OBJECT);
1825                      $$->text = new text_item(format_number(0, $2), 0, -1);
1826                    }
1827            | PLOT expr text
1828                    {
1829                      $$ = new object_spec(TEXT_OBJECT);
1830                      $$->text = new text_item(format_number($3.str, $2),
1831                                               $3.filename, $3.lineno);
1832                      a_delete $3.str;
1833                    }
1834            | '['
1835                    {
1836                      saved_state *p = new saved_state;
1837                      $<pstate>$ = p;
1838                      p->x = current_position.x;
1839                      p->y = current_position.y;
1840                      p->dir = current_direction;
1841                      p->tbl = current_table;
1842                      p->prev = current_saved_state;
1843                      current_position.x = 0.0;
1844                      current_position.y = 0.0;
1845                      current_table = new PTABLE(place);
1846                      current_saved_state = p;
1847                      olist.append(make_mark_object());
1848                    }
1849              element_list ']'
1850                    {
1851                      current_position.x = $<pstate>2->x;
1852                      current_position.y = $<pstate>2->y;
1853                      current_direction = $<pstate>2->dir;
1854                      $$ = new object_spec(BLOCK_OBJECT);
1855                      olist.wrap_up_block(& $$->oblist);
1856                      $$->tbl = current_table;
1857                      current_table = $<pstate>2->tbl;
1858                      current_saved_state = $<pstate>2->prev;
1859                      delete $<pstate>2;
1860                    }
1861            | object_spec HEIGHT expr
1862                    {
1863                      $$ = $1;
1864                      $$->height = $3;
1865                      $$->flags |= HAS_HEIGHT;
1866                    }
1867            | object_spec RADIUS expr
1868                    {
1869                      $$ = $1;
1870                      $$->radius = $3;
1871                      $$->flags |= HAS_RADIUS;
1872                    }
1873            | object_spec WIDTH expr
1874                    {
1875                      $$ = $1;
1876                      $$->width = $3;
1877                      $$->flags |= HAS_WIDTH;
1878                    }
1879            | object_spec DIAMETER expr
1880                    {
1881                      $$ = $1;
1882                      $$->radius = $3/2.0;
1883                      $$->flags |= HAS_RADIUS;
1884                    }
1885            | object_spec expr                                      %prec HEIGHT
1886                    {
1887                      $$ = $1;
1888                      $$->flags |= HAS_SEGMENT;
1889                      switch ($$->dir) {
1890                      case UP_DIRECTION:
1891                        $$->segment_pos.y += $2;
1892                        break;
1893                      case DOWN_DIRECTION:
1894                        $$->segment_pos.y -= $2;
1895                        break;
1896                      case RIGHT_DIRECTION:
1897                        $$->segment_pos.x += $2;
1898                        break;
1899                      case LEFT_DIRECTION:
1900                        $$->segment_pos.x -= $2;
1901                        break;
1902                      }
1903                    }
1904            | object_spec UP
1905                    {
1906                      $$ = $1;
1907                      $$->dir = UP_DIRECTION;
1908                      $$->flags |= HAS_SEGMENT;
1909                      $$->segment_pos.y += $$->segment_height;
1910                    }
1911            | object_spec UP expr
1912                    {
1913                      $$ = $1;
1914                      $$->dir = UP_DIRECTION;
1915                      $$->flags |= HAS_SEGMENT;
1916                      $$->segment_pos.y += $3;
1917                    }
1918            | object_spec DOWN
1919                    {
1920                      $$ = $1;
1921                      $$->dir = DOWN_DIRECTION;
1922                      $$->flags |= HAS_SEGMENT;
1923                      $$->segment_pos.y -= $$->segment_height;
1924                    }
1925            | object_spec DOWN expr
1926                    {
1927                      $$ = $1;
1928                      $$->dir = DOWN_DIRECTION;
1929                      $$->flags |= HAS_SEGMENT;
1930                      $$->segment_pos.y -= $3;
1931                    }
1932            | object_spec RIGHT
1933                    {
1934                      $$ = $1;
1935                      $$->dir = RIGHT_DIRECTION;
1936                      $$->flags |= HAS_SEGMENT;
1937                      $$->segment_pos.x += $$->segment_width;
1938                    }
1939            | object_spec RIGHT expr
1940                    {
1941                      $$ = $1;
1942                      $$->dir = RIGHT_DIRECTION;
1943                      $$->flags |= HAS_SEGMENT;
1944                      $$->segment_pos.x += $3;
1945                    }
1946            | object_spec LEFT
1947                    {
1948                      $$ = $1;
1949                      $$->dir = LEFT_DIRECTION;
1950                      $$->flags |= HAS_SEGMENT;
1951                      $$->segment_pos.x -= $$->segment_width;
1952                    }
1953            | object_spec LEFT expr
1954                    {
1955                      $$ = $1;
1956                      $$->dir = LEFT_DIRECTION;
1957                      $$->flags |= HAS_SEGMENT;
1958                      $$->segment_pos.x -= $3;
1959                    }
1960            | object_spec FROM position
1961                    {
1962                      $$ = $1;
1963                      $$->flags |= HAS_FROM;
1964                      $$->from.x = $3.x;
1965                      $$->from.y = $3.y;
1966                    }
1967            | object_spec TO position
1968                    {
1969                      $$ = $1;
1970                      if ($$->flags & HAS_SEGMENT)
1971                        $$->segment_list = new segment($$->segment_pos,
1972                                                       $$->segment_is_absolute,
1973                                                       $$->segment_list);
1974                      $$->flags |= HAS_SEGMENT;
1975                      $$->segment_pos.x = $3.x;
1976                      $$->segment_pos.y = $3.y;
1977                      $$->segment_is_absolute = 1;
1978                      $$->flags |= HAS_TO;
1979                      $$->to.x = $3.x;
1980                      $$->to.y = $3.y;
1981                    }
1982            | object_spec AT position
1983                    {
1984                      $$ = $1;
1985                      $$->flags |= HAS_AT;
1986                      $$->at.x = $3.x;
1987                      $$->at.y = $3.y;
1988                      if ($$->type != ARC_OBJECT) {
1989                        $$->flags |= HAS_FROM;
1990                        $$->from.x = $3.x;
1991                        $$->from.y = $3.y;
1992                      }
1993                    }
1994            | object_spec WITH path
1995                    {
1996                      $$ = $1;
1997                      $$->flags |= HAS_WITH;
1998                      $$->with = $3;
1999                    }
2000            | object_spec WITH position                             %prec ','
2001                    {
2002                      $$ = $1;
2003                      $$->flags |= HAS_WITH;
2004                      position pos;
2005                      pos.x = $3.x;
2006                      pos.y = $3.y;
2007                      $$->with = new path(pos);
2008                    }
2009            | object_spec BY expr_pair
2010                    {
2011                      $$ = $1;
2012                      $$->flags |= HAS_SEGMENT;
2013                      $$->segment_pos.x += $3.x;
2014                      $$->segment_pos.y += $3.y;
2015                    }
2016            | object_spec THEN
2017                    {
2018                      $$ = $1;
2019                      if ($$->flags & HAS_SEGMENT) {
2020                        $$->segment_list = new segment($$->segment_pos,
2021                                                       $$->segment_is_absolute,
2022                                                       $$->segment_list);
2023                        $$->flags &= ~HAS_SEGMENT;
2024                        $$->segment_pos.x = $$->segment_pos.y = 0.0;
2025                        $$->segment_is_absolute = 0;
2026                      }
2027                    }
2028            | object_spec SOLID
2029                    {
2030                      $$ = $1;      // nothing
2031                    }
2032            | object_spec DOTTED
2033                    {
2034                      $$ = $1;
2035                      $$->flags |= IS_DOTTED;
2036                      lookup_variable("dashwid", & $$->dash_width);
2037                    }
2038            | object_spec DOTTED expr
2039                    {
2040                      $$ = $1;
2041                      $$->flags |= IS_DOTTED;
2042                      $$->dash_width = $3;
2043                    }
2044            | object_spec DASHED
2045                    {
2046                      $$ = $1;
2047                      $$->flags |= IS_DASHED;
2048                      lookup_variable("dashwid", & $$->dash_width);
2049                    }
2050            | object_spec DASHED expr
2051                    {
2052                      $$ = $1;
2053                      $$->flags |= IS_DASHED;
2054                      $$->dash_width = $3;
2055                    }
2056            | object_spec FILL
2057                    {
2058                      $$ = $1;
2059                      $$->flags |= IS_DEFAULT_FILLED;
2060                    }
2061            | object_spec FILL expr
2062                    {
2063                      $$ = $1;
2064                      $$->flags |= IS_FILLED;
2065                      $$->fill = $3;
2066                    }
2067            | object_spec SHADED text
2068                    {
2069                      $$ = $1;
2070                      $$->flags |= (IS_SHADED | IS_FILLED);
2071                      $$->shaded = new char[strlen($3.str)+1];
2072                      strcpy($$->shaded, $3.str);
2073                    }
2074            | object_spec COLORED text
2075                    {
2076                      $$ = $1;
2077                      $$->flags |= (IS_SHADED | IS_OUTLINED | IS_FILLED);
2078                      $$->shaded = new char[strlen($3.str)+1];
2079                      strcpy($$->shaded, $3.str);
2080                      $$->outlined = new char[strlen($3.str)+1];
2081                      strcpy($$->outlined, $3.str);
2082                    }
2083            | object_spec OUTLINED text
2084                    {
2085                      $$ = $1;
2086                      $$->flags |= IS_OUTLINED;
2087                      $$->outlined = new char[strlen($3.str)+1];
2088                      strcpy($$->outlined, $3.str);
2089                    }
2090            | object_spec CHOP
2091                    {
2092                      $$ = $1;
2093                      // line chop chop means line chop 0 chop 0
2094                      if ($$->flags & IS_DEFAULT_CHOPPED) {
2095                        $$->flags |= IS_CHOPPED;
2096                        $$->flags &= ~IS_DEFAULT_CHOPPED;
2097                        $$->start_chop = $$->end_chop = 0.0;
2098                      }
2099                      else if ($$->flags & IS_CHOPPED) {
2100                        $$->end_chop = 0.0;
2101                      }
2102                      else {
2103                        $$->flags |= IS_DEFAULT_CHOPPED;
2104                      }
2105                    }
2106            | object_spec CHOP expr
2107                    {
2108                      $$ = $1;
2109                      if ($$->flags & IS_DEFAULT_CHOPPED) {
2110                        $$->flags |= IS_CHOPPED;
2111                        $$->flags &= ~IS_DEFAULT_CHOPPED;
2112                        $$->start_chop = 0.0;
2113                        $$->end_chop = $3;
2114                      }
2115                      else if ($$->flags & IS_CHOPPED) {
2116                        $$->end_chop = $3;
2117                      }
2118                      else {
2119                        $$->start_chop = $$->end_chop = $3;
2120                        $$->flags |= IS_CHOPPED;
2121                      }
2122                    }
2123            | object_spec SAME
2124                    {
2125                      $$ = $1;
2126                      $$->flags |= IS_SAME;
2127                    }
2128            | object_spec INVISIBLE
2129                    {
2130                      $$ = $1;
2131                      $$->flags |= IS_INVISIBLE;
2132                    }
2133            | object_spec LEFT_ARROW_HEAD
2134                    {
2135                      $$ = $1;
2136                      $$->flags |= HAS_LEFT_ARROW_HEAD;
2137                    }
2138            | object_spec RIGHT_ARROW_HEAD
2139                    {
2140                      $$ = $1;
2141                      $$->flags |= HAS_RIGHT_ARROW_HEAD;
2142                    }
2143            | object_spec DOUBLE_ARROW_HEAD
2144                    {
2145                      $$ = $1;
2146                      $$->flags |= (HAS_LEFT_ARROW_HEAD|HAS_RIGHT_ARROW_HEAD);
2147                    }
2148            | object_spec CW
2149                    {
2150                      $$ = $1;
2151                      $$->flags |= IS_CLOCKWISE;
2152                    }
2153            | object_spec CCW
2154                    {
2155                      $$ = $1;
2156                      $$->flags &= ~IS_CLOCKWISE;
2157                    }
2158            | object_spec text                                      %prec TEXT
2159                    {
2160                      $$ = $1;
2161                      text_item **p;
2162                      for (p = & $$->text; *p; p = &(*p)->next)
2163                        ;
2164                      *p = new text_item($2.str, $2.filename, $2.lineno);
2165                    }
2166            | object_spec LJUST
2167                    {
2168                      $$ = $1;
2169                      if ($$->text) {
2170                        text_item *p;
2171                        for (p = $$->text; p->next; p = p->next)
2172                          ;
2173                        p->adj.h = LEFT_ADJUST;
2174                      }
2175                    }
2176            | object_spec RJUST
2177                    {
2178                      $$ = $1;
2179                      if ($$->text) {
2180                        text_item *p;
2181                        for (p = $$->text; p->next; p = p->next)
2182                          ;
2183                        p->adj.h = RIGHT_ADJUST;
2184                      }
2185                    }
2186            | object_spec ABOVE
2187                    {
2188                      $$ = $1;
2189                      if ($$->text) {
2190                        text_item *p;
2191                        for (p = $$->text; p->next; p = p->next)
2192                          ;
2193                        p->adj.v = ABOVE_ADJUST;
2194                      }
2195                    }
2196            | object_spec BELOW
2197                    {
2198                      $$ = $1;
2199                      if ($$->text) {
2200                        text_item *p;
2201                        for (p = $$->text; p->next; p = p->next)
2202                          ;
2203                        p->adj.v = BELOW_ADJUST;
2204                      }
2205                    }
2206            | object_spec THICKNESS expr
2207                    {
2208                      $$ = $1;
2209                      $$->flags |= HAS_THICKNESS;
2210                      $$->thickness = $3;
2211                    }
2212            | object_spec ALIGNED
2213                    {
2214                      $$ = $1;
2215                      $$->flags |= IS_ALIGNED;
2216                    }
2217            ;
2218    
2219    text:
2220            TEXT
2221                    { $$ = $1; }
2222            | SPRINTF '(' TEXT sprintf_args ')'
2223                    {
2224                      $$.filename = $3.filename;
2225                      $$.lineno = $3.lineno;
2226                      $$.str = do_sprintf($3.str, $4.v, $4.nv);
2227                      a_delete $4.v;
2228                      a_delete $3.str;
2229                    }
2230            ;
2231    
2232    sprintf_args:
2233            /* empty */
2234                    {
2235                      $$.v = 0;
2236                      $$.nv = 0;
2237                      $$.maxv = 0;
2238                    }
2239            | sprintf_args ',' expr
2240                    {
2241                      $$ = $1;
2242                      if ($$.nv >= $$.maxv) {
2243                        if ($$.nv == 0) {
2244                          $$.v = new double[4];
2245                          $$.maxv = 4;
2246                        }
2247                        else {
2248                          double *oldv = $$.v;
2249                          $$.maxv *= 2;
2250                          $$.v = new double[$$.maxv];
2251                          memcpy($$.v, oldv, $$.nv*sizeof(double));
2252                          a_delete oldv;
2253                        }
2254                      }
2255                      $$.v[$$.nv] = $3;
2256                      $$.nv += 1;
2257                    }
2258            ;
2259    
2260    position:
2261            position_not_place
2262                    { $$ = $1; }
2263            | place
2264                    {
2265                      position pos = $1;
2266                      $$.x = pos.x;
2267                      $$.y = pos.y;
2268                    }
2269            ;
2270    
2271    position_not_place:
2272            expr_pair
2273                    { $$ = $1; }
2274            | position '+' expr_pair
2275                    {
2276                      $$.x = $1.x + $3.x;
2277                      $$.y = $1.y + $3.y;
2278                    }
2279            | position '-' expr_pair
2280                    {
2281                      $$.x = $1.x - $3.x;
2282                      $$.y = $1.y - $3.y;
2283                    }
2284            | '(' position ',' position ')'
2285                    {
2286                      $$.x = $2.x;
2287                      $$.y = $4.y;
2288                    }
2289            | expr between position AND position
2290                    {
2291                      $$.x = (1.0 - $1)*$3.x + $1*$5.x;
2292                      $$.y = (1.0 - $1)*$3.y + $1*$5.y;
2293                    }
2294            | expr '<' position ',' position '>'
2295                    {
2296                      $$.x = (1.0 - $1)*$3.x + $1*$5.x;
2297                      $$.y = (1.0 - $1)*$3.y + $1*$5.y;
2298                    }
2299            ;
2300    
2301    between:
2302            BETWEEN
2303            | OF THE WAY BETWEEN
2304            ;
2305    
2306    expr_pair:
2307            expr ',' expr
2308                    {
2309                      $$.x = $1;
2310                      $$.y = $3;
2311                    }
2312            | '(' expr_pair ')'
2313                    { $$ = $2; }
2314            ;
2315    
2316    place:
2317            /* line at A left == line (at A) left */
2318            label                                                   %prec CHOP
2319                    { $$ = $1; }
2320            | label corner
2321                    {
2322                      path pth($2);
2323                      if (!pth.follow($1, & $$))
2324                        YYABORT;
2325                    }
2326            | corner label
2327                    {
2328                      path pth($1);
2329                      if (!pth.follow($2, & $$))
2330                        YYABORT;
2331                    }
2332            | corner OF label
2333                    {
2334                      path pth($1);
2335                      if (!pth.follow($3, & $$))
2336                        YYABORT;
2337                    }
2338            | HERE
2339                    {
2340                      $$.x = current_position.x;
2341                      $$.y = current_position.y;
2342                      $$.obj = 0;
2343                    }
2344            ;
2345    
2346    label:
2347            LABEL
2348                    {
2349                      place *p = lookup_label($1);
2350                      if (!p) {
2351                        lex_error("there is no place `%1'", $1);
2352                        YYABORT;
2353                      }
2354                      $$ = *p;
2355                      a_delete $1;
2356                    }
2357            | nth_primitive
2358                    { $$.obj = $1; }
2359            | label '.' LABEL
2360                    {
2361                      path pth($3);
2362                      if (!pth.follow($1, & $$))
2363                        YYABORT;
2364                    }
2365            ;
2366    
2367    ordinal:
2368            ORDINAL
2369                    { $$ = $1; }
2370            | '`' any_expr TH
2371                    {
2372                      // XXX Check for overflow (and non-integers?).
2373                      $$ = (int)$2;
2374                    }
2375            ;
2376    
2377    optional_ordinal_last:
2378            LAST
2379                    { $$ = 1; }
2380            | ordinal LAST
2381                    { $$ = $1; }
2382            ;
2383    
2384    nth_primitive:
2385            ordinal object_type
2386                    {
2387                      int count = 0;
2388                      object *p;
2389                      for (p = olist.head; p != 0; p = p->next)
2390                        if (p->type() == $2 && ++count == $1) {
2391                          $$ = p;
2392                          break;
2393                        }
2394                      if (p == 0) {
2395                        lex_error("there is no %1%2 %3", $1, ordinal_postfix($1),
2396                                  object_type_name($2));
2397                        YYABORT;
2398                      }
2399                    }
2400            | optional_ordinal_last object_type
2401                    {
2402                      int count = 0;
2403                      object *p;
2404                      for (p = olist.tail; p != 0; p = p->prev)
2405                        if (p->type() == $2 && ++count == $1) {
2406                          $$ = p;
2407                          break;
2408                        }
2409                      if (p == 0) {
2410                        lex_error("there is no %1%2 last %3", $1,
2411                                  ordinal_postfix($1), object_type_name($2));
2412                        YYABORT;
2413                      }
2414                    }
2415            ;
2416    
2417    object_type:
2418            BOX
2419                    { $$ = BOX_OBJECT; }
2420            | CIRCLE
2421                    { $$ = CIRCLE_OBJECT; }
2422            | ELLIPSE
2423                    { $$ = ELLIPSE_OBJECT; }
2424            | ARC
2425                    { $$ = ARC_OBJECT; }
2426            | LINE
2427                    { $$ = LINE_OBJECT; }
2428            | ARROW
2429                    { $$ = ARROW_OBJECT; }
2430            | SPLINE
2431                    { $$ = SPLINE_OBJECT; }
2432            | '[' ']'
2433                    { $$ = BLOCK_OBJECT; }
2434            | TEXT
2435                    { $$ = TEXT_OBJECT; }
2436            ;
2437    
2438    label_path:
2439            '.' LABEL
2440                    { $$ = new path($2); }
2441            | label_path '.' LABEL
2442                    {
2443                      $$ = $1;
2444                      $$->append($3);
2445                    }
2446            ;
2447    
2448    relative_path:
2449            corner                                                  %prec CHOP
2450                    { $$ = new path($1); }
2451            /* give this a lower precedence than LEFT and RIGHT so that
2452               [A: box] with .A left == [A: box] with (.A left) */
2453            | label_path                                            %prec TEXT
2454                    { $$ = $1; }
2455            | label_path corner
2456                    {
2457                      $$ = $1;
2458                      $$->append($2);
2459                    }
2460            ;
2461    
2462    path:
2463            relative_path
2464                    { $$ = $1; }
2465            | '(' relative_path ',' relative_path ')'
2466                    {
2467                      $$ = $2;
2468                      $$->set_ypath($4);
2469                    }
2470            /* The rest of these rules are a compatibility sop. */
2471            | ORDINAL LAST object_type relative_path
2472                    {
2473                      lex_warning("`%1%2 last %3' in `with' argument ignored",
2474                                  $1, ordinal_postfix($1), object_type_name($3));
2475                      $$ = $4;
2476                    }
2477            | LAST object_type relative_path
2478                    {
2479                      lex_warning("`last %1' in `with' argument ignored",
2480                                  object_type_name($2));
2481                      $$ = $3;
2482                    }
2483            | ORDINAL object_type relative_path
2484                    {
2485                      lex_warning("`%1%2 %3' in `with' argument ignored",
2486                                  $1, ordinal_postfix($1), object_type_name($2));
2487                      $$ = $3;
2488                    }
2489            | LABEL relative_path
2490                    {
2491                      lex_warning("initial `%1' in `with' argument ignored", $1);
2492                      a_delete $1;
2493                      $$ = $2;
2494                    }
2495            ;
2496    
2497    corner:
2498            DOT_N
2499                    { $$ = &object::north; }
2500            | DOT_E
2501                    { $$ = &object::east; }
2502            | DOT_W
2503                    { $$ = &object::west; }
2504            | DOT_S
2505                    { $$ = &object::south; }
2506            | DOT_NE
2507                    { $$ = &object::north_east; }
2508            | DOT_SE
2509                    { $$ = &object:: south_east; }
2510            | DOT_NW
2511                    { $$ = &object::north_west; }
2512            | DOT_SW
2513                    { $$ = &object::south_west; }
2514            | DOT_C
2515                    { $$ = &object::center; }
2516            | DOT_START
2517                    { $$ = &object::start; }
2518            | DOT_END
2519                    { $$ = &object::end; }
2520            | TOP
2521                    { $$ = &object::north; }
2522            | BOTTOM
2523                    { $$ = &object::south; }
2524            | LEFT
2525                    { $$ = &object::west; }
2526            | RIGHT
2527                    { $$ = &object::east; }
2528            | UPPER LEFT
2529                    { $$ = &object::north_west; }
2530            | LOWER LEFT
2531                    { $$ = &object::south_west; }
2532            | UPPER RIGHT
2533                    { $$ = &object::north_east; }
2534            | LOWER RIGHT
2535                    { $$ = &object::south_east; }
2536            | LEFT_CORNER
2537                    { $$ = &object::west; }
2538            | RIGHT_CORNER
2539                    { $$ = &object::east; }
2540            | UPPER LEFT_CORNER
2541                    { $$ = &object::north_west; }
2542            | LOWER LEFT_CORNER
2543                    { $$ = &object::south_west; }
2544            | UPPER RIGHT_CORNER
2545                    { $$ = &object::north_east; }
2546            | LOWER RIGHT_CORNER
2547                    { $$ = &object::south_east; }
2548            | NORTH
2549                    { $$ = &object::north; }
2550            | SOUTH
2551                    { $$ = &object::south; }
2552            | EAST
2553                    { $$ = &object::east; }
2554            | WEST
2555                    { $$ = &object::west; }
2556            | CENTER
2557                    { $$ = &object::center; }
2558            | START
2559                    { $$ = &object::start; }
2560            | END
2561                    { $$ = &object::end; }
2562            ;
2563    
2564    expr:
2565            VARIABLE
2566                    {
2567                      if (!lookup_variable($1, & $$)) {
2568                        lex_error("there is no variable `%1'", $1);
2569                        YYABORT;
2570                      }
2571                      a_delete $1;
2572                    }
2573            | NUMBER
2574                    { $$ = $1; }
2575            | place DOT_X
2576                    {
2577                      if ($1.obj != 0)
2578                        $$ = $1.obj->origin().x;
2579                      else
2580                        $$ = $1.x;
2581                    }                      
2582            | place DOT_Y
2583                    {
2584                      if ($1.obj != 0)
2585                        $$ = $1.obj->origin().y;
2586                      else
2587                        $$ = $1.y;
2588                    }
2589            | place DOT_HT
2590                    {
2591                      if ($1.obj != 0)
2592                        $$ = $1.obj->height();
2593                      else
2594                        $$ = 0.0;
2595                    }
2596            | place DOT_WID
2597                    {
2598                      if ($1.obj != 0)
2599                        $$ = $1.obj->width();
2600                      else
2601                        $$ = 0.0;
2602                    }
2603            | place DOT_RAD
2604                    {
2605                      if ($1.obj != 0)
2606                        $$ = $1.obj->radius();
2607                      else
2608                        $$ = 0.0;
2609                    }
2610            | expr '+' expr
2611                    { $$ = $1 + $3; }
2612            | expr '-' expr
2613                    { $$ = $1 - $3; }
2614            | expr '*' expr
2615                    { $$ = $1 * $3; }
2616            | expr '/' expr
2617                    {
2618                      if ($3 == 0.0) {
2619                        lex_error("division by zero");
2620                        YYABORT;
2621                      }
2622                      $$ = $1/$3;
2623                    }
2624            | expr '%' expr
2625                    {
2626                      if ($3 == 0.0) {
2627                        lex_error("modulus by zero");
2628                        YYABORT;
2629                      }
2630                      $$ = fmod($1, $3);
2631                    }
2632            | expr '^' expr
2633                    {
2634                      errno = 0;
2635                      $$ = pow($1, $3);
2636                      if (errno == EDOM) {
2637                        lex_error("arguments to `^' operator out of domain");
2638                        YYABORT;
2639                      }
2640                      if (errno == ERANGE) {
2641                        lex_error("result of `^' operator out of range");
2642                        YYABORT;
2643                      }
2644                    }
2645            | '-' expr                                              %prec '!'
2646                    { $$ = -$2; }
2647            | '(' any_expr ')'
2648                    { $$ = $2; }
2649            | SIN '(' any_expr ')'
2650                    {
2651                      errno = 0;
2652                      $$ = sin($3);
2653                      if (errno == ERANGE) {
2654                        lex_error("sin result out of range");
2655                        YYABORT;
2656                      }
2657                    }
2658            | COS '(' any_expr ')'
2659                    {
2660                      errno = 0;
2661                      $$ = cos($3);
2662                      if (errno == ERANGE) {
2663                        lex_error("cos result out of range");
2664                        YYABORT;
2665                      }
2666                    }
2667            | ATAN2 '(' any_expr ',' any_expr ')'
2668                    {
2669                      errno = 0;
2670                      $$ = atan2($3, $5);
2671                      if (errno == EDOM) {
2672                        lex_error("atan2 argument out of domain");
2673                        YYABORT;
2674                      }
2675                      if (errno == ERANGE) {
2676                        lex_error("atan2 result out of range");
2677                        YYABORT;
2678                      }
2679                    }
2680            | LOG '(' any_expr ')'
2681                    {
2682                      errno = 0;
2683                      $$ = log10($3);
2684                      if (errno == ERANGE) {
2685                        lex_error("log result out of range");
2686                        YYABORT;
2687                      }
2688                    }
2689            | EXP '(' any_expr ')'
2690                    {
2691                      errno = 0;
2692                      $$ = pow(10.0, $3);
2693                      if (errno == ERANGE) {
2694                        lex_error("exp result out of range");
2695                        YYABORT;
2696                      }
2697                    }
2698            | SQRT '(' any_expr ')'
2699                    {
2700                      errno = 0;
2701                      $$ = sqrt($3);
2702                      if (errno == EDOM) {
2703                        lex_error("sqrt argument out of domain");
2704                        YYABORT;
2705                      }
2706                    }
2707            | K_MAX '(' any_expr ',' any_expr ')'
2708                    { $$ = $3 > $5 ? $3 : $5; }
2709            | K_MIN '(' any_expr ',' any_expr ')'
2710                    { $$ = $3 < $5 ? $3 : $5; }
2711            | INT '(' any_expr ')'
2712                    { $$ = floor($3); }
2713            | RAND '(' any_expr ')'
2714                    { $$ = 1.0 + floor(((rand()&0x7fff)/double(0x7fff))*$3); }
2715            | RAND '(' ')'
2716                    {
2717                      /* return a random number in the range >=0, <1 */
2718                      /* portable, but not very random */
2719                      $$ = (rand() & 0x7fff) / double(0x8000);
2720                    }
2721            | SRAND '(' any_expr ')'
2722                    {
2723                      $$ = 0;
2724                      srand((unsigned int)$3);
2725                    }
2726            | expr '<' expr
2727                    { $$ = ($1 < $3); }
2728            | expr LESSEQUAL expr
2729                    { $$ = ($1 <= $3); }
2730            | expr '>' expr
2731                    { $$ = ($1 > $3); }
2732            | expr GREATEREQUAL expr
2733                    { $$ = ($1 >= $3); }
2734            | expr EQUALEQUAL expr
2735                    { $$ = ($1 == $3); }
2736            | expr NOTEQUAL expr
2737                    { $$ = ($1 != $3); }
2738            | expr ANDAND expr
2739                    { $$ = ($1 != 0.0 && $3 != 0.0); }
2740            | expr OROR expr
2741                    { $$ = ($1 != 0.0 || $3 != 0.0); }
2742            | '!' expr
2743                    { $$ = ($2 == 0.0); }
2744    
2745            ;
2746    ]])
2747    
2748    # Pass plenty of options, to exercise plenty of code, even if we
2749    # don't actually check the output.  But SEGV is watching us, and
2750    # so might do dmalloc.
2751    AT_CHECK([[bison --verbose --defines input.y]], 0, [], [])
2752    
2753    AT_CLEANUP

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.5

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26