home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 5 / Amiga Tools 5.iso / tools / developer-tools / c-tools / mui2c / mui.l < prev    next >
Encoding:
Text File  |  1996-06-22  |  11.9 KB  |  479 lines

  1. /* Flex definition file.
  2.  *
  3.  * State description:
  4.  *
  5.  * <initial>    -- Before parsing the Class keyword
  6.  * <predata>    -- After parsing the Class clause, before Data keyword
  7.  * <maincode>   -- After parsing the Data clause, outside of any methods
  8.  *
  9.  *
  10.  *      <initial> + "Class("   -> <cls>             -- Encountered start of Class clause
  11.  *          <cls> + "<name>"   -> <postcls>         -- Encountered name of class
  12.  *      <postcls> + "::"       -> <supercls>        -- Encountered start of Superclass section
  13.  *     <supercls> + "<name>"   -> <postsupercls>    -- Encountered name of superclass
  14.  * <postsupercls> + "):"       -> <basecode>        -- Encountered start of base code clause
  15.  *     <basecode> + "<number>" -> <predata>         -- Encountered value of base code
  16.  *
  17.  *
  18.  *      <predata> + "Data("    -> <predataname>     -- Encountered start of Data clause
  19.  *  <predataname> + "<name>"   -> <postdataname>    -- Encountered name of data
  20.  * <postdataname> + ")"        -> <maincode>        -- Encountered end of Data clause
  21.  *
  22.  *
  23.  *     <maincode> + "Method("  -> <premethname>     -- Encountered start of Method clause
  24.  *  <premethname> + "<name>"   -> <postmethname>    -- Encountered name of method
  25.  * <postmethname> + "){"       -> <inmethcode>      -- Encountered start of method code
  26.  *   <inmethcode> + "}"        -> <maincode>        -- Encountered end of method code
  27.  *
  28.  *
  29.  *     <maincode> + "Method(OM_GET){" -> <ingmethcode>  -- Encountered start of OM_GET method code
  30.  *  <ingmethcode> + "Attributes{"     -> <ingattname>   -- Encountered start of OM_GET attributes
  31.  *   <ingattname> + "<name>"          -> <ingattblk>    -- Encountered name of an attribute
  32.  *   <ingattblk>  + "{"               -> <ingattcode>   -- Encountered start of an attribute definition
  33.  *   <ingattcode> + "}"               -> <ingattname>   -- Encountered end of an attribute definition
  34.  *   <ingattname> + "}"               -> <ingmethcode>  -- Encountered end of OM_GET attributes
  35.  *  <ingmethcode> + "}"               -> <maincode>     -- Encountered end of OM_GET method code
  36.  *
  37.  *
  38.  *     <maincode> + "Method(OM_SET){" -> <insmethcode>  -- Encountered start of OM_SET method code
  39.  *  <insmethcode> + "Attributes{"     -> <insattname>   -- Encountered start of OM_SET attributes
  40.  *   <insattname> + "<name>"          -> <insattblk>    -- Encountered name of an attribute
  41.  *   <insattblk>  + "{"               -> <insattcode>   -- Encountered start of an attribute definition
  42.  *   <insattcode> + "}"               -> <insattname>   -- Encountered end of an attribute definition
  43.  *   <insattname> + "}"               -> <insmethcode>  -- Encountered end of OM_SET attributes
  44.  *  <insmethcode> + "}"               -> <maincode>     -- Encountered end of OM_SET method code
  45.  *
  46.  *
  47.  */
  48.  
  49. %x comment
  50. %x bracket
  51. %x cppcomment
  52. %x cls
  53. %x postcls
  54. %x supercls
  55. %x postsupercls
  56. %x basecode
  57. %x predata
  58. %x predataname
  59. %x postdataname
  60. %x maincode
  61. %x premethname
  62. %x postmethname
  63. %x inmethcode
  64. %x ingmethcode
  65. %x insmethcode
  66. %x ingattname
  67. %x insattname
  68. %x ingattblk
  69. %x insattblk
  70. %x ingattcode
  71. %x insattcode
  72. %option stack
  73. %option noyywrap 
  74.  
  75. %{
  76. #include <stdlib.h>
  77. #include <string.h>
  78. #include "id.h"
  79.  
  80. char outfilename[1024], headerfilename[1024], privheaderfilename[1024], tempname[1024];
  81. unsigned long base, vars = 0, trailer = 0, atttrailer = 0;
  82.  
  83. const char version[]="$VER: mui2c 1.2 (22.06.96) ©1996 Jason Birch\0";
  84. %}
  85.  
  86. SP      [ \t]*
  87. NL      \n*
  88. SPNL    [ \t\n]*
  89. NAME    [A-Za-z0-9_]+
  90. SPCNAME [A-Za-z0-9_ ]+
  91. NUM     [0-9xa-fA-F]+
  92. OPEN    {SP}"("{SP}
  93. PUBLIC  ":"{SP}"public"{SP}
  94. CLOSE   {SP}")"{SP}
  95. CLOSEP  {CLOSE}{PUBLIC}
  96. OPENBLK {SPNL}"{"{SP}{NL}
  97. NOBRKT  [^"{}"]+
  98. CLASS   ^{SP}Class{SP}{OPEN}
  99. DATA    ^{SP}Data{SP}{OPEN}
  100. METHOD  ^{SP}Method{SP}{OPEN}
  101. METHODS ^{SP}"Method*"{SP}{OPEN}
  102. ATTRIB  ^{SP}Attributes{SP}{OPENBLK}
  103.  
  104. %%
  105.  
  106. %{
  107. /* Rules to handle the class definition.
  108.  */
  109. %}
  110.  
  111. {CLASS}                     BEGIN(cls);
  112.  
  113. <cls>{NAME}             {   SetClassName(yytext);
  114.                             MakeMainHeader(yyout,headerfilename,privheaderfilename);
  115.                             BEGIN(postcls);
  116.                         }
  117.  
  118. <postcls>{
  119.         {SP}"::"{SP}        BEGIN(supercls);
  120.         {CLOSE}         {   printf("Error: Superclass must be specified after class name.\n");
  121.                             exit(1);
  122.                         }
  123.         {SP}[^"::"]     {   printf("Error: Class name must not contain spaces.\n");
  124.                             exit(1);
  125.                         }
  126. }
  127.  
  128. <supercls>{NAME}        {   SetSuperClassName(yytext);
  129.                             BEGIN(postsupercls);
  130.                         }
  131.  
  132. <postsupercls>{
  133.         {SP}[^")"]      {   printf("Error: Superclass name must not contain spaces.\n");
  134.                             exit(1);
  135.                         }
  136.         {CLOSE}{SP}":"      BEGIN(basecode);
  137.         {CLOSE}         {   printf("Error: Base tag value must follow superclass definition.\n");
  138.                             exit(1);
  139.                         }
  140. }
  141.  
  142. <basecode>{
  143.         {SP}{NUM}{SPNL} {   char *end;
  144.                             base = strtol(yytext,&end,0);
  145.                             BEGIN(predata);
  146.                         }
  147.         .               {   printf("Error: Invalid base tag. Must be octal, decimal, or hexadecimal.\n");
  148.                             exit(1);
  149.                         }
  150.         {SPNL}          {   printf("Error: Missing base tag.\n");
  151.                             exit(1);
  152.                         }
  153. }
  154.  
  155. %{
  156. /* Followed by rules to handle the data definition.
  157.  */
  158. %}
  159.  
  160. <predata>{DATA}             BEGIN(predataname);
  161.  
  162. <*>{DATA}               {   printf("Error: Data keyword found while Class undefined.\n");
  163.                             exit(1);
  164.                         }
  165.  
  166. <predataname>{SPCNAME}  {   SetDataName(yytext);
  167.                             BEGIN(postdataname);
  168.                         }
  169.  
  170. <postdataname>{CLOSE}{SPNL} {
  171.                             BEGIN(maincode);
  172.                             fprintf(yyout,messages[DEFINES]);
  173.                         }
  174.  
  175.  
  176. %{
  177. /* Ready to parse the main code now.
  178.  * Method definitions are recognized and the state changed appropriately.
  179.  * OM_GET and OM_SET are handled separately because they have nested Attribute
  180.  * structures.
  181.  */
  182. %}
  183.  
  184. <maincode>{
  185.         {METHOD}OM_GET{CLOSEP}{OPENBLK} |
  186.         {METHOD}OM_GET{CLOSE}{OPENBLK} {
  187.                             fprintf(yyout,messages[GET_HEADER],clsname);
  188.                             Add("OM_GET",METHOD);
  189.                             BEGIN(ingmethcode);
  190.                             fprintf(yyout,messages[MTH_VARS],dataname);
  191.                             fprintf(yyout,messages[GET_VARS]);
  192.                         }
  193.  
  194.         {METHOD}OM_SET{CLOSEP}{OPENBLK} |
  195.         {METHOD}OM_SET{CLOSE}{OPENBLK} {
  196.                             fprintf(yyout,messages[SET_HEADER],clsname);
  197.                             Add("OM_SET",METHOD);
  198.                             BEGIN(insmethcode);
  199.                             fprintf(yyout,messages[MTH_VARS],dataname);
  200.                             fprintf(yyout,messages[SET_VARS]);
  201.                         }
  202.  
  203.         {METHODS}       {   vars = MTH_VARS_SMALL;
  204.                             trailer = MTH_TRAILER_SMALL;
  205.                             BEGIN(premethname);
  206.                         }
  207.  
  208.         {METHOD}        {   vars = MTH_VARS;
  209.                             trailer = MTH_TRAILER;
  210.                             BEGIN(premethname);
  211.                         }
  212. }
  213.  
  214. <*>{METHOD}             {   printf("Error: Method keyword found while instance data undefined.\n");
  215.                             exit(1);
  216.                         }
  217.  
  218.  
  219. %{
  220. /* Handle a standard method.
  221.  */
  222. %}
  223.  
  224. <premethname>{NAME}     {   Add(yytext, METHOD);
  225.                             fprintf(yyout,messages[MTH_HEADER],clsname,yytext);
  226.                             if (vars == MTH_VARS)
  227.                                 CheckSpecialCases(yytext, &vars, &trailer);
  228.                             BEGIN(postmethname);
  229.                         }
  230.  
  231. <postmethname>{
  232.         {CLOSEP}{OPENBLK} {
  233.                             MakePublic();   /* This method was flagged as public */
  234.                             BEGIN(inmethcode);
  235.                             if (vars == 0){
  236.                                 printf("Panic: Internal error 'vars'!\n");
  237.                                 exit(1);
  238.                             }
  239.                             fprintf(yyout,messages[vars],dataname);
  240.                             vars = 0;
  241.                         }
  242.         {CLOSE}{OPENBLK} {
  243.                             BEGIN(inmethcode);
  244.                             if (vars == 0){
  245.                                 printf("Panic: Internal error 'vars'!\n");
  246.                                 exit(1);
  247.                             }
  248.                             fprintf(yyout,messages[vars],dataname);
  249.                             vars = 0;
  250.                         }
  251.  
  252.         [^")"]          {   printf("Error: Method name must not contain spaces.\n");
  253.                             exit(1);
  254.                         }
  255. }
  256.  
  257. <inmethcode>{SP}"}"     {   if (trailer == 0){
  258.                                 printf("Panic: Internal error 'trailer'!\n");
  259.                                 exit(1);
  260.                             }
  261.                             fprintf(yyout,messages[trailer]);
  262.                             trailer = 0;
  263.                             BEGIN(maincode);
  264.                         }
  265.  
  266. %{
  267. /* End of a standard method. Goes back to the main code now.
  268.  */
  269. %}
  270.  
  271. %{
  272. /* Handle an OM_GET method.
  273.  */
  274. %}
  275.  
  276. <ingmethcode>{
  277.         {ATTRIB}        {   fprintf(yyout,messages[INGETMETH]);
  278.                             BEGIN(ingattname);
  279.                         }
  280.         {SP}"}"         {   fprintf(yyout,messages[GET_TRAILER]);
  281.                             BEGIN(maincode);
  282.                         }
  283. }
  284.  
  285. <ingattname>{
  286.         {SPNL}              ECHO;
  287.         {NAME}/"*"      {   Add(yytext, ATTRIBUTE);
  288.                             fprintf(yyout,messages[CASE],yytext);
  289.                             BEGIN(ingattblk);
  290.                             atttrailer = ATT_TRAILER_SMALL;
  291.                             input();    /* Get rid of "*" */
  292.                         }             
  293.         {NAME}          {   Add(yytext, ATTRIBUTE);
  294.                             fprintf(yyout,messages[CASE],yytext);
  295.                             BEGIN(ingattblk);
  296.                             atttrailer = GET_ATT_TRAILER;
  297.                         }
  298.         {SP}"}"         {   fprintf(yyout,messages[GET_DEFS_TRAILER]);
  299.                             BEGIN(ingmethcode);
  300.                         }
  301. }
  302.  
  303. <ingattblk>{
  304.         {SP}{PUBLIC}        MakePublic();
  305.         {OPENBLK}       {   ECHO;
  306.                             BEGIN(ingattcode);
  307.                         }
  308.         .               {   printf("Error: No attribute definition.\n");
  309.                             exit(1);
  310.                         }
  311. }
  312.  
  313. <ingattcode>{
  314.         {SP}"}"         {   if ((atttrailer != GET_ATT_TRAILER) && (atttrailer != ATT_TRAILER_SMALL)){
  315.                                 printf("Panic: Internal error 'atttrailer'.\n");
  316.                                 exit(1);
  317.                             }
  318.                             fprintf(yyout,messages[atttrailer]);
  319.                             BEGIN(ingattname);
  320.                         }
  321.         {NOBRKT}           ECHO;
  322. }
  323.  
  324. %{
  325. /* Handle an OM_SET method.
  326.  */
  327. %}
  328.  
  329. <insmethcode>{
  330.         {ATTRIB}        {   fprintf(yyout,messages[INSETMETH]);
  331.                             BEGIN(insattname);
  332.                         }
  333.         {SP}"}"         {   fprintf(yyout,messages[SET_TRAILER]);
  334.                             BEGIN(maincode);
  335.                         }
  336. }
  337.  
  338. <insattname>{
  339.         {SPNL}              ECHO;
  340.         {NAME}/"*"      {   Add(yytext, ATTRIBUTE);
  341.                             fprintf(yyout,messages[CASE],yytext);
  342.                             BEGIN(insattblk);
  343.                             atttrailer = ATT_TRAILER_SMALL;
  344.                             input();    /* Get rid of "*" */
  345.                         }
  346.         {NAME}          {   Add(yytext, ATTRIBUTE);
  347.                             fprintf(yyout,messages[CASE],yytext);
  348.                             BEGIN(insattblk);
  349.                             atttrailer = SET_ATT_TRAILER;
  350.                         }
  351.         {SP}"}"         {   fprintf(yyout,messages[SET_DEFS_TRAILER]);
  352.                             BEGIN(insmethcode);
  353.                         }
  354. }
  355.  
  356. <insattblk>{
  357.         {SP}{PUBLIC}        MakePublic();
  358.         {OPENBLK}       {   ECHO;
  359.                             BEGIN(insattcode);
  360.                         }
  361.         .               {   printf("Error: No attribute definition.\n");
  362.                             exit(1);
  363.                         }
  364. }
  365.  
  366. <insattcode>{
  367.         {SP}"}"         {   if ((atttrailer != SET_ATT_TRAILER) && (atttrailer != ATT_TRAILER_SMALL)){
  368.                                 printf("Panic: Internal error 'atttrailer'.\n");
  369.                                 exit(1);
  370.                             }
  371.                             fprintf(yyout,messages[atttrailer]);
  372.                             BEGIN(insattname);
  373.                         }
  374.         {NOBRKT}        ECHO;
  375. }
  376.  
  377.  
  378. <*>{ATTRIB}             {   printf("Error: Attributes keyword may only be used within OM_GET and OM_SET methods.\n");
  379.                             exit(1);
  380.                         }
  381.  
  382.  
  383.  
  384. %{
  385. /* Handle nested brackets within other structures.
  386.  * We don't want to mistakenly grab a "}" that belongs to another "{".
  387.  */
  388. %}
  389.  
  390. <*>"{"                  {   yy_push_state(bracket);
  391.                             ECHO;
  392.                         }
  393.  
  394. <bracket>{
  395.         NOBRKT              ECHO;
  396.         {SP}"}"         {   yy_pop_state();
  397.                             ECHO;
  398.                         }
  399.         <<EOF>>         {   printf("Error: Unclosed bracket.\n");
  400.                             exit(1);
  401.                         }
  402. }
  403.  
  404.  
  405.  
  406. %{
  407. /* Handle the various forms of comment.
  408.  */
  409. %}
  410.  
  411. <*>"/*"                 {   yy_push_state(comment);
  412.                             ECHO;
  413.                         }
  414. <comment>{
  415.         [^"*/"]*            ECHO;
  416.         "*/"            {   yy_pop_state();
  417.                             ECHO;
  418.                         }
  419.         <<EOF>>         {   printf("Error: Unclosed comment.\n");
  420.                             exit(1);
  421.                         }
  422. }
  423.  
  424. <cppcomment>{
  425.          [^\n]+             ECHO;
  426.         \n              {   yy_pop_state();
  427.                             ECHO;
  428.                         }
  429. }
  430.  
  431. <*>"//"                 {   yy_push_state(cppcomment);
  432.                             ECHO;
  433.                         }
  434.  
  435. <*>"}"                  {   printf("Error: Unexpected }.\n");
  436.                             ECHO;
  437.                         }
  438.  
  439.  
  440. %%
  441. main(int argc, char **argv)
  442. {
  443.     char *extension;
  444.     int length;
  445.  
  446.     if (argc != 2){
  447.         fprintf(stderr,"Usage: %s <filename>\n",argv[0]);
  448.         exit(1);
  449.     }
  450.  
  451.     length = strlen(argv[1]);
  452.     extension = &(argv[1][length - 2]);
  453.  
  454.     if (strcmp(extension,".m") == 0 ||
  455.         strcmp(extension,".M") == 0){
  456.         strncpy(tempname,argv[1],length-2);
  457.         tempname[length-2] = '\0';
  458.     } else
  459.         strcpy(tempname,argv[1]);
  460.  
  461.     sprintf(outfilename, "%s.c", tempname);
  462.     sprintf(headerfilename, "%s.h", tempname);
  463.     sprintf(privheaderfilename, "%sp.h", tempname);
  464.  
  465.     if (!(yyin = fopen(argv[1], "r"))){
  466.         fprintf(stderr,messages[ERROPENR],tempname);
  467.         exit(1);
  468.     }
  469.  
  470.     if (!(yyout = fopen(outfilename, "w"))){
  471.         fprintf(stderr,messages[ERROPENW],outfilename);
  472.         exit(1);
  473.     }
  474.  
  475.     yylex();
  476.     MakeHeaders(headerfilename,privheaderfilename,base);
  477.     MakeHousekeeping(yyout);
  478. }
  479.