C语言解释器-1(源起)

来源:互联网 发布:git mac客户端下载 编辑:程序博客网 时间:2024/05/22 11:55

在维护新建对象的时候,利用对象休眠的闲暇,写了个习作。

咸盐少许。

通常,编译原理或编译技术都会建议使用yacc或lex来实现语言、公式的解释器或编译器。鉴于实现一个语言编译器或解释器的困难,大多数猿类都会使用这类工具。不过,本文穿越到了工具出现以前的时代,同时又开启了金手指:带了c#、Flex和Bison。既是习作,故使用c#手工打造了一个简单的c语言解释器,而并未使用Flex和Bison。遂有此文。

这个解释器,斗胆命名为SharpC。它实现了c语言的如下部分功能:

 

1. 基本的类型:char, short, int, float。

对于unsigned, signed的区分不明显,不支持const关键字。

2. 支持函数。

包括不定参数函数,支持递归,支持嵌套定义。

3. 支持几乎所有表达式。

不支持?:三元操作符,逗号操作符未测试。

4. 支持指针。

这意味着支持内存操作,也意味支持字符串。

5. 支持除goto外的所有控制结构。

包括:if/else, for, while, do/while, switch/case/default/break, return, continue.

6. 其它。

内建了几个基本的辅助函数:malloc, free, print, vararg, varlen, input, prompt, confirm。

7.所有其他c语言功能皆不支持。

诸如#符号,typedef, struct等。

 

我们先看看最终结果,对于这样的一个c源代码:

/** This is a multi-line comment.**/// This is a single line comment.char globalChar = 'A';short globalShort = 333;int globalInt = 1;// Global scope declarationfloat globalFloat = 1.2345;char* ptr = "abcdefg" "hijklmn";void funcFwdDecl();// forwarding declarationvoid funcWithoutArg(){// Variable declaration and initializationint x = 1;// Empty statement;{ // anonymous blockint y = 3;} // end of block// Test bare expression1 < 2;1 <= 2;2 > 1;2 >= 1;// Test commentsx += 1 // This is a comment;// Test assignx = 10 - 3;x += 1;x -= 1;x *= 1;x /= 1;x %= 1;x &= 1;x |= 1;x ^= 1;x <<= 1;x >>= 1;// Test pre/post operatorx = x++;x = x--;x = ++x;x = --x;// Control flow// If with statementif (x <= 1)x++;// If/elseif (x <= 2)x--;elsex++;// if/else matching 1if (x <= 3)--x;elseif (x <= 4)x++;if (x <= 5)x += 1;elseif (x <= 6)x += 2;elsex += 3;// If with blockif (x <= 7){x /= 10;}else{x *= 10;}if (1 < 2)x = 0;elseif (3 < 4)  x = 1;else   x = 2; // for loop// Commonly for loop with single statemntfor(int i = 0; i < 100; i++)x++;// for loop with blockfor(int i = 0; i < 100; i++){x++;x--;}// for loop with long initializerint i = 0;for(i = 1, x = 0; i < 100; i++){x--;x++;}// for loop with long iteratorfor(int l = 0; l < 100; l++, x--, x++, x--)x--;// for loop with break & continuefor(int l = 0; l < 100; l++){if (l > 100)break;elseif (l > 50)continue;}// while with single statementwhile(1 < 2) x++;// while with blockwhile(x < 3){x++;x;}// while with break & continuewhile( x < 10){if (x > 5)break;elsecontinue;x++;}// do/whiledo{x++;x--;--x;++x;}// commentswhile(1);switch(x){case '0': break;case 'a': break;case '\t': break;case 1:case 2:case 3: break;case 5:{x--;x++;x *= 10;}break;case 6:switch(x){case 1:case 2:case 3: break;case 4:{}break;default: break;}break;default: x++; break;}return 1; // This will cause an error.} // end of funcvoid funcWithArg(int var1){return;}void funcWithManyArg(int var1, int var2, int var3){do{var1++;var2--;if (var1 + var2 <= var3)return ;}while(1 > 2);while(var2 > var1){int ddd = 100;continue;}int innerFunc(int var4, int var5){var4 = var1 + var2 + var3 / var5;}innerFunc(1, 2);}int funcInt(){return ; // This will cause an error.}int funcVar(...){funcVar(1, 2, 3);return 0;}


 

SharpC的分析结果如下:

