home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / fontutils-0.6-base.tgz / fontutils-0.6-base.tar / fsf / fontutils / bpltobzr / bpl.y < prev    next >
Text File  |  1992-10-25  |  11KB  |  428 lines

  1. %{
  2. /* bpl.y: parse a Bezier property list file and output it in the binary
  3.    BZR format.  We assume `bzr_open_output_file' has been called.
  4.  
  5. Copyright (C) 1992 Free Software Foundation, Inc.
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2, or (at your option)
  10. any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. #include "config.h"
  22.  
  23. #include <ctype.h>
  24. #include "bzr.h"
  25. #include "spline.h"
  26. #include "varstring.h"
  27.  
  28. #include "main.h"
  29.  
  30.  
  31. /* We need to keep track of a current point for building the characters.  */
  32. static real_coordinate_type cur;
  33.  
  34. static void yyerror (string);
  35. static int yylex (void);
  36. %}
  37.  
  38. %union
  39. {
  40.   real_bounding_box_type *bbval;
  41.   int intval;
  42.   spline_list_type *outlineval;        /* A single cyclic path.  */
  43.   real realval;
  44.   spline_list_array_type *shapeval;    /* A sequence of outlines.  */
  45.   spline_type splineval;        /* A single line or cubic.  */
  46.   string strval;
  47. }
  48. %token TR_BB TR_CHAR TR_DESIGNSIZE TR_FONTBB TR_FONTCOMMENT TR_FONTFILE
  49. %token TR_LINE TR_NCHARS TR_OUTLINE TR_SPLINE TR_WIDTH
  50. %token <intval> T_INTEGER
  51. %token <realval> T_REAL T_REALSTR
  52. %token <strval> T_STRING
  53.  
  54. %type <bbval> charbb
  55. %type <outlineval> outline splines
  56. %type <realval> designsize setwidth
  57. %type <shapeval> outline_list shape
  58. %type <splineval> spline
  59. %type <strval> fontcomment
  60.  
  61. %%
  62. bpl_file:
  63.     preamble chardefs postamble ;
  64.  
  65. preamble:
  66.       fontfile fontcomment designsize
  67.             { bzr_preamble_type pre;
  68.               BZR_COMMENT (pre) = $2;
  69.               BZR_DESIGN_SIZE (pre) = $3;
  70.               bzr_put_preamble (pre);
  71.             }
  72.         ;
  73.  
  74. fontfile:
  75.     TR_FONTFILE T_STRING ;
  76.  
  77. fontcomment:
  78.           TR_FONTCOMMENT T_STRING
  79.             { $$ = $2; }
  80.         ;
  81.  
  82. designsize:
  83.       TR_DESIGNSIZE T_REAL
  84.             { $$ = $2; }
  85.         ;
  86.  
  87. chardefs:
  88.       chardef
  89.         | chardefs chardef
  90.         ;
  91.  
  92. chardef:
  93.           TR_CHAR T_INTEGER setwidth charbb shape
  94.             {
  95.               bzr_char_type ch;
  96.  
  97.               if ($2 > MAX_CHARCODE)
  98.                 {
  99.                   WARNING1 ("%d: Character code too large", $2);
  100.                   $2 %= 256;
  101.                 }
  102.               CHARCODE (ch) = $2;
  103.               CHAR_SET_WIDTH (ch) = $3;
  104.               CHAR_BB (ch) = *$4;
  105.               BZR_SHAPE (ch) = *$5;
  106.               bzr_put_char (ch);
  107.             }
  108.     ;
  109.  
  110. setwidth:
  111.         TR_WIDTH T_REALSTR
  112.         { $$ = $2; }
  113.         ;
  114.  
  115. charbb:
  116.       TR_BB T_REALSTR T_REALSTR T_REALSTR T_REALSTR 
  117.             { $$ = XTALLOC1 (real_bounding_box_type); 
  118.               MIN_COL (*$$) = $2;
  119.               MAX_COL (*$$) = $3;
  120.               MIN_ROW (*$$) = $4;
  121.               MAX_ROW (*$$) = $5;
  122.             }
  123.         ;
  124.  
  125. shape:
  126.       /* empty */
  127.             { $$ = XTALLOC1 (spline_list_array_type);
  128.               SPLINE_LIST_ARRAY_LENGTH (*$$) = 0;
  129.               SPLINE_LIST_ARRAY_DATA (*$$) = NULL;
  130.             }
  131.         | outline_list
  132.             { $$ = $1; }
  133.  
  134. outline_list:
  135.       outline
  136.             { $$ = XTALLOC1 (spline_list_array_type);
  137.               SPLINE_LIST_ARRAY_LENGTH (*$$) = 1;
  138.               SPLINE_LIST_ARRAY_DATA (*$$) = XTALLOC (1, spline_list_type);
  139.               SPLINE_LIST_ARRAY_ELT (*$$, 0) = *$1;
  140.             }
  141.     | outline_list outline
  142.             { append_spline_list ($1, *$2);
  143.               $$ = $1;
  144.             }
  145.         ;
  146.  
  147. outline:
  148.           TR_OUTLINE T_REALSTR T_REALSTR
  149.         { cur = (real_coordinate_type) { $2, $3 }; }
  150.           splines
  151.             { $$ = $5; }
  152.         ;
  153.  
  154. splines:
  155.       spline
  156.             { $$ = XTALLOC1 (spline_list_type);
  157.               SPLINE_LIST_LENGTH (*$$) = 1;
  158.               SPLINE_LIST_DATA (*$$) = XTALLOC (1, spline_type);
  159.               SPLINE_LIST_ELT (*$$, 0) = $1;
  160.             }
  161.         | splines spline
  162.             { append_spline ($1, $2);
  163.               $$ = $1;
  164.             }
  165.         ;
  166.  
  167. spline:
  168.       TR_LINE T_REALSTR T_REALSTR
  169.         { $$ = new_spline ();
  170.               START_POINT ($$) = cur; 
  171.               cur = (real_coordinate_type) { $2, $3 };
  172.               END_POINT ($$) = cur;
  173.               SPLINE_DEGREE ($$) = LINEAR;
  174.             }
  175.     | TR_SPLINE T_REALSTR T_REALSTR T_REALSTR T_REALSTR T_REALSTR T_REALSTR
  176.             { $$ = new_spline ();
  177.               START_POINT ($$) = cur;
  178.               CONTROL1 ($$) = (real_coordinate_type) { $2, $3 };
  179.               CONTROL2 ($$) = (real_coordinate_type) { $4, $5 };
  180.               cur = (real_coordinate_type) { $6, $7 };
  181.               END_POINT ($$) = cur;
  182.               SPLINE_DEGREE ($$) = CUBIC;
  183.             }
  184.         ;
  185.  
  186. postamble:
  187.       fontbb nchars
  188.         { bzr_put_postamble (); }
  189.         ;
  190.  
  191. fontbb:
  192.     TR_FONTBB T_REALSTR T_REALSTR T_REALSTR T_REALSTR ;
  193.  
  194. nchars:
  195.     TR_NCHARS T_INTEGER ;
  196. %%
  197.  
  198. /* Let's hope Bison will never use this value as a token code.  */
  199. #define NOT_A_TOKEN (-1)
  200.  
  201. static int get_numeric_token (FILE *);
  202. static int get_word_token (FILE *);
  203. static int get_string_token (FILE *);
  204. static int token_number (string);
  205.  
  206.  
  207. /* Return the next token from `bpl_file'.  */
  208.  
  209. static int
  210. yylex (void)
  211. {
  212.   int t = NOT_A_TOKEN;
  213.   
  214.   do
  215.     {
  216.       int c = getc (bpl_file);
  217.  
  218.       /* Although the BPL file has parentheses in it to make it easy for
  219.          Lisp to execute, there's no need to clutter up the grammar with
  220.          parentheses everywhere.  The keywords do well enough to
  221.          separate the various components.  */
  222.       while (c != EOF && (isspace (c) || c == '(' || c == ')'))
  223.         c = getc (bpl_file);
  224.         
  225.       switch (c)
  226.         {
  227.         case EOF: 
  228.           t = 0;
  229.           break;
  230.  
  231.         case '0': case '1': case '2': case '3': case '4':
  232.         case '5': case '6': case '7': case '8': case '9':
  233.         case '.':
  234.           ungetc (c, bpl_file);
  235.           t = get_numeric_token (bpl_file);
  236.           break;
  237.  
  238.         case '"':
  239.           t = get_string_token (bpl_file);
  240.           break;
  241.  
  242.         default:
  243.           if (isalpha (c))
  244.             {
  245.               ungetc (c, bpl_file);
  246.               t = get_word_token (bpl_file);
  247.             }
  248.           else 
  249.             t = c;
  250.           break;
  251.         }
  252.     }
  253.   while (t == NOT_A_TOKEN);
  254.  
  255.   return t;
  256. }
  257.  
  258.  
  259. /* Don't do anything special for errors.  */
  260.  
  261. static void
  262. yyerror (string s)
  263. {
  264.   fprintf (stderr, "%s\n", s);
  265. }
  266.  
  267. /* Read a numeric decimal constant from the file F.  If we see just
  268.    <digits>, we return T_INTEGER and set yylval.intval.  If we see
  269.    <digits>.<digits>, we return T_REAL and set yylval.realval.  This
  270.    allows only unsigned numbers.  */
  271.  
  272. static int
  273. get_numeric_token (FILE *f)
  274. {
  275.   int c;
  276.   int t = T_INTEGER;
  277.   variable_string vs = vs_init ();
  278.   
  279.   /* First collect leading digits.  */
  280.   for (;;)
  281.     {
  282.       c = getc (f);
  283.       if (!isdigit (c))
  284.         break;
  285.       vs_append_char (&vs, c);
  286.     }
  287.   
  288.   /* If we're at a decimal point, this is a real constant.  */
  289.   if (c == '.')
  290.     {
  291.       t = T_REAL;
  292.       
  293.       /* Collect more digits.  Append first, so we grab the `.'.  */
  294.       do
  295.         {
  296.           vs_append_char (&vs, c);
  297.           c = getc (f);
  298.         }
  299.       while (isdigit (c));
  300.       
  301.       /* Don't bother to allow `e<exponent>' at the end, since we never
  302.          need to output in that format.  */
  303.     }
  304.   
  305.   /* Add the terminating null and convert the string to a number.  */
  306.   vs_append_char (&vs, 0);
  307.   
  308.   if (t == T_INTEGER)
  309.     yylval.intval = atoi (VS_CHARS (vs));
  310.   else
  311.     yylval.realval = atof (VS_CHARS (vs));
  312.   
  313.   vs_free (&vs);
  314.   
  315.   return t;
  316. }
  317.  
  318. /* Read a string constant from the file F. We make no provision for
  319.    quoting " characters; the string just consists of everything from one
  320.    " to the next.  Because Emacs 18 does not support floating-point
  321.    numeric constants, bzrto writes such as a string.  Therefore, when we
  322.    find a string whose contents are entirely such a constant, we return
  323.    T_REALSTR and set yylval.realval.  Otherwise, we return T_STRING and
  324.    set yylval.strval.  */
  325.  
  326. static int
  327. get_string_token (FILE *f)
  328. {
  329.   int c, t;
  330.   variable_string vs = vs_init ();
  331.  
  332.   while ((c = getc (f)) != EOF && c != '"')
  333.     vs_append_char (&vs, c);
  334.  
  335.   if (c == EOF)
  336.     FATAL ("BPL file ended in the midst of a string");
  337.  
  338.   /* Add the terminating null.  */
  339.   vs_append_char (&vs, 0);
  340.  
  341.   /* Cheat and use `scanf' to see if this string is really a real.  */
  342.   if (float_ok (VS_CHARS (vs)))
  343.     {
  344.       t = T_REALSTR;
  345.       yylval.realval = atof (VS_CHARS (vs));
  346.     }
  347.   else
  348.     {
  349.       t = T_STRING;
  350.       yylval.strval = VS_CHARS (vs);
  351.     }
  352.   
  353.   return t;
  354. }
  355.  
  356. /* Return the Bison-defined value for the token equal to the
  357.    next nonalpha-delimited word in the file F, unless the word is
  358.    ``comment''; in that case, ignore everything through the next `)' and
  359.    return NOT_A_TOKEN.  */
  360.    
  361. static int
  362. get_word_token (FILE *f)
  363. {
  364.   int c, t;
  365.   variable_string word = vs_init ();
  366.  
  367.   while ((c = getc (f)) != EOF && isalpha (c))
  368.     vs_append_char (&word, c);
  369.   
  370.   if (c != EOF)
  371.     ungetc (c, f);
  372.  
  373.   /* Add the terminating null.  */
  374.   vs_append_char (&word, 0);
  375.  
  376.   if (STREQ (VS_CHARS (word), "comment"))
  377.     {
  378.       while ((c = getc (f)) != EOF && c != ')')
  379.         ;
  380.       if (c == EOF)
  381.         FATAL ("BPL file ended in the midst of a comment");
  382.       t = NOT_A_TOKEN;
  383.     }
  384.   else
  385.     t = token_number (VS_CHARS (word));
  386.   
  387.   /* We don't need the characters in the identifier again.  */
  388.   vs_free (&word);
  389.   
  390.   return t;
  391. }
  392.  
  393.  
  394. /* Return the token code corresponding to the word STR.  If STR is not
  395.    one of the reserved words, give an error message and return NOT_A_TOKEN:
  396.    this is a language which doesn't have arbitrary user identifiers.  */
  397.  
  398. static int
  399. token_number (string word)
  400. {
  401.   int t = NOT_A_TOKEN;
  402.   
  403.   if (STREQ (word, "bb"))
  404.     return TR_BB;
  405.   else if (STREQ (word, "char"))
  406.     return TR_CHAR;
  407.   else if (STREQ (word, "designsize"))
  408.     return TR_DESIGNSIZE;
  409.   else if (STREQ (word, "fontbb"))
  410.     return TR_FONTBB;
  411.   else if (STREQ (word, "fontcomment"))
  412.     return TR_FONTCOMMENT;
  413.   else if (STREQ (word, "fontfile"))
  414.     return TR_FONTFILE;
  415.   else if (STREQ (word, "line"))
  416.     return TR_LINE;
  417.   else if (STREQ (word, "nchars"))
  418.     return TR_NCHARS;
  419.   else if (STREQ (word, "outline"))
  420.     return TR_OUTLINE;
  421.   else if (STREQ (word, "spline"))
  422.     return TR_SPLINE;
  423.   else if (STREQ (word, "width"))
  424.     return TR_WIDTH;
  425.  
  426.   return t;
  427. }
  428.