Update:
-
igame@May/16/2019:
- Removed "ExternalFunction": it's redundent. So did the "RegesterExternalFunction".
- Renamed "InternalFunctions" directory(or namespace) to "ExtraFunctions".
- Removed Flex/Bison project which based on WinSDK 8.1.
- Renamed extra function "input" to "inputDlg".
- Fixed bug: "inputDlg" won't work.
在维护新建对象(my son)的时候,利用对象休眠的闲暇,写了个习作。
咸盐少许。
通常,编译原理或编译技术都会建议使用yacc或lex来实现语言、公式的解释器或编译器。鉴于实现一个语言编译器或解释器的困难,大多数猿类都会使用这类工具。不过,本文穿越到了工具出现以前的时代,同时又开启了金手指:带了c#、Flex和Bison。既是习作,故使用c#手工打造了一个简单的c语言解释器,而并未使用Flex和Bison。
这个解释器被胡乱命名为SharpC。它实现了c语言的如下部分特性:
特性 | 支持程度 | 说明 |
---|---|---|
基本的类型 | char, short, int, float, struct | 对于unsigned, signed的区分不明显,不支持const关键字 now keyword "const" is supported。 |
函数 | 支持 | 包括不定参数函数,支持递归,支持嵌套定义。 |
表达式 | 仅不支持?:三元操作符 | 逗号操作符未测试。 |
指针 | 支持 | 这意味着支持内存操作,也意味支持字符串。 |
控制结构 | 仅不支持goto | 包括:if/else, for, while, do/while, switch/case/default/break, return, continue. |
内建函数 | malloc(), free(), print(), vararg(), varlen(), input(), InputDlg(), prompt(), confirm() | According updating of May-16-19, it's easier to add new functions into system. |
其它 | 所有其它c语言功能皆不支持 | 诸如: #符号,macro, typedef 等。 |
我们先看看最终结果,对于这样的一个c语言测试代码:
/*
* This is a multi-line comment.
*
*/
// This is a single line comment.
char globalChar = 'A';
short globalShort = 333;
int globalInt = 1; // Global scope declaration
float globalFloat = 1.2345;
char* ptr = "abcdefg" "hijklmn";
void funcFwdDecl(); // forwarding declaration
void funcWithoutArg()
{
// Variable declaration and initialization
int x = 1;
// Empty statement
;
{ // anonymous block
int y = 3;
} // end of block
// Test bare expression
1 < 2;
1 <= 2;
2 > 1;
2 >= 1;
// Test comments
x += 1 // This is a comment
;
// Test assign
x = 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 operator
x = x++;
x = x--;
x = ++x;
x = --x;
// Control flow
// If with statement
if (x <= 1)
x++;
// If/else
if (x <= 2)
x--;
else
x++;
// if/else matching 1
if (x <= 3)
--x;
else
if (x <= 4)
x++;
if (x <= 5)
x += 1;
else
if (x <= 6)
x += 2;
else
x += 3;
// If with block
if (x <= 7)
{
x /= 10;
}
else
{
x *= 10;
}
if (1 < 2)
x = 0;
else
if (3 < 4)
x = 1;
else
x = 2;
// for loop
// Commonly for loop with single statemnt
for(int i = 0; i < 100; i++)
x++;
// for loop with block
for(int i = 0; i < 100; i++)
{
x++;
x--;
}
// for loop with long initializer
int i = 0;
for(i = 1, x = 0; i < 100; i++)
{
x--;
x++;
}
// for loop with long iterator
for(int l = 0; l < 100; l++, x--, x++, x--)
x--;
// for loop with break & continue
for(int l = 0; l < 100; l++)
{
if (l > 100)
break;
else
if (l > 50)
continue;
}
// while with single statement
while(1 < 2) x++;
// while with block
while(x < 3)
{
x++;
x;
}
// while with break & continue
while( x < 10)
{
if (x > 5)
break;
else
continue;
x++;
}
// do/while
do{
x++;
x--;
--x;
++x;
}// comments
while(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 func
void 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;
else
if (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;
else
if (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:15
void * 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 = 65
short globalShort
globalShort = 333
int globalInt
globalInt = 1
float globalFloat
globalFloat = 1.2345
char * ptr
ptr = $var_char_ptr_6$
void funcFwdDecl()
void funcWithoutArg()
{
int x
x = 1
{
int y
y = 3
}
1 < 2
1 <= 2
2 > 1
2 >= 1
x += 1
x = 10 - 3
x += 1
x += 1
x *= 1
x /= 1
x %= 1
x &= 1
x |= 1
x ^= 1
x <<= 1
x >>= 1
x = x++
x = x--
x = ++x
x = --x
if(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 = 0
Condition: i < 100
Iterator: i++
{
x++
}
for(
Initalizer:
int i
i = 0
Condition: i < 100
Iterator: i++
{
x++
x--
}
int i
i = 0
for(
Initalizer:
i = 1
Condition: i < 100
Iterator: i++
{
x--
x++
}
for(
Initalizer:
int l
l = 0
Condition: l < 100
Iterator: l++
{
x--
}
for(
Initalizer:
int l
l = 0
Condition: l < 100
Iterator: 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
}
可以看到,结果大致与源代码相同。