Advertisement
Guest User

Optimization Strange Behaviour

a guest
Feb 2nd, 2013
25
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 17.43 KB | None | 0 0
  1. /*
  2.   Everything running on a Mac OS X Lion, GCC 4.8 got from macports, CLang from recent repository.
  3.  
  4.   GCC 4.8 -O0: TODO! [gypsy.c, line 433]
  5.   GCC 4.8 -01: Parses the file successfully.
  6.   GCC 4.8 -O2: Unexpected high byte on file (0xE0).
  7.   GCC 4.8 -O3: Unexpected high byte on file (0xE0).
  8.  
  9.   CLang, last version (3.3, trunk 173610), -Wno-return-type, -O0: Parses the file successfully.
  10.   CLang, last version (3.3, trunk 173610), -Wno-return-type, -O1: Unexpected high byte on file (0xE0).
  11.   CLang, last version (3.3, trunk 173610), -Wno-return-type, -O2: Unexpected high byte on file (0xE0).
  12.   CLang, last version (3.3, trunk 173610), -Wno-return-type, -O3: Unexpected high byte on file (0xE0).
  13.   CLang, last version (3.3, trunk 173610), -Wno-return-type, -O4: Unexpected high byte on file (0xE0).
  14.  
  15. */
  16.  
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include <string.h>
  20.  
  21. #define fallthrough
  22.  
  23.  
  24. char *strtrim(str) char *str; {
  25.   /* Declarations */
  26.   static char buf[64];
  27.   auto i, x, len;
  28.   /* Statements */
  29.   len = strlen(str);
  30.   x = 0;
  31.   for(i = 0; i < len; i++) {
  32.     if((!x) && (str[i] == ' ' || str[i] == '\t'))
  33.       continue;
  34.     buf[x++] = str[i];
  35.   }
  36.   buf[x] = 0;
  37.   while(--x)
  38.     if(buf[x]  == ' ' || buf[x] == '\t')
  39.       buf[x] = 0;
  40.     else break;
  41.   return buf;
  42. }
  43.  
  44. char *zalloc(size) size_t size; {
  45.   /* Declarations */
  46.   char *result;
  47.   /* Statements */
  48.   result = malloc(size);
  49.   if(result) {
  50.     memset(result, 0, size);
  51.     return result;
  52.   } else {
  53.     printf("Memory exausted: aborting.\n");
  54.     exit(-1);
  55.   }
  56. }
  57.  
  58.  
  59.  
  60. //----------------------------------
  61.  
  62.  
  63. /* Needed constants for the GYPSY parser, plus a default buffer size */
  64. #define GYPSY_ASSURE   0x101 /**< */
  65. #define GYPSY_THAT     0x102 /**< */
  66. #define GYPSY_COMPILES 0x103 /**< */
  67. #define GYPSY_LINKS    0x104 /**< */
  68. #define GYPSY_INTO     0x105 /**< */
  69. #define GYPSY_SUCCEEDS 0x106 /**< */
  70. #define GYPSY_FAILS    0x107 /**< */
  71. #define GYPSY_RETURNS  0x108 /**< */
  72. #define GYPSY_EXISTS   0x109 /**< */
  73. #define GYPSY_OUTPUTS  0x10A /**< */
  74. #define GYPSY_SET      0x10B /**< */
  75. #define GYPSY_TO       0x10C /**< */
  76. #define GYPSY_UNSET    0x10D /**< */
  77. #define GYPSY_BLOCK    0x10E /**< */
  78. #define GYPSY_TEXT     0x10F /**< */
  79. #define GYPSY_FILE     0x110 /**< */
  80. #define GYPSY_EOF      0x111 /**< */
  81. #define GYPSY_BUF      0x800 /**< */
  82.  
  83. /** GYPSY Token Str: returns a string representation of a GYPSY parser token. */
  84. char *gypsy_token_str(token) {
  85.   /* Declarations */
  86.   static char buf[64];
  87.   /* Statements */
  88.   switch(token) {
  89. #define TOKEN(x, s) case x: strcpy(buf, #x); strcat(buf, s); break
  90.     TOKEN(GYPSY_ASSURE,   "");
  91.     TOKEN(GYPSY_THAT,     "");
  92.     TOKEN(GYPSY_COMPILES, "");
  93.     TOKEN(GYPSY_LINKS,    "");
  94.     TOKEN(GYPSY_INTO,     "");
  95.     TOKEN(GYPSY_SUCCEEDS, "");
  96.     TOKEN(GYPSY_FAILS,    "");
  97.     TOKEN(GYPSY_RETURNS,  "");
  98.     TOKEN(GYPSY_OUTPUTS,  "");
  99.     TOKEN(GYPSY_SET,      "");
  100.     TOKEN(GYPSY_UNSET,    "");
  101.     TOKEN(GYPSY_BLOCK,    "");
  102.     TOKEN(GYPSY_TEXT,     "");
  103.     TOKEN(GYPSY_FILE,     "");
  104. #undef TOKEN
  105.     default:
  106.       /* If we fall here, the token is an ASCII character */
  107.       sprintf(buf, "`%c' (0x%02X)", token, token);
  108.   }
  109.   /* Return the temporary buffer... note that this function is not reentrant */
  110.   return buf;
  111. }
  112.  
  113. /**
  114.  *
  115.  */
  116. static struct {
  117.   char *name;
  118.   int token;
  119. } gypsy_keywords[] = {
  120.   {"assure",   GYPSY_ASSURE},
  121.   {"that",     GYPSY_THAT},
  122.   {"compiles", GYPSY_COMPILES},
  123.   {"links",    GYPSY_LINKS},
  124.   {"into",     GYPSY_INTO},
  125.   {"succeeds", GYPSY_SUCCEEDS},
  126.   {"fails",    GYPSY_FAILS},
  127.   {"returns",  GYPSY_RETURNS},
  128.   {"exists",   GYPSY_EXISTS},
  129.   {"outputs",  GYPSY_OUTPUTS},
  130.   {"set",      GYPSY_SET},
  131.   {"to",       GYPSY_TO},
  132.   {"unset",    GYPSY_UNSET}
  133. };
  134.  
  135. /**
  136.  *
  137.  */
  138. gypsy_cmd_compiles(input, output) char *input, *output; {
  139.  
  140. }
  141.  
  142. /**
  143.  *
  144.  */
  145. gypsy_cmd_links(input, output) char *input, *output; {
  146.  
  147. }
  148.  
  149. /**
  150.  *
  151.  */
  152. gypsy_cmd_succeeds(command, foo) char *command, *foo; {
  153.  
  154. }
  155.  
  156. /**
  157.  *
  158.  */
  159. gypsy_cmd_fails(command, foo) char *command, *foo; {
  160.  
  161. }
  162.  
  163. /**
  164.  *
  165.  */
  166. gypsy_cmd_returns(command, exit_code) char *command, *exit_code; {
  167.  
  168. }
  169.  
  170. /**
  171.  *
  172.  */
  173. gypsy_cmd_exists(filename, foo) char *filename, *foo; {
  174.  
  175. }
  176.  
  177. /**
  178.  *
  179.  */
  180. gypsy_cmd_outputs(command, text) char *command, *text; {
  181.  
  182. }
  183.  
  184. /** */
  185. typedef struct gypsy_command {
  186.   char argument1[64];
  187.   char argument2[64];
  188.   int (*callback)(char *, char *);
  189.   struct gypsy_command *next;
  190. } gypsy_command;
  191.  
  192. /** */
  193. typedef struct gypsy_parser {
  194.   char filename[64];
  195.   FILE *file;
  196.   int line;
  197.   int ahead_line;
  198.   int token;
  199.   int ahead;                        
  200.   int behind;
  201.   gypsy_command *head;
  202.   gypsy_command *tail;
  203.   int sol;
  204.   char buf[GYPSY_BUF];
  205.   char aux[GYPSY_BUF];
  206.   char err[GYPSY_BUF];
  207. } gypsy_parser;
  208.  
  209. /** */
  210. gypsy_chain_command(parser, command) gypsy_parser *parser;
  211.                                      gypsy_command *command; {
  212.   if(parser->head) {
  213.    
  214.     printf("todo lol lol lol\n");
  215.     exit(-1);
  216.    
  217.    
  218.   } else {
  219.     parser->head = command;
  220.     parser->tail = command;
  221.   }
  222. }
  223.  
  224. /** */
  225. gypsy_lacking_newline(parser) gypsy_parser *parser; {
  226.   printf("Warning: no newline at the end of file (%s).\n", parser->filename);
  227. }
  228.  
  229. /** */
  230. gypsy_parse_error(parser) gypsy_parser *parser; {
  231.   printf("GYPSY Error (%s, line %d)! ", parser->filename, parser->line);
  232.   puts(parser->err);
  233.   exit(-1);
  234. }
  235.  
  236. /** GYPSY To Do: helper function to show an error for some missing part. */
  237. gypsy_todo(parser, file, line) gypsy_parser *parser; char *file; {
  238.   sprintf(parser->err, "TODO! [%s, line %d]", file, line);
  239.   gypsy_parse_error(parser);
  240. }
  241.  
  242. /** Simplify the task by automatically adding the position of the call. */
  243. #define gypsy_todo(parser) gypsy_todo(parser, __FILE__, __LINE__)
  244.  
  245. /** */
  246. gypsy_try_keyword(peek, parser, real) gypsy_parser *parser; {
  247.   /* Declarations */
  248.   auto i, j;
  249.   char buf[32];
  250.   /* Statements */
  251.   for(i = 0; i < sizeof(gypsy_keywords) / sizeof(gypsy_keywords[0]); i++) {
  252. #define keyword gypsy_keywords[i]
  253.     /* */
  254.     if(keyword.name[0] == tolower(peek)) {
  255.       for(j = 1; j < strlen(keyword.name); j++) {
  256.         buf[j] = fgetc(parser->file);
  257.         if(keyword.name[j] != tolower(buf[j])) {
  258.           while(j) {
  259.             ungetc(buf[j], parser->file);
  260.             j--;
  261.           }
  262.           goto next;
  263.         }
  264.       }
  265.       /* Matches! */
  266.       parser->ahead = keyword.token;
  267.       if(real)
  268.         parser->aux[0] = 0;
  269.       else {
  270.         /* If we were just checking ahead, unget everything */
  271.         while(j) {
  272.           ungetc(buf[j], parser->file);
  273.           j--;
  274.         }
  275.         ungetc(peek, parser->file);
  276.       }
  277.       return 1;
  278.     }
  279.     /* */
  280.     next: fallthrough;
  281. #undef keyword
  282.   }
  283.   /* */
  284.   return 0;
  285. }
  286.  
  287. /** */
  288. gypsy_get_lookahead(parser) gypsy_parser *parser; {
  289.   /* Declarations */
  290.   auto peek, prev, i, j;
  291.   /* Statements */
  292.   peek = fgetc(parser->file);
  293.   if(peek > 0x7F) {
  294.     sprintf(parser->err, "Unexpected high byte on file (0x%02X).", peek);
  295.     gypsy_parse_error(parser);
  296.   }
  297.   /* */
  298.   switch(peek) {
  299.     case -1:
  300.       if(!parser->sol)
  301.         gypsy_lacking_newline(parser);
  302.       parser->ahead = GYPSY_EOF;
  303.       break;
  304.     /* Check for possible comments */
  305.     case '(':
  306.       peek = fgetc(parser->file);
  307.       if(peek == '*') {
  308.         /* We started a comment */
  309.         parser->sol = 0;
  310.         /* Eat it up */
  311.         peek = fgetc(parser->file);
  312.         do {
  313.           prev = peek;
  314.           peek = fgetc(parser->file);
  315.           if(prev == '*' && peek == ')')
  316.             return gypsy_get_lookahead(parser);
  317.           if(peek == '\n' || ((prev == '\r' && peek != '\n')))
  318.             parser->ahead_line++;
  319.         } while(peek > 0);
  320.         /* Unterminated comment found */
  321.         sprintf(parser->err, "Unterminated comment.");
  322.         gypsy_parse_error(parser);
  323.       } else stray: {
  324.         sprintf(parser->err, "Stray '%c' (0x%02X) on file.", peek, peek);
  325.         gypsy_parse_error(parser);
  326.       };
  327.     /* */
  328.     case ' ':
  329.     case '\t':
  330.       parser->sol = 0;
  331.       do {
  332.         strcat(parser->aux, peek == ' ' ? " " : "\t");
  333.         peek = fgetc(parser->file);
  334.       } while(peek == ' ' || peek == '\t');
  335.       ungetc(peek, parser->file);
  336.       return gypsy_get_lookahead(parser);
  337.     case '\r':
  338.       /* Special check for \r\n to count as one single line */
  339.       peek = fgetc(parser->file);
  340.       if(peek != '\n')
  341.         ungetc(peek, parser->file);
  342.       fallthrough;
  343.     case '\n':
  344.       parser->sol = 1;
  345.       /* Increase the line counter, and warn the newline (only once!) */
  346.       parser->ahead_line++;
  347.       /* Clean the auxiliar buffer */
  348.       parser->aux[0] = 0;
  349.       /* Resume the procedure */
  350.       return gypsy_get_lookahead(parser);
  351.     /* */
  352.     case '[':
  353.      
  354.       if(parser->sol) {
  355.         i = 0;
  356.         do {
  357.           prev = peek;
  358.           peek = fgetc(parser->file);
  359.          
  360.           parser->aux[i] = peek;
  361.          
  362.           if(prev == ']') {
  363.             if(peek == -1)
  364.               gypsy_lacking_newline(parser);
  365.             else
  366.               if(peek == '\n' || peek == '\r')
  367.                 ungetc(peek, parser->file);
  368.               else {
  369.                 sprintf(parser->err, "Unexpected `%c', expected newline.",
  370.                         peek);
  371.                 gypsy_parse_error(parser);
  372.               }
  373.             /* */
  374.             parser->aux[i] = 0;
  375.             /* */
  376.             parser->ahead = GYPSY_BLOCK;
  377.             /* We are done here */
  378.             return;
  379.           } else
  380.             /*
  381.               We should increase the counter if the current character isn't
  382.               the end of the block
  383.             */
  384.             if(peek != ']')
  385.               i++;
  386.         } while(peek > 0);
  387.         /* Falling here, the file has ended */
  388.         sprintf(parser->err, "Unterminated block.");
  389.         gypsy_parse_error(parser);
  390.       } else {
  391.         gypsy_todo(parser);
  392.       }
  393.     case ';':
  394.     case '.':
  395.       parser->aux[0] = 0;
  396.       parser->ahead = peek;
  397.       break;
  398.     default:
  399.       if(gypsy_try_keyword(peek, parser, 1))
  400.         return;
  401.       else
  402.         for(i = strlen(parser->aux); peek > 0; i++) {
  403.           parser->aux[i] = peek;
  404.           peek = fgetc(parser->file);
  405.           if(peek == -1) finish_text: {
  406.             parser->aux[i] = 0;
  407.             parser->ahead = GYPSY_TEXT;
  408.             return;
  409.           }
  410.           if(gypsy_try_keyword(peek, parser, 0)) {
  411.             goto finish_text;
  412.           }
  413.           if(peek == '\n' || peek == '\r' || peek == ';') {
  414.             ungetc(peek, parser->file);
  415.             i++;
  416.             goto finish_text;
  417.           }
  418.           if(peek == '.') {
  419.             peek = fgetc(parser->file);
  420.             if(!peek)
  421.               break;
  422.             if(peek == '\n' || peek == '\r') {
  423.               /* Dot token instead of part of the text */
  424.               ungetc(peek, parser->file);
  425.               ungetc('.', parser->file);
  426.               i++;
  427.               goto finish_text;
  428.             }
  429.            
  430.             parser->aux[i++] = peek;
  431.           }
  432.         }
  433.       gypsy_todo(parser);
  434.   };
  435. }
  436.  
  437. /** */
  438. gypsy_get_token(parser) gypsy_parser *parser; {
  439.   parser->behind = parser->token;
  440.   /* If running for the first time, get two tokens */
  441.   if(!parser->token)
  442.     gypsy_get_lookahead(parser);
  443.   /* Move the previous lookahead to the current token */
  444.   parser->line = parser->ahead_line;
  445.   parser->token = parser->ahead;
  446.   strcpy(parser->buf, parser->aux);
  447.   /* And get a new lookahead */
  448.   if(parser->token != GYPSY_EOF)
  449.     gypsy_get_lookahead(parser);
  450.   return parser->token;
  451. }
  452.  
  453. gypsy_get_compiles(parser, command) gypsy_parser *parser;
  454.                                    gypsy_command *command; {
  455.   switch(parser->token) {
  456.     case GYPSY_INTO:
  457.       gypsy_get_token(parser);
  458.       if(parser->token == GYPSY_TEXT) {
  459.        
  460.         strcpy(command->argument2, strtrim(parser->buf));
  461.        
  462.        
  463.         gypsy_chain_command(parser, command);
  464.        
  465.        
  466.        
  467.         gypsy_get_token(parser);
  468.        
  469.         if(parser->token == ';' || parser->token == '.')
  470.           return;
  471.        
  472.         free(command);
  473.         sprintf(parser->err, "Expected ';' or '.' at line %d; got %s instead.",
  474.                 parser->line, gypsy_token_str(parser->token));
  475.         gypsy_parse_error(parser);
  476.        
  477.        
  478.        
  479.        
  480.       } else {
  481.         free(command);
  482.         sprintf(parser->err, "Expected GYPSY_TEXT at line %d; got %s instead.",
  483.                 parser->line, gypsy_token_str(parser->token));
  484.         gypsy_parse_error(parser);
  485.       }
  486.     case ';':
  487.     case '.':
  488.       gypsy_chain_command(parser, command);
  489.       return;
  490.     default:
  491.       free(command);
  492.       sprintf(parser->err, "Expected GYPSY_INTO at line %d; got %s instead.",
  493.               parser->line, gypsy_token_str(parser->token));
  494.       gypsy_parse_error(parser);
  495.   }
  496. }
  497.  
  498. gypsy_get_assure2(parser, command) gypsy_parser *parser;
  499.                                    gypsy_command *command; {
  500.   switch(parser->token) {
  501.     case GYPSY_COMPILES:
  502.       command->callback = gypsy_cmd_compiles;
  503.       gypsy_get_token(parser);
  504.       gypsy_get_compiles(parser, command);
  505.       break;
  506.     case GYPSY_LINKS:
  507.       command->callback = gypsy_cmd_links;
  508.       gypsy_todo(parser);
  509.     case GYPSY_SUCCEEDS:
  510.       command->callback = gypsy_cmd_succeeds;
  511.       gypsy_todo(parser);
  512.     case GYPSY_FAILS:
  513.       command->callback = gypsy_cmd_fails;
  514.       gypsy_todo(parser);
  515.     case GYPSY_RETURNS:
  516.       command->callback = gypsy_cmd_returns;
  517.       gypsy_todo(parser);
  518.     case GYPSY_OUTPUTS:
  519.       command->callback = gypsy_cmd_outputs;
  520.       gypsy_todo(parser);
  521.     default:
  522.       sprintf(parser->err, "Expected GYPSY_COMPILES, GYPSY_LINKS, GYPSY_SUCCEED"
  523.               "S, GYPSY_FAILS, GYPSY_RETURNS or GYPSY_OUTPUTS at line %d; got %"
  524.               "s instead.", parser->line, gypsy_token_str(parser->token));
  525.       gypsy_parse_error(parser);
  526.   }
  527. }
  528.  
  529. gypsy_get_assure(parser) gypsy_parser *parser; {
  530.   /* Declarations */
  531.   gypsy_command *command;
  532.   /* Statements */
  533.   if(parser->token == GYPSY_ASSURE) {
  534.     gypsy_get_token(parser);
  535.     if(parser->token == GYPSY_THAT) {
  536.       gypsy_get_token(parser);
  537.       if(parser->token == GYPSY_TEXT) {
  538.         command = (gypsy_command *)zalloc(sizeof(gypsy_command));
  539.         strcpy(command->argument1, strtrim(parser->buf));
  540.         gypsy_get_token(parser);
  541.         gypsy_get_assure2(parser, command);
  542.       } else {
  543.         sprintf(parser->err, "Expected GYPSY_TEXT at line %d; got %s instead.",
  544.                 parser->line, gypsy_token_str(parser->token));
  545.         gypsy_parse_error(parser);
  546.       }
  547.     } else {
  548.       sprintf(parser->err, "Expected GYPSY_THAT at line %d; got %s instead.",
  549.               parser->line, gypsy_token_str(parser->token));
  550.       gypsy_parse_error(parser);
  551.     }
  552.   }
  553. }
  554.  
  555. gypsy_get_unit(parser) gypsy_parser *parser; {
  556.   while(parser->token != GYPSY_EOF) {
  557.     switch(parser->token) {
  558.       case GYPSY_ASSURE:
  559.         gypsy_get_assure(parser);
  560.         if(parser->token == '.')
  561.           return;
  562.         if(parser->token == ';')
  563.           gypsy_get_token(parser);
  564.         continue;
  565.       case GYPSY_SET:
  566.       case GYPSY_UNSET:
  567.         gypsy_todo(parser);
  568.       default:
  569.         sprintf(parser->err, "Expected GYPSY_ASSURE, GYPSY_SET or GYPSY_UNSET; "
  570.                 "got %s instead.", gypsy_token_str(parser->token));
  571.         gypsy_parse_error(parser);
  572.         break;
  573.     }
  574.   }
  575. }
  576.  
  577. gypsy_get_file(parser) gypsy_parser *parser; {
  578.  
  579. }
  580.  
  581. gypsy_get_unit_or_file(parser) gypsy_parser *parser; {
  582.   if(parser->token == GYPSY_BLOCK) {
  583.     gypsy_get_token(parser);
  584.     if(strchr(parser->buf, '.'))
  585.       gypsy_get_file(parser);
  586.     else gypsy_get_unit(parser);
  587.   } else {
  588.     sprintf(parser->err, "Expected GYPSY_BLOCK; got %s instead.",
  589.             gypsy_token_str(parser->token));
  590.     gypsy_parse_error(parser);
  591.   }
  592. }
  593.  
  594. /** */
  595. gypsy_parse(parser) gypsy_parser *parser; {
  596.   /*gypsy_get_token(parser);
  597.   while(parser->token != GYPSY_EOF)
  598.     gypsy_get_unit_or_file(parser);*/
  599.    
  600.  
  601.   while(parser->token != GYPSY_EOF) {
  602.     gypsy_get_token(parser);
  603.     printf("Token: %s [%d]\n", gypsy_token_str(parser->token), parser->line);
  604.   };
  605.   exit(-1);
  606.  
  607.  
  608.  
  609.   return 1;
  610. }
  611.  
  612. /** */
  613. gypsy_parser *gypsy_open(file) char *file; {
  614.   /* Declarations */
  615.   gypsy_parser *result;
  616.   /* Statements */
  617.   result = (gypsy_parser *)zalloc(sizeof(gypsy_parser));
  618.   /* Check for the allocation */
  619.   if(result) {
  620.     result->file = fopen(file, "r");
  621.     /* If the file could be open */
  622.     if(result->file) {
  623.       /* We setup and return the newly allocated object */
  624.       result->ahead_line = 1;
  625.       result->sol = 1;
  626.       strcpy(result->filename, file);
  627.       /* And then parse it */
  628.       if(!gypsy_parse(result)) {
  629.         strcpy(result->err, "Sorry, couldn't parse file.");
  630.         gypsy_parse_error(result);
  631.       }
  632.       /* Now we can close the file and return safely */
  633.       fclose(result->file);
  634.       result->file = 0;
  635.       return result;
  636.     }
  637.   }
  638.   /* Return NULL if anything bad happened */
  639.   return 0;  
  640. }
  641.  
  642. /** */
  643. gypsy_parser *gypsy_test(parser) gypsy_parser *parser; {
  644.  
  645. }
  646.  
  647. /** */
  648. gypsy_close(parser) gypsy_parser *parser; {
  649.   if(parser)
  650.     free(parser);
  651. }
  652.  
  653.  
  654.  
  655.  
  656.  
  657.  
  658.  
  659.  
  660. int main() {
  661.  
  662.   gypsy_parser *parser = gypsy_open("test.psy");
  663.   gypsy_close(parser);
  664.  
  665.   return EXIT_SUCCESS;
  666. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement