免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: cjaizss
打印 上一主题 下一主题

娱乐一下,介绍一种语言——brainfuck [复制链接]

论坛徽章:
0
41 [报告]
发表于 2008-06-09 00:18 |只看该作者
好,不错

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
42 [报告]
发表于 2008-06-09 17:04 |只看该作者
最新的优化,一般说来,运算效率可能比之前最后一个提高%50甚至更多。(因为一个程序中一般都有数据复制或者累计的动作,而bf中都是通过反复循环仿真出来的)

  1. /*bf.c*/
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. char s[30000]={0};
  6. char code[100000];
  7. int len = 0;
  8. int  stack[100];
  9. int stack_len=0;
  10. #ifndef DEBUG
  11. #define DEBUG 0
  12. #endif
  13. int main(int argc,char**argv)
  14. {
  15.         char c;
  16.         int i,j,k,left_flag,left_offset,x=0;
  17.         int x1,x2,x3,x4;
  18.         int m,n;
  19.         FILE* f;
  20.         char* p=s+10000;
  21.         if(argc==2) {
  22.                 f=fopen(argv[1],"r");
  23.                 if(f==NULL) {
  24.                         perror("fopen");
  25.                                 return 1;
  26.                 }
  27.                 len=fread(code,1,sizeof(code),f);
  28.                 if(len==0&&len==sizeof(code)) {
  29.                         return 4;
  30.                 }
  31.         } else return 2;

  32.         /*optimization*/
  33.         /*We can prove that n is never greater than m.So we can use the same memory*/
  34.         for(m=0,n=0,c=0,j=0,left_flag=0;m<len;m++) {
  35.                 switch(code[m]) {
  36.                         case '+':
  37.                                 switch (j) {
  38.                                         case 1:
  39.                                                 code[n++]='>';
  40.                                                 break;
  41.                                         case -1:
  42.                                                 code[n++]='<';
  43.                                                 break;
  44.                                         case 0:
  45.                                                 break;
  46.                                         default:
  47.                                                 code[n++]='p';
  48.                                                 code[n++]=j;
  49.                                                 break;
  50.                                 }
  51.                                 j=0;
  52.                                 c++;
  53.                                 break;
  54.                         case '-':
  55.                                 switch (j) {
  56.                                         case 1:
  57.                                                 code[n++]='>';
  58.                                                 break;
  59.                                         case -1:
  60.                                                 code[n++]='<';
  61.                                                 break;
  62.                                         case 0:
  63.                                                 break;
  64.                                         default:
  65.                                                 code[n++]='p';
  66.                                                 code[n++]=j;
  67.                                                 break;
  68.                                 }
  69.                                 j=0;
  70.                                 c--;
  71.                                 break;
  72.                         case '>':
  73.                                 switch (c) {
  74.                                         case ((char)1):
  75.                                                 code[n++]='+';
  76.                                                 break;
  77.                                         case ((char)(-1)):
  78.                                                 code[n++]='-';
  79.                                                 break;
  80.                                         case ((char)0):
  81.                                                 break;
  82.                                         default:
  83.                                                 code[n++]='a';
  84.                                                 code[n++]=c;
  85.                                                 break;
  86.                                 }
  87.                                 c=0;
  88.                                 j++;
  89.                                 if(j==0x7f) {
  90.                                         code[n++]='p';
  91.                                         code[n++]=0x7f;
  92.                                         j=0;
  93.                                 }
  94.                                 break;
  95.                         case '<':
  96.                                 switch (c) {
  97.                                         case ((char)1):
  98.                                                 code[n++]='+';
  99.                                                 break;
  100.                                         case ((char)(-1)):
  101.                                                 code[n++]='-';
  102.                                                 break;
  103.                                         case ((char)0):
  104.                                                 break;
  105.                                         default:
  106.                                                 code[n++]='a';
  107.                                                 code[n++]=c;
  108.                                                 break;
  109.                                 }
  110.                                 c=0;
  111.                                 j--;
  112.                                 if(j==-128) {
  113.                                         code[n++]='p';
  114.                                         code[n++]=-128;
  115.                                         j=0;
  116.                                 }
  117.                                 break;
  118.                         case '.':
  119.                         case ',':
  120.                         case '[':
  121.                                 switch (c) {
  122.                                         case ((char)1):
  123.                                                 code[n++]='+';
  124.                                                 break;
  125.                                         case ((char)(-1)):
  126.                                                 code[n++]='-';
  127.                                                 break;
  128.                                         case ((char)0):
  129.                                                 break;
  130.                                         default:
  131.                                                 code[n++]='a';
  132.                                                 code[n++]=c;
  133.                                                 break;
  134.                                 }
  135.                                 c=0;
  136.                                 switch (j) {
  137.                                         case 1:
  138.                                                 code[n++]='>';
  139.                                                 break;
  140.                                         case -1:
  141.                                                 code[n++]='<';
  142.                                                 break;
  143.                                         case 0:
  144.                                                 break;
  145.                                         default:
  146.                                                 code[n++]='p';
  147.                                                 code[n++]=j;
  148.                                                 break;
  149.                                 }
  150.                                 j=0;
  151.                                 code[n++]=code[m];
  152.                                 if(code[m]=='[') {
  153.                                         left_flag=1;
  154.                                         left_offset=n;
  155.                                 }
  156.                                 break;
  157.                         case ']':
  158.                                 switch (c) {
  159.                                         case ((char)1):
  160.                                                 code[n++]='+';
  161.                                                 break;
  162.                                         case ((char)(-1)):
  163.                                                 code[n++]='-';
  164.                                                 break;
  165.                                         case ((char)0):
  166.                                                 break;
  167.                                         default:
  168.                                                 code[n++]='a';
  169.                                                 code[n++]=c;
  170.                                                 break;
  171.                                 }
  172.                                 c=0;
  173.                                 switch (j) {
  174.                                         case 1:
  175.                                                 code[n++]='>';
  176.                                                 break;
  177.                                         case -1:
  178.                                                 code[n++]='<';
  179.                                                 break;
  180.                                         case 0:
  181.                                                 break;
  182.                                         default:
  183.                                                 code[n++]='p';
  184.                                                 code[n++]=j;
  185.                                                 break;
  186.                                 }
  187.                                 j=0;
  188.                                 if(n-1>=0&&n-2>=0&&code[n-2]=='['&&(code[n-1]=='+'||code[n-2]=='-')) {
  189.                                         code[n-2]='0';
  190.                                         n--;
  191.                                 } else {
  192.                                         code[n++]=code[m];
  193.                                         if(left_flag) {
  194.                                                 for(i=left_offset,x1=x2=x3=0,x4=n+1;i<n;i++) {
  195.                                                         switch(code[i]) {
  196.                                                                 case '+':
  197.                                                                         if(x2==0) {
  198.                                                                                 if(x3) {
  199.                                                                                         i=n;
  200.                                                                                         break;
  201.                                                                                 }
  202.                                                                                 x3=1;
  203.                                                                                 break;
  204.                                                                         }
  205.                                                                         code[x4++] = 0x80|(x2&0x7f);
  206.                                                                         code[x4++] = 1;
  207.                                                                         break;
  208.                                                                 case '-':
  209.                                                                         if(x2==0) {
  210.                                                                                 if(x3) {
  211.                                                                                         i=n;
  212.                                                                                         break;
  213.                                                                                 }
  214.                                                                                 x3=-1;
  215.                                                                                 break;
  216.                                                                         }
  217.                                                                         code[x4++] = 0x80|(x2&0x7f);
  218.                                                                         code[x4++] = -1;
  219.                                                                         break;
  220.                                                                 case 'a':
  221.                                                                         if(x2==0)
  222.                                                                                 i=n;//quit
  223.                                                                         code[x4++] = 0x80|(x2&0x7f);
  224.                                                                         if(code[i+1]==(char)0x80) {
  225.                                                                                 i=n;//quit
  226.                                                                                 break;
  227.                                                                         }
  228.                                                                         code[x4++] = code[i+1];
  229.                                                                         i++;
  230.                                                                         break;
  231.                                                                 case 'p':
  232.                                                                         x2+=(unsigned char)code[i++];
  233.                                                                         if(x2>63||x2<-64) {
  234.                                                                                 i=n;//quit
  235.                                                                         }
  236.                                                                         break;
  237.                                                                 case '<':
  238.                                                                         x2--;
  239.                                                                         if(x2>63||x2<-64) {
  240.                                                                                 i=n;//quit
  241.                                                                         }
  242.                                                                         break;
  243.                                                                 case '>':
  244.                                                                         x2++;
  245.                                                                         if(x2>63||x2<-64) {
  246.                                                                                 i=n;//quit
  247.                                                                         }
  248.                                                                         break;
  249.                                                                 case ']':
  250.                                                                         if(!x3||x2) {
  251.                                                                                 break;/***It can not be optimized******/
  252.                                                                         }
  253.                                                                         if(x3==-1) {
  254.                                                                                 memcpy(&code[left_offset-1],&code[n+1],x4-n-1);
  255.                                                                                 code[x4-n-1+left_offset-1]='0';
  256.                                                                                 n=x4-n-1+left_offset-1+1;
  257.                                                                                 /***Then, i must be greater than n*******/
  258.                                                                         } else {
  259.                                                                                 for(x1=left_offset-1,x2=n+1;x2<x4;x1+=2,x2+=2) {
  260.                                                                                         code[x1]=code[x2];
  261.                                                                                         code[x1+1]=-code[x2+1];
  262.                                                                                 }
  263.                                                                                 code[x4-n-1+left_offset-1]='0';
  264.                                                                                 n=x4-n-1+left_offset-1+1;
  265.                                                                                 /***Then, i must be greater than n*******/
  266.                                                                         }
  267.                                                                         break;
  268.                                                                 /*
  269.                                                                 case '[':
  270.                                                                 case '.':
  271.                                                                 case ',':*/
  272.                                                                 default:
  273.                                                                         i=n;//quit
  274.                                                                         break;
  275.                                                         }/*swtich(code[i])*/
  276.                                                 }/*for(i=left_offset,x1=x2=x3=x4=0;i<n;i++)*/
  277.                                         } else {
  278.                                         }
  279.                                 }
  280.                                 left_flag=0;
  281.                                 break;
  282.                         default:
  283.                                 break;
  284.                 }/*switch(code[m])*/
  285.         }/*for(m=0,n=0,c=0,j=0,left_flag=0;m<len;m++)*/
  286.         len=n;
  287.         setbuf(stdout,NULL);
  288. #if DEBUG>2
  289.         for(i=0;i<len;i++)
  290.                 putchar(code[i]);
  291.         return 0;
  292. #endif
  293.         i=0;
  294.         while(i<len) {
  295.                 switch(code[i]) {
  296.                         case '0':
  297.                                 *p=0;
  298.                                 break;
  299.                         case 'a':
  300.                                 i++;
  301.                                 *p+=(signed char)code[i];
  302.                                 break;
  303.                         case 'p':
  304.                                 i++;
  305.                                 p+=(signed char)code[i];
  306.                                 break;
  307.                         case '+':
  308.                                 (*p)++;
  309.                                 break;
  310.                         case '-':
  311.                                 (*p)--;
  312.                                 break;
  313.                         case '>':
  314.                                 p++;
  315.                                 break;
  316.                         case '<':
  317.                                 p--;
  318.                                 break;
  319.                         case '.':
  320.                                 putchar((int)(*p));
  321.                                 //printf("put:%hd\n",*p);
  322.                                 break;
  323.                         case ',':
  324.                                 *p=getchar();
  325.                                 break;
  326.                         case '[':
  327.                                 if(*p) {
  328.                                         stack[stack_len++]=i;
  329.                                 } else {
  330.                                         for(k=i,j=0;k<len;k++) {
  331.                                                 //if(code[k]=='a'||code[k]=='p'||code[k]&0x80) {
  332.                                                 /**replaced by*****/
  333.                                                 if((unsigned char)code[k]>=(unsigned char)'a') {
  334.                                                         k++;
  335.                                                         continue;
  336.                                                 }
  337.                                                 code[k]=='['&&j++;
  338.                                                 code[k]==']'&&j--;
  339.                                                 if(j==0)break;
  340.                                         }
  341.                                         if(j==0)
  342.                                                 i=k;
  343.                                         else {
  344.                                                 fprintf(stderr,"%s:%d\n",__FILE__,__LINE__);
  345.                                                 return 3;
  346.                                         }
  347.                                 }
  348.                                 break;
  349.                         case ']':
  350.                                 if(*p) {
  351.                                         i=stack[stack_len - 1];
  352.                                         #if DEBUG>0
  353.                                         if(code[i] != '[') {
  354.                                                 fprintf(stderr,"%s:%d\n",__FILE__,__LINE__);
  355.                                                 return 0;
  356.                                         }
  357.                                         #endif
  358.                                 } else {
  359.                                         stack_len--;
  360.                                 }
  361.                                 break;
  362.                         default:
  363.                                 #if DEBUG>1
  364.                                 if(code[i]&0x80)break;
  365.                                 #endif
  366.                                 p[(signed char)(code[i]&(code[i]&0x40?0xff:0x7f))]+=*p*((signed char)code[i+1]);
  367.                                 i++;
  368.                                 break;
  369.                 }
  370.                 i++;
  371.                 //x++;
  372.                 //printf("%d : i=%d\n",x,i);
  373.         }
  374.         return 0;
  375. }

