要写一个脚本引擎,首先要明确脚本长什么样,具备哪些功能,需要有怎样的能力。
Since昨天我说第一版是面向过程,强类型,无闭包,无自定义结构,支持数组,那么我将脚本设计如下:
CNScript 0.1 Draft
Functionality:
Procedure Oriented, No Custom Data Structures, No Closures, Strong Typed, Array Supported.
Keywords:
int,double,char,string,bool,void,if,else,for,do,while,return
Statements:
Single Expression:
expression;
Chunk:
{
Statement1
Statement2
}
Array Declaration:
type name[size];
Variable Declaration:
type name [= expression];
Function definition:
type FunctionName(type paramName1, type paramName2)
Chunk
IF-ELSE:
if(expression)
Statement1
else
Statement2
FOR-LOOP:
for(statement1 expression2;expression3)
Statement
WHILE-LOOP:
while(expression)
Statement
DO-WHILE-LOOP:
do
Statement
while(expression);
Expressions:
Values:
true
false
number
string
char
Variable Name
Array Name[index]
Assign:
name = expression
Function Call:
name(expression1,expression2)
Compares:
expression1 == expression2
expression1 != expression2
expression1 < expression2
expression1 > expression2
expression1 <= expression2
expression1 >= expression2
Boolean Operations:
!expression
expression1 && expression2
expression1 || expression2
Calculating:
expression++
expression—
++expression
--expression
expression1 + expression2
expression1 – expression2
expression1 * expression2
expression1 / expression2
expression1 % expression2
expression1 ^ expression2
(expression)
Lexical Tokens:
Spaces:
Space: (space_bar+)|(\n+) (\r+)|(\t+)
TypeNames:
Type: (int)|(double)|(char)|(string)|(bool)|(void)
Keywords:
Keyword_if: if
Keyword_else: else
Keyword_for: for
Keyword_do: do
Keyword_while: while
Keyword_return: return
Brackets:
BigLeftBracket: {
BigRightBracket: }
MidLeftBracket: [
MidRightBracket: ]
SmallLeftBracket: \(
SmallRightBracket: \)
Identifier:
Identifier: (_+[a-zA-Z0-9_]+)|([a-zA-Z][a-zA-Z0-9_]*)
Number Value:
Integer: 0|[1-9][0-9]*
Double: (0|[1-9][0-9]*)\.[0-9]+
Bool Value:
BoolValue: true|false
Char:
CharValue: ‘(\\[^\r\n\t])|([^’\r\n\t])’
String:
StringValue: “((\\”)|[^\r\n])*”
Operators:
Operator: =|\+|-|\*|/|%|^|(++)|(--)|(&&)|(\|\|)|(!)|<|>|(<=)|(>=)|(==)|(!=)
Seprators:
Seprator: ;
以上就是脚本设计初稿,如果后面发现有错误,会去更正的。
按这个设计,写出来的程序大概是下面这样:
1 int Foo(int value)
2 {
3 return value;
4 }
5
6 void main()
7 {
8 int a = 100;
9 for(int i=0;i<100;i++)
10 {
11 --a;
12 }
13 if(a>0)
14 {
15 Foo(a);
16 }
17 }
基本上就是个没模板,没类,没指针的C++了。
设计就这样了,明天开始写词法分析喔!上面的Lexical Tokens就是给词法分析用的,因为代码是字符串,我们先要把整个字符串读成一个一个的Token,才方便进行语法分析和更深入的处理,比如
int a = 100;
要先拆成[type:int] [space] [identifier:a] [space] [operator:=] [space] [integer:100] [seperator:;]
这个过程就是词法分析了。
词法分析完了得出这些Tokens然后再匹配到
Variable Declaration:
type name [= expression];
才能建立起语法树来。
Lexical Tokens中是每种Token对应的正则表达式。