SharpC.Grammar.Variable:Line: 7 Pos: 7 "globalChar"SharpC.Grammar.Statement:Line: 7 Pos: 7 "globalChar = 'A'"SharpC.Grammar.Variable:Line: 8 Pos: 8 "globalShort"SharpC.Grammar.Statement:Line: 8 Pos: 8 "globalShort = 333"SharpC.Grammar.Variable:Line: 9 Pos: 6 "globalInt"SharpC.Grammar.Statement:Line: 9 Pos: 6 "globalInt = 1"SharpC.Grammar.Variable:Line: 10 Pos: 8 "globalFloat"SharpC.Grammar.Statement:Line: 10 Pos: 8 "globalFloat = 1.2345"SharpC.Grammar.Variable:Line: 12 Pos: 8 "ptr"SharpC.Grammar.Statement:Line: 12 Pos: 8 "ptr = "abcdefg" "hijklmn""SharpC.Grammar.Variable:Line: 19 Pos: 7 "x"SharpC.Grammar.Statement:Line: 19 Pos: 7 "x = 1"SharpC.Grammar.Statement:Line: 22 Pos: 3 ";"SharpC.Grammar.Variable:Line: 25 Pos: 7 " "SharpC.Grammar.Statement:Line: 25 Pos: 7 " y = "SharpC.Grammar.Statement:Line: 29 Pos: 3 "1 < 2;"SharpC.Grammar.Statement:Line: 30 Pos: 3 "1 <= 2;"SharpC.Grammar.Statement:Line: 31 Pos: 3 "2 > 1;"SharpC.Grammar.Statement:Line: 32 Pos: 3 "2 >= 1;"SharpC.Grammar.Statement:Line: 34 Pos: 3 "x += 1 // This is a comment;"SharpC.Grammar.Statement:Line: 38 Pos: 3 "x = 10 - 3;"SharpC.Grammar.Statement:Line: 39 Pos: 3 "x += 1;"SharpC.Grammar.Statement:Line: 40 Pos: 3 "x -= 1;"SharpC.Grammar.Statement:Line: 41 Pos: 3 "x *= 1;"SharpC.Grammar.Statement:Line: 42 Pos: 3 "x /= 1;"SharpC.Grammar.Statement:Line: 43 Pos: 3 "x %= 1;"SharpC.Grammar.Statement:Line: 44 Pos: 3 "x &= 1;"SharpC.Grammar.Statement:Line: 45 Pos: 3 "x |= 1;"SharpC.Grammar.Statement:Line: 46 Pos: 3 "x ^= 1;"SharpC.Grammar.Statement:Line: 47 Pos: 3 "x <<= 1;"SharpC.Grammar.Statement:Line: 48 Pos: 3 "x >>= 1;"SharpC.Grammar.Statement:Line: 51 Pos: 3 "x = x++;"SharpC.Grammar.Statement:Line: 52 Pos: 3 "x = x--;"SharpC.Grammar.Statement:Line: 53 Pos: 3 "x = ++x;"SharpC.Grammar.Statement:Line: 54 Pos: 3 "x = --x;"SharpC.Grammar.Statement:Line: 59 Pos: 4 "x++;"SharpC.Grammar.ControlFlow.IfThen:Line: 58 Pos: 3 "if (x <= 1)"SharpC.Grammar.Statement:Line: 63 Pos: 4 "x--;"SharpC.Grammar.ControlFlow.IfThen:Line: 62 Pos: 3 "if (x <= 2)"SharpC.Grammar.Statement:Line: 65 Pos: 4 "x++;"SharpC.Grammar.ControlFlow.IfThen:Line: 62 Pos: 3 "if (x <= 2)x--;else"SharpC.Grammar.Statement:Line: 69 Pos: 4 "--x;"SharpC.Grammar.ControlFlow.IfThen:Line: 68 Pos: 3 "if (x <= 3)"SharpC.Grammar.Statement:Line: 72 Pos: 5 "x++;"SharpC.Grammar.ControlFlow.IfThen:Line: 71 Pos: 4 "if (x <= 4)"SharpC.Grammar.ControlFlow.IfThen:Line: 68 Pos: 3 "if (x <= 3)--x;else"SharpC.Grammar.Statement:Line: 75 Pos: 4 "x += 1;"SharpC.Grammar.ControlFlow.IfThen:Line: 74 Pos: 3 "if (x <= 5)"SharpC.Grammar.Statement:Line: 78 Pos: 5 "x += 2;"SharpC.Grammar.ControlFlow.IfThen:Line: 77 Pos: 4 "if (x <= 6)"SharpC.Grammar.ControlFlow.IfThen:Line: 74 Pos: 3 "if (x <= 5)x += 1;else"SharpC.Grammar.Statement:Line: 80 Pos: 5 "x += 3;"SharpC.Grammar.ControlFlow.IfThen:Line: 74 Pos: 3 "if (x <= 5)x += 1;elseif (x <= 6)x += 2;else"SharpC.Grammar.Statement:Line: 85 Pos: 4 "x /= 10;"SharpC.Grammar.ControlFlow.IfThen:Line: 83 Pos: 3 "if (x <= 7){x /= 10;}"SharpC.Grammar.Statement:Line: 89 Pos: 4 "x *= 10;"SharpC.Grammar.ControlFlow.IfThen:Line: 83 Pos: 3 "if (x <= 7){x /= 10;}else{x *= 10;}"SharpC.Grammar.Statement:Line: 93 Pos: 4 "x = 0;"SharpC.Grammar.ControlFlow.IfThen:Line: 92 Pos: 3 "if (1 < 2)"SharpC.Grammar.Statement:Line: 96 Pos: 6 "x = 1;"SharpC.Grammar.ControlFlow.IfThen:Line: 95 Pos: 4 "if (3 < 4)  "SharpC.Grammar.ControlFlow.IfThen:Line: 92 Pos: 3 "if (1 < 2)x = 0;else"SharpC.Grammar.Statement:Line: 98 Pos: 7 "x = 2;"SharpC.Grammar.ControlFlow.IfThen:Line: 92 Pos: 3 "if (1 < 2)x = 0;elseif (3 < 4)  x = 1;else   "SharpC.Grammar.Variable:Line: 102 Pos: 11 "i"SharpC.Grammar.Statement:Line: 102 Pos: 11 "i = 0"SharpC.Grammar.Statement:Line: 103 Pos: 4 "x++;"SharpC.Grammar.ControlFlow.ForLoop:Line: 102 Pos: 3 "for(int i = 0; i < 100; i++)"SharpC.Grammar.Variable:Line: 106 Pos: 11 "i"SharpC.Grammar.Statement:Line: 106 Pos: 11 "i = 0"SharpC.Grammar.Statement:Line: 108 Pos: 4 "x++;"SharpC.Grammar.Statement:Line: 109 Pos: 4 "x--;"SharpC.Grammar.ControlFlow.ForLoop:Line: 106 Pos: 3 "for(int i = 0; i < 100; i++){"SharpC.Grammar.Variable:Line: 113 Pos: 7 "i"SharpC.Grammar.Statement:Line: 113 Pos: 7 "i = 0"SharpC.Grammar.Statement:Line: 114 Pos: 7 "i = 1, x = 0;"SharpC.Grammar.Statement:Line: 116 Pos: 4 "x--;"SharpC.Grammar.Statement:Line: 117 Pos: 4 "x++;"SharpC.Grammar.ControlFlow.ForLoop:Line: 114 Pos: 3 "for(i = 1, x = 0; i < 100; i++){"SharpC.Grammar.Variable:Line: 121 Pos: 11 "l"SharpC.Grammar.Statement:Line: 121 Pos: 11 "l = 0"SharpC.Grammar.Statement:Line: 122 Pos: 4 "x--;"SharpC.Grammar.ControlFlow.ForLoop:Line: 121 Pos: 3 "for(int l = 0; l < 100; l++, x--, x++, x--)"SharpC.Grammar.Variable:Line: 125 Pos: 11 "l"SharpC.Grammar.Statement:Line: 125 Pos: 11 "l = 0"SharpC.Grammar.ControlFlow.Break:Line: 128 Pos: 5 "break;"SharpC.Grammar.ControlFlow.IfThen:Line: 127 Pos: 4 "if (l > 100)"SharpC.Grammar.ControlFlow.Continue:Line: 131 Pos: 6 "continue"SharpC.Grammar.ControlFlow.IfThen:Line: 130 Pos: 5 "if (l > 50)"SharpC.Grammar.ControlFlow.IfThen:Line: 127 Pos: 4 "if (l > 100)break;else"SharpC.Grammar.ControlFlow.ForLoop:Line: 125 Pos: 3 "for(int l = 0; l < 100; l++){"SharpC.Grammar.Statement:Line: 135 Pos: 16 "x++;"SharpC.Grammar.ControlFlow.WhileLoop:Line: 135 Pos: 3 "while(1 < 2) "SharpC.Grammar.ControlFlow.WhileLoop:Line: 135 Pos: 3 "while(1 < 2) "SharpC.Grammar.Statement:Line: 140 Pos: 4 "x++;"SharpC.Grammar.Statement:Line: 141 Pos: 4 "x;"SharpC.Grammar.ControlFlow.WhileLoop:Line: 138 Pos: 3 "while(x < 3){"SharpC.Grammar.ControlFlow.WhileLoop:Line: 138 Pos: 3 "while(x < 3){"SharpC.Grammar.ControlFlow.Break:Line: 148 Pos: 5 "break;"SharpC.Grammar.ControlFlow.IfThen:Line: 147 Pos: 4 "if (x > 5)"SharpC.Grammar.ControlFlow.Continue:Line: 150 Pos: 5 "continue"SharpC.Grammar.ControlFlow.IfThen:Line: 147 Pos: 4 "if (x > 5)break;else"SharpC.Grammar.Statement:Line: 152 Pos: 4 "x++;"SharpC.Grammar.ControlFlow.WhileLoop:Line: 145 Pos: 3 "while( x < 10){"SharpC.Grammar.ControlFlow.WhileLoop:Line: 145 Pos: 3 "while( x < 10){"SharpC.Grammar.Statement:Line: 157 Pos: 4 "x++;"SharpC.Grammar.Statement:Line: 158 Pos: 4 "x--;"SharpC.Grammar.Statement:Line: 159 Pos: 4 "--x;"SharpC.Grammar.Statement:Line: 160 Pos: 4 "++x;"SharpC.Grammar.ControlFlow.DoWhileLoop:Line: 156 Pos: 3 "do{"SharpC.Grammar.ControlFlow.Case:Line: 166 Pos: 4 "case '0':"SharpC.Grammar.ControlFlow.Break:Line: 166 Pos: 14 "break;"SharpC.Grammar.ControlFlow.Case:Line: 167 Pos: 4 "case 'a':"SharpC.Grammar.ControlFlow.Break:Line: 167 Pos: 14 "break;"SharpC.Grammar.ControlFlow.Case:Line: 168 Pos: 4 "case '\t':"SharpC.Grammar.ControlFlow.Break:Line: 168 Pos: 15 "break;"SharpC.Grammar.ControlFlow.Case:Line: 169 Pos: 4 "case 1:"SharpC.Grammar.ControlFlow.Case:Line: 170 Pos: 4 "case 2:"SharpC.Grammar.ControlFlow.Case:Line: 171 Pos: 4 "case 3:"SharpC.Grammar.ControlFlow.Break:Line: 171 Pos: 12 "break;"SharpC.Grammar.ControlFlow.Case:Line: 172 Pos: 4 "case 5:"SharpC.Grammar.Statement:Line: 174 Pos: 5 "x--"SharpC.Grammar.Statement:Line: 175 Pos: 5 "x++"SharpC.Grammar.Statement:Line: 176 Pos: 5 "x *= 10"SharpC.Grammar.ControlFlow.Break:Line: 178 Pos: 5 "break;"SharpC.Grammar.ControlFlow.Case:Line: 179 Pos: 4 "case 6:"SharpC.Grammar.ControlFlow.Case:Line: 182 Pos: 6 "case 1:"SharpC.Grammar.ControlFlow.Case:Line: 183 Pos: 6 "case 2:"SharpC.Grammar.ControlFlow.Case:Line: 184 Pos: 6 "case 3:"SharpC.Grammar.ControlFlow.Break:Line: 184 Pos: 14 "break;"SharpC.Grammar.ControlFlow.Case:Line: 185 Pos: 6 "case 4:"SharpC.Grammar.ControlFlow.Break:Line: 188 Pos: 7 "break;"SharpC.Grammar.ControlFlow.Break:Line: 189 Pos: 15 "break;"SharpC.Grammar.ControlFlow.Switch:Line: 180 Pos: 5 "switch(x){case 1:case 2:case 3: break;case 4:{}break;default: break;}"SharpC.Grammar.ControlFlow.Break:Line: 191 Pos: 5 "break;"SharpC.Grammar.Statement:Line: 192 Pos: 13 "x++;"SharpC.Grammar.ControlFlow.Break:Line: 192 Pos: 18 "break;"SharpC.Grammar.ControlFlow.Switch:Line: 164 Pos: 3 "switch(x){case '0': break;case 'a': break;case '\t': break;case 1:case 2:case 3: break;case 5:{x--;x++;x *= 10;}break;case 6:switch(x){case 1:case 2:case 3: break;case 4:{}break;default: break;}break;default: x++; break;}"1>>Syntax error: Line: 196 Pos: 3 "return 1;": return value type does not match the function type.SharpC.Grammar.ControlFlow.Return:Line: 196 Pos: 3 "return 1;"SharpC.Grammar.ControlFlow.Return:Line: 201 Pos: 3 "return;"SharpC.Grammar.Statement:Line: 207 Pos: 4 "var1++;"SharpC.Grammar.Statement:Line: 208 Pos: 4 "var2--;"SharpC.Grammar.ControlFlow.Return:Line: 211 Pos: 5 "return ;"SharpC.Grammar.ControlFlow.IfThen:Line: 210 Pos: 4 "if (var1 + var2 <= var3)"SharpC.Grammar.ControlFlow.DoWhileLoop:Line: 206 Pos: 3 "do{"2>>Syntax error: Line: 214 Pos: 3 "while": ';' is expected.SharpC.Grammar.ControlFlow.DoWhileLoop:Line: 206 Pos: 3 "do{var1++;var2--;if (var1 + var2 <= var3)return ;}while(1 > 2)"SharpC.Grammar.Statement:Line: 223 Pos: 4 "var4 = var1 + var2 + var3 / var5;"SharpC.Grammar.Statement:Line: 227 Pos: 3 "innerFunc(1, 2);"3>>Syntax error: Line: 232 Pos: 3 "return ;": return value type does not match the function type.SharpC.Grammar.ControlFlow.Return:Line: 232 Pos: 3 "return ;"SharpC.Grammar.Statement:Line: 237 Pos: 3 "funcVar(1, 2, 3);"SharpC.Grammar.ControlFlow.Return:Line: 238 Pos: 3 "return 0;"Time consumption: 0.5753843 sec