复制代码

[ 本帖最后由 cjaizss 于 2008-6-9 18:03 编辑 ]

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
43 [报告]
发表于 2008-06-09 17:16 |只看该作者
以下为最新的解释器优化39楼的自举编译器所生成的过程代码:

  1. linux-0gt0:/tmp/ch/a2 # gcc -DDEBUG=3 bf.c -o bf
  2. linux-0gt0:/tmp/ch/a2 # ./bf bf2c.bf | od -c
  3. 0000000   a   #   .   a   F   .   a 005   .   a 365   .   a  \t   .   a
  4. 0000020  \t   .   a 357   .   +   .   a 273   .   a 034   .   a   7   .
  5. 0000040   +   .   a 360   .   a 005   .   a 006   .   a 277   .   a   :
  6. 0000060   .   a 326   .   a 314   .   a 031   .   a   F   .   a 005   .
  7. 0000100   a 365   .   a  \t   .   a  \t   .   a 357   .   +   .   a 273
  8. 0000120   .   a 034   .   a   7   .   +   .   a 360   .   a  \b   .   a
  9. 0000140 375   .   a 371   .   a 314   .   a   :   .   a 326   .   a 314
  10. 0000160   .   a 031   .   a   A   .   +   .   +   .   a 003   .   a 005
  11. 0000200   .   a 367   .   a 273   .   a   !   .   a 337   .   a  \v   .
  12. 0000220   .   -   .   a   F   .   a 313   .   a 317   .   a 031   .   a
  13. 0000240   A   .   +   .   +   .   a 003   .   a 005   .   a 367   .   a
  14. 0000260 273   .   a   "   .   a 336   .   a  \n   .   a   F   .   a 315
  15. 0000300   .   a   *   .   a 376   .   a 017   .   a 357   .   a 005   .
  16. 0000320   a 371   .   a 021   .   a 266   .   +   .   a 022   .   a 317
  17. 0000340   .   a 031   .   a   A   .   +   .   +   .   a 003   .   a 005
  18. 0000360   .   a 367   .   a 273   .   a   #   .   a 335   .   a  \r   .
  19. 0000400   .   a 375   .   a   F   .   a 313   .   a 317   .   a 031   .
  20. 0000420   a   A   .   +   .   +   .   a 003   .   a 005   .   a 367   .
  21. 0000440   a 273   .   a   $   .   a 334   .   a   P   .   a 005   .   -
  22. 0000460   .   a 357   .   a 005   .   a 371   .   a 021   .   a 266   .
  23. 0000500   a 002   .   a   F   .   a 271   .   a 022   .   a 317   .   a
  24. 0000520 031   .   a   A   .   +   .   +   .   a 003   .   a 005   .   a
  25. 0000540 367   .   a 273   .   a   %   .   a 333   .   a   P   .   a 275
  26. 0000560   .   .   a 016   .   a 317   .   a 031   .   a   A   .   +   .
  27. 0000600   +   .   a 003   .   a 005   .   a 367   .   a 273   .   a   &
  28. 0000620   .   a 332   .   a   P   .   a 273   .   .   a 020   .   a 317
  29. 0000640   .   a 031   .   a   A   .   +   .   +   .   a 003   .   a 005
  30. 0000660   .   a 367   .   a 273   .   a   '   .   a 331   .   a   W   .
  31. 0000700   a 361   .   +   .   a 003   .   a 371   .   a 303   .   a 002
  32. 0000720   .   a   F   .   a 271   .   a   R   .   a 217   .   a 031   .
  33. 0000740   a   A   .   +   .   +   .   a 003   .   a 005   .   a 367   .
  34. 0000760   a 273   .   a   (   .   a 330   .   a   ]   .   a 215   .   a
  35. 0001000   Y   .   a 005   .   a 371   .   a 021   .   a 256   .   a   R
  36. 0001020   .   a 351   .   a 331   .   a 374   .   .   .   .   a   -   .
  37. 0001040   a 340   .   a   >   .   a 265   .   a   M   .   a 276   .   a
  38. 0001060   .   .   a 005   .   a 006   .   a 254   .   a   M   .   a 364
  39. 0001100   .   a  \b   .   a 005   .   a 272   .   a   N   .   a 371   .
  40. 0001120   a 372   .   a 373   .   a 305   .   a   R   .   a 350   .   a
  41. 0001140 005   .   a 371   .   a 021   .   a 270   .   a   F   .   a 315
  42. 0001160   .   a   5   .   a 271   .   a 006   .   -   .   .   .   .   a
  43. 0001200  \v   .   a 317   .   .   p 002   +   [   ,   +   [   [   -   p
  44. 0001220 002   +   >   +   >   +   >   +   >   +   >   +   >   +   >   +
  45. 0001240   p 367   ]   +   p 002   a 324   [   <   0   +   >   -   ]   <
  46. 0001260   -   [   a   B   .   0   a  \t   .   0   ]   p 002   a 323   [
  47. 0001300   p 376   0   +   p 002   -   ]   p 376   -   [   a   C   .   0
  48. 0001320   a  \t   .   0   ]   p 003   a 322   [   p 375   0   +   p 003
  49. 0001340   -   ]   p 375   -   [   a   D   .   0   a  \t   .   0   ]   p
  50. 0001360 004   a 321   [   p 374   0   +   p 004   -   ]   p 374   -   [
  51. 0001400   a   E   .   0   a  \t   .   0   ]   p 005   a 303   [   p 373
  52. 0001420   0   +   p 005   -   ]   p 373   -   [   a   F   .   0   a  \t
  53. 0001440   .   0   ]   p 006   a 301   [   p 372   0   +   p 006   -   ]
  54. 0001460   p 372   -   [   a   G   .   0   a  \t   .   0   ]   p  \a   a
  55. 0001500 244   [   p 371   0   +   p  \a   -   ]   p 371   -   [   a   H
  56. 0001520   .   0   a  \t   .   0   ]   p  \b   a 242   [   p 370   0   +
  57. 0001540   p  \b   -   ]   p 370   -   [   a   I   .   0   a  \t   .   0
  58. 0001560   ]   ]   <   ]   0   a   r   .   a 363   .   a 017   .   +   .
  59. 0001600   a 375   .   a 374   .   a 262   .   a 020   .   a  \v   .   a
  60. 0001620   B   .   0   a  \n   .
  61. 0001626
