锘??xml version="1.0" encoding="utf-8" standalone="yes"?>
2.涓鏉ush鎸囦護鏈澶氬帇鍏?涓瓧鑺?褰撲笉瓚?涓瓧鑺傛椂搴旇ˉ榻?涓瓧鑺?瓚呰繃4涓瓧鑺傛椂搴旇鐢變綆浣嶅埌楂樹綅渚濇鍘嬫爤.
3.pop鎸囦護涔熷拰push涓鏍蜂竴嬈″彧鑳藉脊鍑?涓瓧鑺?
4.鎴戜滑闇瑕佷竴涓狢allStruct綾誨瀷鏉ュ偍瀛樹竴涓弬鏁?
2 {
3 public:
4 INT Integer;
5 BOOL Bool;
6 DOUBLE Real;
7 WCHAR String[MAX_STRING];
8
9 enum TYPE
10 {
11 ctInteger,
12 ctString,
13 ctBool,
14 ctReal,
15 ctVoid,
16 }Type;
17
18 CallStruct() : Integer(0),Bool(FALSE),Real(0)
19 {
20 String[0] = 0;
21 }
22
23 CallStruct(const NAutoPtr<VirtualMachine::VarClass>& Var) : Integer(Var->Integer),Bool(Var->Bool),Real(Var->Real),Type((TYPE)Var->Type)
24 {
25 if(Type == ctString) wcscpy(String,Var->String);
26 }
27 };
2 NAutoPtr<CallStruct> Return;
2 FARPROC FunctionPtr;
2 BOOL SetReturnType(CallStruct::TYPE Type);
3 BOOL SetLibName(LPTSTR Name);
4 BOOL SetFunctionName(LPTSTR Name);
8.鎴戜滑娣誨姞涓涓嚱鏁癛un鐢ㄤ簬璋冪敤鍑芥暟.
2 {
3 if(FunctionPtr == 0 || Return.Buffer() == 0) return FALSE;
4 union RealStruct
5 {
6 double Real;
7 struct
8 {
9 int Head,Tail;
10 };
11 };
12 NAutoPtr<CallStruct> cs;
13 int Integer;
14 BOOL Bool;
15 RealStruct Real; // Push鎸囦護涓嬈″彧鑳藉帇鍏?瀛楄妭
16 LPTSTR String;
17
18 int iEsp;
19 __asm mov int ptr[iEsp],esp; // 淇濆瓨esp
20 for(int i=0;i<VarList.Size();i++)
21 {
22 cs = VarList[i];
23 Integer = cs->Integer;
24 Bool = cs->Bool;
25 Real.Real = cs->Real;
26 String = cs->String;
27 switch(cs->Type)
28 {
29 case CallStruct::ctInteger:
30 __asm push Integer;
31 break;
32 case CallStruct::ctString:
33 __asm push String;
34 break;
35 case CallStruct::ctBool:
36 __asm push Bool;
37 break;
38 case CallStruct::ctReal:
39 __asm push Real.Tail;
40 __asm push Real.Head;
41 break;
42 }
43 }
44 FARPROC proc = FunctionPtr;
45 int Head,Tail;
46 __asm
47 {
48 call proc
49 mov int ptr[Head],edx
50 mov int ptr[Tail],eax
51 }
52 switch(Return->Type)
53 {
54 case CallStruct::ctInteger:
55 Return->Integer = Tail;
56 break;
57 case CallStruct::ctString:
58 wcscpy(Return->String,(LPCTSTR)Tail);
59 break;
60 case CallStruct::ctBool:
61 Return->Bool = Tail;
62 break;
63 case CallStruct::ctReal:
64 __asm fstp [Real.Real];
65 Return->Real = Real.Real;
66 break;
67 }
68 // __declspec璋冪敤綰﹀畾,闇瑕佹墜宸ヨ繕鍘熷爢鏍?/span>
69 __asm mov esp,int ptr[iEsp];
70 return TRUE;
71 }
鐒跺悗鏍規(guī)嵁綾誨瀷渚濇灝嗗嚱鏁板帇鏍?
鐒跺悗璋冪敤call鎸囦護騫朵繚瀛樿繑鍥炲?(榪欓噷闇瑕佹敞鎰忕殑鏄?span style="COLOR: red">褰撹繑鍥炲肩被鍨嬩負double鎴杅loat綾誨瀷鏃跺繀欏諱嬌鐢╢stp鎸囦護浠嶧PU瀵勫瓨鍣ㄦ爤鐨勬爤欏剁殑鍊煎彇鍑烘潵)
鏈鍚庤繕鍘熷爢鏍?
鐒跺悗鎴戜滑鏉ユ祴璇曚竴涓?
鍒涘緩涓涓悕涓篢estDLL鐨凞LL宸ョ▼騫舵坊鍔犲嚱鏁癟est.
2 {
3 if(d == 123.456789) MessageBox(0,lpBuffer,L"",0);
4 *d1 = 789.654;
5 return 77777;
6 }
鐒跺悗鍒涘緩涓涓祴璇曞伐紼?娣誨姞鐩稿叧鏂囦歡.
鍦╛tmain涓坊鍔犱互涓嬩唬鐮?
2 {
3 double d;
4 CallMacro cm;
5 NAutoPtr<VirtualMachine::VarClass> Var;
6
7 Var = new VirtualMachine::VarClass;
8 Var->Type = VirtualMachine::VarClass::vtString;
9 wcscpy(Var->String,L"aaaaa");
10 cm.AddVar(Var);
11
12 Var = new VirtualMachine::VarClass;
13 Var->Type = VirtualMachine::VarClass::vtInteger;
14 Var->Integer = (INT)&d;
15 cm.AddVar(Var);
16
17 Var = new VirtualMachine::VarClass;
18 Var->Type = VirtualMachine::VarClass::vtReal;
19 Var->Real = 123.456789;
20 cm.AddVar(Var);
21
22 cm.SetLibName(L"TestDll.dll");
23 cm.SetFunctionName(L"Test");
24 cm.SetReturnType(CallMacro::CallStruct::ctReal);
25 cm.Run();
26
27 wprintf(L"%f %f\n",d,cm.Return->Real);
28 system("pause");
29 return 0;
30 }
緙栬瘧騫惰繍琛?鍙互鐪嬪埌Test鍑芥暟璋冪敤鎴愬姛,騫舵垚鍔熻緭鍑篸鐨勫煎拰榪斿洖鍊?
鏈鍚庣粰鍑?a href="http://www.shnenglu.com/Files/lwch/DLLTest.rar">瀹屾暣浠g爜.
]]>
鎴戜滑棣栧厛闇瑕佷竴涓狥ail鍩虹被,浠栨湁涓涓函铏氬嚱鏁癙arser.
2 {
3 public:
4 virtual NWString Parser(NWString& input)=0;
5 };
鐒跺悗鎴戜滑闇瑕佷竴涓狢h鍜屼竴涓猄tr鍒嗗埆鐢ㄦ潵鍒嗘瀽鍗曚釜瀛楃鍜屼竴涓瓧絎︿覆.
2 {
3 public:
4 Ch(WCHAR _value) : value(_value){}
5
6 NWString Parser(NWString& input);
7
8 WCHAR Value();
9 protected:
10 WCHAR value; // 寰呭尮閰嶄覆
11 };
12
13 class Str : public Fail
14 {
15 public:
16 Str(NWString _value) : value(_value){}
17
18 NWString Parser(NWString& input);
19 protected:
20 NWString value; // 寰呭尮閰嶄覆
21 };
鐒跺悗鏄疭eq,Alt鍜孉ny,鍒嗗埆琛ㄧず緇勫悎,閫夋嫨鍜屽驚鐜?
2 {
3 public:
4 Seq(const NAutoPtr<Fail>& _left,const NAutoPtr<Fail>& _right) : left(_left),right(_right){}
5
6 NWString Parser(NWString& input);
7 protected:
8 NAutoPtr<Fail> left;
9 NAutoPtr<Fail> right;
10 };
11
12 class Alt : public Fail
13 {
14 public:
15 Alt(const NAutoPtr<Fail>& _left,const NAutoPtr<Fail>& _right) : left(_left),right(_right){}
16
17 NWString Parser(NWString& input);
18 protected:
19 NAutoPtr<Fail> left;
20 NAutoPtr<Fail> right;
21 };
22
23 class Any : public Fail
24 {
25 public:
26 Any(const NAutoPtr<Fail>& _left,const int _count) : left(_left),count(_count){}
27
28 NWString Parser(NWString& input);
29 protected:
30 NAutoPtr<Fail> left;
31 int count;
32 };
鏈鍚庢垜浠渶瑕佷竴涓狽ode綾誨瀷鏉ュ瓨鏀句互涓婅繖鍑犵被瀵硅薄.
2 {
3 public:
4 Node(){}
5 Node(const NAutoPtr<Fail>& _left) : left(_left){}
6
7 friend NAutoPtr<Node> operator+(const NAutoPtr<Node>& left,const NAutoPtr<Node>& right);
8 friend NAutoPtr<Node> operator|(const NAutoPtr<Node>& left,const NAutoPtr<Node>& right);
9 friend NAutoPtr<Node> operator-(const NAutoPtr<Node>& left,const NAutoPtr<Node>& right);
10
11 static NAutoPtr<Node> OnceMore(NAutoPtr<Node> node);
12 static NAutoPtr<Node> More(NAutoPtr<Node> node);
13 static NAutoPtr<Node> NewCh(WCHAR input);
14 static NAutoPtr<Node> NewStr(NWString input);
15
16 NWString Parser(NWString& input);
17
18 NAutoPtr<Fail>& Value();
19 protected:
20 NAutoPtr<Fail> left;
21 };
+:瀵瑰簲浜嶴eq,鐢ㄤ簬灝嗕袱涓狽ode榪炴帴璧鋒潵.
|:瀵瑰簲涓嶢lt,鐢ㄤ簬閫夋嫨涓や釜Node.
-:鍙湁left鍜宺ight鐨刅alue()閮芥槸NAutoPtr<Ch>鏃舵墠鍙嬌鐢?鍐呴儴鏈夌被鍨嬭漿鎹?琛ㄧず浠庡摢涓瓧絎﹀埌鍝釜瀛楃.
OnceMore:閲嶅1嬈″強浠ヤ笂.
More:閲嶅0嬈′互涓?
NewCh:鐢熸垚涓涓狽AutoPtr<Ch>鐨凬ode瀵硅薄.
NewStr:鐢熸垚涓涓狽AutoPtr<Str>鐨凬ode瀵硅薄.
涓嬮潰鎴戜滑闇瑕?涓畯.
2 #define MORE(N) Node::More(N)
3 #define NEWCH(N) Node::NewCh(N)
4 #define NEWSTR(N) Node::NewStr(N)
鐒跺悗鎴戜滑鏉ユ祴璇曚竴涓?
2 + MORE(NEWCH('_') | (NEWCH('0') - NEWCH('9')) | (NEWCH('a') - NEWCH('z')) | (NEWCH('A') - NEWCH('Z')));
3 NAutoPtr<Node> Number = ONCEMORE(NEWCH('0') - NEWCH('9'));
4 NAutoPtr<Node> Real = Number + NEWCH('.') + Number;
Symbol->[_a-zA-Z]+[_0-9a-zA-Z]*
Number->[0-9]+
Real->[0-9]+.[0-9]+
瀹氫箟涓涓緟鍒嗘瀽鐨勫瓧絎︿覆.
瀵瑰叾鍒嗘瀽.
2 wprintf(L"%s\n",Symbol->Parser(str));
3 wprintf(L"%s\n",Real->Parser(str));
4 wprintf(L"%s\n",Symbol->Parser(str));
鍒嗘瀽緇撴灉.
2 123.459agetr
3 agetr
4
鍥犱負娌℃湁鑰冭檻鍒嗘瀽鏁堢巼闂,鎵浠ヤ嬌鐢∟WString浣滀負杈撳叆鍜岃緭鍑?鍦ㄥ疄闄呬嬌鐢ㄤ腑鍙敤LPTSTR鏉ヤ唬鏇縉WString,鍚屾椂淇敼鍝嶅簲浠g爜.
鏈鍚庣粰鍑?a href="http://www.shnenglu.com/Files/lwch/RegexEngine.rar">婧愪唬鐮?/a>
]]>
]]>
2 {
3 public:
4 int Op1;
5 int Op2;
6 List<NAutoPtr<SyntaxNode>> Child;
7
8 SyntaxNode(int O1,int O2) : Op1(O1),Op2(O2){}
9 };
10
11 class CharClass
12 {
13 public:
14 int Index;
15 NWString String;
16
17 CharClass(NWString S) : String(S){}
18 };
姣忎釜璇硶鏍戠殑鑺傜偣鏈?涓弬鏁癘p1,Op2鍒嗗埆琛ㄧず褰撳墠鑺傜偣鐨勭被鍨嬪拰闄勫姞鍙傛暟
Child涓哄綋鍓嶈妭鐐圭殑瀛愯妭鐐?br>
CharClass緇撴瀯鍒欐瘮杈冪畝鍗曞垎鍒負绱㈠紩鍜屽瓧絎?br>
鐒跺悗鏄儴鍒哠yntaxNode鐨凮p1鐨勬灇涓?
2 {
3 opNull,
4 opVar,
5 opConst,
6 };
浠ュ強VarType鐨勬灇涓?
2 {
3 vtNull,
4 vtVoid,
5 vtBool,
6 vtInt,
7 vtReal,
8 vtString,
9 vtSymbol,
10 };
2 #define INDEX_VARTYPE_BOOL 2
3 #define INDEX_VARTYPE_INT 3
4 #define INDEX_VARTYPE_REAL 4
5 #define INDEX_VARTYPE_STRING 5
6 #define INDEX_VALUETYPE_STRING 6
7 #define INDEX_VALUETYPE_SYMBOL 7
8 #define INDEX_VALUETYPE_REAL 8
9 #define INDEX_VALUETYPE_DIGIT 9
10 #define INDEX_VALUETYPE_TRUE 10
11 #define INDEX_VALUETYPE_FALSE 11
浠ヤ笂绱㈠紩鐨勫畾涔夊彇鑷狽S.txt,闅忕潃浠ュ悗鏂囨硶鐨勫鍔犺繖閲岀殑绱㈠紩瀹氫箟涔熶細澧炲姞
NS.h,NS.cpp,NS.ParserTable鍧囨槸鐢盢ScriptMacro.exe榪愯NS.txt鐢熸垚鐨?br>
涓嬮潰鏉ョ湅涓涓婼yntaxAnalyze鍑芥暟:
2 {
3 BOOL bResult = TRUE;
4 // 鏍規(guī)嵁浜х敓寮忕儲寮曠敓鎴愯娉曟爲
5 switch(i)
6 {
7 case INDEX_VARTYPE_VOID:
8 case INDEX_VARTYPE_BOOL:
9 case INDEX_VARTYPE_INT:
10 case INDEX_VARTYPE_REAL:
11 case INDEX_VARTYPE_STRING:
12 bResult = VarType(i);
13 break;
14 case INDEX_VALUETYPE_STRING:
15 case INDEX_VALUETYPE_SYMBOL:
16 case INDEX_VALUETYPE_REAL:
17 case INDEX_VALUETYPE_DIGIT:
18 case INDEX_VALUETYPE_TRUE:
19 case INDEX_VALUETYPE_FALSE:
20 bResult = ValueType(i);
21 break;
22 }
23 return bResult;
24 }
榪欎釜鍑芥暟鏍規(guī)嵁浼犲叆鍙傛暟(浜х敓寮忕儲寮?璋冪敤鐩稿叧鍑芥暟鐢熸垚璇硶鏍?鍏蜂綋璇硶鏍戠殑鐢熸垚榪囩▼璇風(fēng)湅鐩稿叧浠g爜
]]>
鏈鍒濇枃娉曞畾涔変負:
2 %token "true" "false";
3 %token "{" "}" "," ";" "=";
4 %token "+" "-" "*" "/";
5 %token ">" "<" ">=" "<=" "==" "and" "not" "or";
6
7 %start program;
8
9 var_type -> "void"
10 | "bool"
11 | "int"
12 | "real"
13 | "string"
14 ;
15
16 value_type -> "{String}"
17 | "{Symbol}"
18 | "{real}"
19 | "{digit}"
20 | "true"
21 | "false"
22 ;
23
24 paramter_define_desc -> "{LQ}" paramter_defines "{RQ}"
25 | "{LQ}" "{RQ}"
26 ;
27
28 paramter_defines -> paramter_defines "," paramter_one
29 | paramter_one
30 ;
31
32 paramter_one -> var_type "{Symbol}"
33 ;
34
35 assign_type -> "{Symbol}"
36 ;
37
38 program -> item_list
39 ;
40
41 item_list -> item_list item
42 | item
43 ;
44
45 item -> function
46 | define_desc ";"
47 ;
48
49 stmt_list -> stmt_list stmt
50 | stmt
51 ;
52
53 stmt -> define_desc ";"
54 | assign_desc ";"
55 | ";"
56 ;
57
58 function -> var_type "{Symbol}" paramter_define_desc "{" stmt_list "}"
59 | var_type "{Symbol}" paramter_define_desc "{" "}"
60 ;
61
62 define_desc -> define_desc "," "{Symbol}"
63 | var_type "{Symbol}"
64 ;
65
66 assign_desc -> assign_type "=" exp
67 ;
68
69 exp -> exp ">" exp1
70 | exp "<" exp1
71 | exp ">=" exp1
72 | exp "<=" exp1
73 | exp "==" exp1
74 | exp "and" exp1
75 | exp "or" exp1
76 | "not" exp1
77 | "+" exp1
78 | "-" exp1
79 | exp1
80 ;
81
82 exp1 -> exp1 "+" exp2
83 | exp1 "-" exp2
84 | exp2
85 ;
86
87 exp2 -> exp2 "*" exp3
88 | exp2 "/" exp3
89 | exp3
90 ;
91
92 exp3 -> "{LQ}" exp "{RQ}"
93 | value_type
94 ;
鐢變互涓婃枃娉曚腑浠呮湁鍑芥暟鐨勫畾涔夊拰鍙橀噺鐨勫畾涔?br>鏈夌偣綾籆鐨勫懗閬?
宸叉垚鍔熷皢ESLanguage澶ч儴鍒嗕唬鐮佺Щ妞嶅埌榪欎釜欏圭洰閲?
]]>
exp->exp1
exp1->exp2 | exp5
exp5->exp1 (“<” | “>” | “==”) exp2
exp2->exp3 | exp6
exp6->exp2 (“+” | “-“) exp3
exp3->exp4 | exp7
exp7->exp3(“*” | “/”) exp4
exp4->”(“ exp “)”int->[0-9]+
real->[0-9]+.[0-9]+
string->
datatype->”int” | “real” | “bool” | “string”
prgama->function | functionheader “;”
functionheader->”function” sym ”(“ parameters ”)” [“as” datatype]
parameters->[[sym as datatype],parameters]
function->functionheader “{“ block “}”
block->statementlist
statement->local-stmt | if-stmt | while-stmt | do-stmt | for-stmt | switch-stmt | assign-stmt | call-stmt | return-stmt
local-stmt->”local” varlist
varlist->symlist “as” datatype [“,” varlist]
if-stmt->”if” exp statementlist [“else” statementlist]
while-stmt->”while” exp statementlist
do-stmt->”do” statementlist “while” exp “;”
for-stmt->”for” “(“ exp “;” exp “;” exp “)” statementlist
switch-stmt->”switch” exp “{“ case-stmt “}”
case-stmt->(”case” sym | “default”) “:” statementlist case-stmt
assign-stmt->exp “=” exp
call-stmt->sym “(“ parameters “)” “;”
return-stmt->”return” exp
symlist->sym [“,” symlist]
statement->“{“ statementlist “}”
statement->”;”
statementlist->statement [statementlist]
exp->exp1
exp1->exp2
exp1->exp1 (“<” | “<=” | “=” | “>=” | “>” | “!=”) exp2
exp2->exp3
exp2->exp2 (“+” | “-“) exp3
exp3->exp4
exp3->exp3(“*” | “/”) exp4
exp4->”(“ exp “)”