打印分析生成的语法树以还原代码:

char * $var_char_ptr_6$ (const) refers to $var_char_ptr_6$ Data length:15void * malloc(int size)void free(void * ptr)int input(char * title, char * message, char * defValue, char * format, char * errMsg, char * result)int confirm(char * title, char * msg)void prompt(char * title, char * msg)void print(...)char vararg(int argIdx)int varlen()char globalChar globalChar = 65short globalShort globalShort = 333int globalInt globalInt = 1float globalFloat globalFloat = 1.2345char * ptr ptr = $var_char_ptr_6$void funcFwdDecl()void funcWithoutArg(){int x x = 1{int y y = 3}1 < 21 <= 22 > 12 >= 1x += 1x = 10 - 3x += 1x += 1x *= 1x /= 1x %= 1x &= 1x |= 1x ^= 1x <<= 1x >>= 1x = x++x = x--x = ++xx = --xif(x <= 1){x++}if(x <= 2){x--}else{x++}if(x <= 3){--x}else{if(x <= 4){x++}}if(x <= 5){x += 1}else{x += 3}if(x <= 7){x /= 10}else{x *= 10}if(1 < 2){x = 0}else{x = 2}for(Initalizer: int i i = 0Condition: i < 100Iterator: i++{x++}for(Initalizer: int i i = 0Condition: i < 100Iterator: i++{x++x--}int i i = 0for(Initalizer: i = 1Condition: i < 100Iterator: i++{x--x++}for(Initalizer: int l l = 0Condition: l < 100Iterator: l++{x--}for(Initalizer: int l l = 0Condition: l < 100Iterator: l++{if(l > 100){break;}else{if(l > 50){continue;}}}while(1 < 2){x++}while(x < 3){x++x}while(x < 10){if(x > 5){break;}else{continue;}x++}do{x++x----x++x}while(1)switch(x){default:{x++break;}case 48:{break;}case 97:{break;}case 9:{break;}case 1:{}case 2:{}case 3:{break;}case 5:{{x--x++x *= 10}break;}case 6:{switch(x){default:{break;}case 1:{}case 2:{}case 3:{break;}case 4:{{}break;}}break;}}return 1}void funcWithArg(int var1){return ;}void funcWithManyArg(int var1, int var2, int var3){do{var1++var2--if(var1 + var2 <= var3){return ;}}while(1 > 2)int innerFunc(int var4, int var5){var4 = var1 + var2 + var3 / var5}innerFunc(1,2,)}int funcInt(){return ;}int funcVar(...){funcVar(1,2,3,)return 0}


可以看到,结果大致与源代码相同。

 

 

原创粉丝点击