复制代码

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
44 [报告]
发表于 2008-06-10 13:04 |只看该作者
又为查找匹配的右方括号建立了"cache",可是这几乎没用,因为在我的解释器里,只有第一次遇到该循环(就是遇到左中括号)的时候因*p==0才不得不找到所匹配的右中括号,以便找到下一个执行点,而这种情况少见。一般时候都是靠右边括号来判断是否跳出循环,而回到该循环体的首部是借助左边括号入栈,所以很快。
但我还是给出了这个"cache",
编译可以定义USE_MATCH_TABLE宏以便加入这个结构,也可以定义cache深度MAX_DEPTH(我并不希望它无限,虽然可以办到,但那样反而不好,不定义则默认为2)
例如
gcc -DUSE_MATCH_TABLE -DMAX_DEPTH=1 bf.c -o bf -O2

  1. /*bf.c*/
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. char s[30000]={0};
  6. char code[100000];
  7. int len = 0;
  8. int  stack[100];
  9. int stack_len=0;
  10. #ifndef DEBUG
  11. #define DEBUG 0
  12. #endif
  13. #ifdef USE_MATCH_TABLE
  14. #if (!defined(MAX_DEPTH)) || MAX_DEPTH<=0
  15. #define MAX_DEPTH 2
  16. #endif
  17. typedef struct _match_des_t{
  18.         int left_offset;
  19.         int right_offset;
  20.         struct _match_des_t* next;
  21. }match_des_t;
  22. typedef struct {
  23.         int depth;
  24.         match_des_t* first;
  25. }  match_table_t;
  26. match_table_t match_table[256]={{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0},{.depth=0}
  27. };
  28. static inline int search_match(int left)
  29. {
  30.         int i;
  31.         match_des_t* pmatch_des;
  32.         match_table_t* pmatch_table=&match_table[left&0xff];
  33.         if(pmatch_table->depth==0)
  34.                 return 0;
  35.         for(i=0,pmatch_des=pmatch_table->first;i<pmatch_table->depth;i++) {
  36.                 if(pmatch_des->left_offset==left)
  37.                         return pmatch_des->right_offset;
  38.                 pmatch_des=pmatch_des->next;
  39.         }
  40.         return 0;
  41. }
  42. static inline void add_match(int left,int right)
  43. {
  44.         match_des_t* pmatch_des;
  45.         match_table_t* pmatch_table=&match_table[left&0xff];
  46.         switch(pmatch_table->depth) {
  47.                 case 0:
  48.                         pmatch_table->first=malloc(sizeof(match_des_t));
  49.                         if(pmatch_table->first==NULL) {
  50.                                 fprintf(stderr,"%s:%d\n",__FILE__,__LINE__);
  51.                                 exit(6);
  52.                         }
  53.                         pmatch_table->first->left_offset=left;
  54.                         pmatch_table->first->right_offset=right;
  55.                         pmatch_table->depth=1;
  56.                         break;
  57.                 case MAX_DEPTH:
  58.                         pmatch_table->first->left_offset=left;
  59.                         pmatch_table->first->right_offset=right;
  60.                         break;
  61.                 default:
  62.                         pmatch_des = pmatch_table->first;
  63.                         pmatch_table->first=malloc(sizeof(match_des_t));
  64.                         if(pmatch_table->first==NULL) {
  65.                                 fprintf(stderr,"%s:%d\n",__FILE__,__LINE__);
  66.                                 exit(6);
  67.                         }
  68.                         pmatch_table->first->left_offset=left;
  69.                         pmatch_table->first->right_offset=right;
  70.                         pmatch_table->first->next=pmatch_des;
  71.                         pmatch_table->depth++;
  72.                         break;
  73.         }
  74. }
  75. #endif
  76. int main(int argc,char**argv)
  77. {
  78.         char c;
  79.         int i,j,k,left_flag,left_offset,x=0;
  80.         int x1,x2,x3,x4;
  81.         int m,n;
  82.         FILE* f;
  83.         char* p=s+10000;
  84.         if(argc==2) {
  85.                 f=fopen(argv[1],"r");
  86.                 if(f==NULL) {
  87.                         perror("fopen");
  88.                                 return 1;
  89.                 }
  90.                 len=fread(code,1,sizeof(code),f);
  91.                 if(len==0&&len==sizeof(code)) {
  92.                         return 4;
  93.                 }
  94.         } else return 2;

  95.         /*optimization*/
  96.         /*We can prove that n is never greater than m.So we can use the same memory*/
  97.         for(m=0,n=0,c=0,j=0,left_flag=0;m<len;m++) {
  98.                 switch(code[m]) {
  99.                         case '+':
  100.                                 switch (j) {
  101.                                         case 1:
  102.                                                 code[n++]='>';
  103.                                                 break;
  104.                                         case -1:
  105.                                                 code[n++]='<';
  106.                                                 break;
  107.                                         case 0:
  108.                                                 break;
  109.                                         default:
  110.                                                 code[n++]='p';
  111.                                                 code[n++]=j;
  112.                                                 break;
  113.                                 }
  114.                                 j=0;
  115.                                 c++;
  116.                                 break;
  117.                         case '-':
  118.                                 switch (j) {
  119.                                         case 1:
  120.                                                 code[n++]='>';
  121.                                                 break;
  122.                                         case -1:
  123.                                                 code[n++]='<';
  124.                                                 break;
  125.                                         case 0:
  126.                                                 break;
  127.                                         default:
  128.                                                 code[n++]='p';
  129.                                                 code[n++]=j;
  130.                                                 break;
  131.                                 }
  132.                                 j=0;
  133.                                 c--;
  134.                                 break;
  135.                         case '>':
  136.                                 switch (c) {
  137.                                         case ((char)1):
  138.                                                 code[n++]='+';
  139.                                                 break;
  140.                                         case ((char)(-1)):
  141.                                                 code[n++]='-';
  142.                                                 break;
  143.                                         case ((char)0):
  144.                                                 break;
  145.                                         default:
  146.                                                 code[n++]='a';
  147.                                                 code[n++]=c;
  148.                                                 break;
  149.                                 }
  150.                                 c=0;
  151.                                 j++;
  152.                                 if(j==0x7f) {
  153.                                         code[n++]='p';
  154.                                         code[n++]=0x7f;
  155.                                         j=0;
  156.                                 }
  157.                                 break;
  158.                         case '<':
  159.                                 switch (c) {
  160.                                         case ((char)1):
  161.                                                 code[n++]='+';
  162.                                                 break;
  163.                                         case ((char)(-1)):
  164.                                                 code[n++]='-';
  165.                                                 break;
  166.                                         case ((char)0):
  167.                                                 break;
  168.                                         default:
  169.                                                 code[n++]='a';
  170.                                                 code[n++]=c;
  171.                                                 break;
  172.                                 }
  173.                                 c=0;
  174.                                 j--;
  175.                                 if(j==-128) {
  176.                                         code[n++]='p';
  177.                                         code[n++]=-128;
  178.                                         j=0;
  179.                                 }
  180.                                 break;
  181.                         case '.':
  182.                         case ',':
  183.                         case '[':
  184.                                 switch (c) {
  185.                                         case ((char)1):
  186.                                                 code[n++]='+';
  187.                                                 break;
  188.                                         case ((char)(-1)):
  189.                                                 code[n++]='-';
  190.                                                 break;
  191.                                         case ((char)0):
  192.                                                 break;
  193.                                         default:
  194.                                                 code[n++]='a';
  195.                                                 code[n++]=c;
  196.                                                 break;
  197.                                 }
  198.                                 c=0;
  199.                                 switch (j) {
  200.                                         case 1:
  201.                                                 code[n++]='>';
  202.                                                 break;
  203.                                         case -1:
  204.                                                 code[n++]='<';
  205.                                                 break;
  206.                                         case 0:
  207.                                                 break;
  208.                                         default:
  209.                                                 code[n++]='p';
  210.                                                 code[n++]=j;
  211.                                                 break;
  212.                                 }
  213.                                 j=0;
  214.                                 code[n++]=code[m];
  215.                                 if(code[m]=='[') {
  216.                                         left_flag=1;
  217.                                         left_offset=n;
  218.                                 }
  219.                                 break;
  220.                         case ']':
  221.                                 switch (c) {
  222.                                         case ((char)1):
  223.                                                 code[n++]='+';
  224.                                                 break;
  225.                                         case ((char)(-1)):
  226.                                                 code[n++]='-';
  227.                                                 break;
  228.                                         case ((char)0):
  229.                                                 break;
  230.                                         default:
  231.                                                 code[n++]='a';
  232.                                                 code[n++]=c;
  233.                                                 break;
  234.                                 }
  235.                                 c=0;
  236.                                 switch (j) {
  237.                                         case 1:
  238.                                                 code[n++]='>';
  239.                                                 break;
  240.                                         case -1:
  241.                                                 code[n++]='<';
  242.                                                 break;
  243.                                         case 0:
  244.                                                 break;
  245.                                         default:
  246.                                                 code[n++]='p';
  247.                                                 code[n++]=j;
  248.                                                 break;
  249.                                 }
  250.                                 j=0;
  251.                                 if(n-1>=0&&n-2>=0&&code[n-2]=='['&&(code[n-1]=='+'||code[n-2]=='-')) {
  252.                                         code[n-2]='0';
  253.                                         n--;
  254.                                 } else {
  255.                                         code[n++]=code[m];
  256.                                         if(left_flag) {
  257.                                                 for(i=left_offset,x1=x2=x3=0,x4=n+1;i<n;i++) {
  258.                                                         switch(code[i]) {
  259.                                                                 case '+':
  260.                                                                         if(x2==0) {
  261.                                                                                 if(x3) {
  262.                                                                                         i=n;
  263.                                                                                         break;
  264.                                                                                 }
  265.                                                                                 x3=1;
  266.                                                                                 break;
  267.                                                                         }
  268.                                                                         code[x4++] = 0x80|(x2&0x7f);
  269.                                                                         code[x4++] = 1;
  270.                                                                         break;
  271.                                                                 case '-':
  272.                                                                         if(x2==0) {
  273.                                                                                 if(x3) {
  274.                                                                                         i=n;
  275.                                                                                         break;
  276.                                                                                 }
  277.                                                                                 x3=-1;
  278.                                                                                 break;
  279.                                                                         }
  280.                                                                         code[x4++] = 0x80|(x2&0x7f);
  281.                                                                         code[x4++] = -1;
  282.                                                                         break;
  283.                                                                 case 'a':
  284.                                                                         if(x2==0)
  285.                                                                                 i=n;//quit
  286.                                                                         code[x4++] = 0x80|(x2&0x7f);
  287.                                                                         if(code[i+1]==(char)0x80) {
  288.                                                                                 i=n;//quit
  289.                                                                                 break;
  290.                                                                         }
  291.                                                                         code[x4++] = code[i+1];
  292.                                                                         i++;
  293.                                                                         break;
  294.                                                                 case 'p':
  295.                                                                         x2+=(unsigned char)code[i++];
  296.                                                                         if(x2>63||x2<-64) {
  297.                                                                                 i=n;//quit
  298.                                                                         }
  299.                                                                         break;
  300.                                                                 case '<':
  301.                                                                         x2--;
  302.                                                                         if(x2>63||x2<-64) {
  303.                                                                                 i=n;//quit
  304.                                                                         }
  305.                                                                         break;
  306.                                                                 case '>':
  307.                                                                         x2++;
  308.                                                                         if(x2>63||x2<-64) {
  309.                                                                                 i=n;//quit
  310.                                                                         }
  311.                                                                         break;
  312.                                                                 case ']':
  313.                                                                         if(!x3||x2) {
  314.                                                                                 break;/***It can not be optimized******/
  315.                                                                         }
  316.                                                                         if(x3==-1) {
  317.                                                                                 memcpy(&code[left_offset-1],&code[n+1],x4-n-1);
  318.                                                                                 code[x4-n-1+left_offset-1]='0';
  319.                                                                                 n=x4-n-1+left_offset-1+1;
  320.                                                                                 /***Then, i must be greater than n*******/
  321.                                                                         } else {
  322.                                                                                 for(x1=left_offset-1,x2=n+1;x2<x4;x1+=2,x2+=2) {
  323.                                                                                         code[x1]=code[x2];
  324.                                                                                         code[x1+1]=-code[x2+1];
  325.                                                                                 }
  326.                                                                                 code[x4-n-1+left_offset-1]='0';
  327.                                                                                 n=x4-n-1+left_offset-1+1;
  328.                                                                                 /***Then, i must be greater than n*******/
  329.                                                                         }
  330.                                                                         break;
  331.                                                                 /*
  332.                                                                 case '[':
  333.                                                                 case '.':
  334.                                                                 case ',':*/
  335.                                                                 default:
  336.                                                                         i=n;//quit
  337.                                                                         break;
  338.                                                         }/*swtich(code[i])*/
  339.                                                 }/*for(i=left_offset,x1=x2=x3=x4=0;i<n;i++)*/
  340.                                         } else {
  341.                                         }
  342.                                 }
  343.                                 left_flag=0;
  344.                                 break;
  345.                         default:
  346.                                 break;
  347.                 }/*switch(code[m])*/
  348.         }/*for(m=0,n=0,c=0,j=0,left_flag=0;m<len;m++)*/
  349.         len=n;
  350.         setbuf(stdout,NULL);
  351. #if DEBUG>2
  352.         for(i=0;i<len;i++)
  353.                 putchar(code[i]);
  354.         return 0;
  355. #endif
  356.         i=0;
  357.         while(i<len) {
  358.                 switch(code[i]) {
  359.                         case '0':
  360.                                 *p=0;
  361.                                 break;
  362.                         case 'a':
  363.                                 i++;
  364.                                 *p+=(signed char)code[i];
  365.                                 break;
  366.                         case 'p':
  367.                                 i++;
  368.                                 p+=(signed char)code[i];
  369.                                 break;
  370.                         case '+':
  371.                                 (*p)++;
  372.                                 break;
  373.                         case '-':
  374.                                 (*p)--;
  375.                                 break;
  376.                         case '>':
  377.                                 p++;
  378.                                 break;
  379.                         case '<':
  380.                                 p--;
  381.                                 break;
  382.                         case '.':
  383.                                 putchar((int)(*p));
  384.                                 //printf("put:%hd\n",*p);
  385.                                 break;
  386.                         case ',':
  387.                                 *p=getchar();
  388.                                 break;
  389.                         case '[':
  390.                                 if(*p) {
  391.                                         stack[stack_len++]=i;
  392.                                 } else {
  393.                                         #ifdef USE_MATCH_TABLE
  394.                                         if(x1=search_match(i)) {
  395.                                                 i=x1;
  396.                                                 break;
  397.                                         }
  398.                                         #endif
  399.                                         for(k=i,j=0;k<len;k++) {
  400.                                                 //if(code[k]=='a'||code[k]=='p'||code[k]&0x80) {
  401.                                                 /**replaced by*****/
  402.                                                 if((unsigned char)code[k]>=(unsigned char)'a') {
  403.                                                         k++;
  404.                                                         continue;
  405.                                                 }
  406.                                                 code[k]=='['&&j++;
  407.                                                 code[k]==']'&&j--;
  408.                                                 if(j==0)break;
  409.                                         }
  410.                                         if(j==0) {
  411.                                                 #ifdef USE_MATCH_TABLE
  412.                                                 add_match(i,k);
  413.                                                 #endif
  414.                                                 i=k;
  415.                                         }
  416.                                         else {
  417.                                                 fprintf(stderr,"%s:%d\n",__FILE__,__LINE__);
  418.                                                 return 3;
  419.                                         }
  420.                                 }
  421.                                 break;
  422.                         case ']':
  423.                                 if(*p) {
  424.                                         i=stack[stack_len - 1];
  425.                                         #if DEBUG>0
  426.                                         if(code[i] != '[') {
  427.                                                 fprintf(stderr,"%s:%d\n",__FILE__,__LINE__);
  428.                                                 return 0;
  429.                                         }
  430.                                         #endif
  431.                                 } else {
  432.                                         stack_len--;
  433.                                 }
  434.                                 break;
  435.                         default:
  436.                                 #if DEBUG>1
  437.                                 if(code[i]&0x80)break;
  438.                                 #endif
  439.                                 p[(signed char)(code[i]&(code[i]&0x40?0xff:0x7f))]+=*p*((signed char)code[i+1]);
  440.                                 i++;
  441.                                 break;
  442.                 }
  443.                 i++;
  444.                 //x++;
  445.                 //printf("%d : i=%d\n",x,i);
  446.         }
  447.         return 0;
  448. }
复制代码

[ 本帖最后由 cjaizss 于 2008-6-10 13:13 编辑 ]

论坛徽章:
0
45 [报告]
发表于 2008-06-11 08:52 |只看该作者
强强.
楼主好样的

论坛徽章:
0
46 [报告]
发表于 2008-06-13 16:52 |只看该作者
[   如果指针指向的这个字节,则进入循环节
]   回到匹配的 ...


问个弱弱的问题,[,]操作没搞懂什么意思?呵呵

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
47 [报告]
发表于 2008-06-13 17:16 |只看该作者

回复 #46 run_xiao2000 的帖子

[ /*在这里判断指针当前所指字节是否为0,如果不为0,则进入循环节,否则跳到A*/
..............循环节
]
.............../*A*/

论坛徽章:
0
48 [报告]
发表于 2008-06-16 09:55 |只看该作者
++++++++++[>++++++++++[>+<-]<-]>>-.+++++++.---------.++++++++.

果然够brainfuck,看了十分钟,拿笔在草稿纸上画了画才搞懂,这个嵌套的循环!

论坛徽章:
0
49 [报告]
发表于 2008-06-16 10:52 |只看该作者
for(k=i,j=0;k<len;k++) {
                                                code[k]=='['&&j++;
                                                code[k]==']'&&j--;
                                                if(j==0)break;
                                        }

这段看了半天也看不懂,只知道是找"["匹配的"]"

论坛徽章:
0
50 [报告]
发表于 2008-06-16 23:14 |只看该作者

回复 #10 run_xiao2000 的帖子

不是一般的强
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP