随笔-341  评论-2670  文章-0  trackbacks-0
    使用了上一篇文章的方法,我已经用C#把NativeX语言的语法分析器写出来了。而且最近把代码文件重构了一遍,删除掉了原来的实验性工程,转而重新设计了一个比较合理的工程结构,当然还是提交到了Vczh Library++ 3.0的页面上去了。现在先来看一看给IDE使用的文法哈。现在语法分析器已经有两套了,一套是C++写的用于开发NativeX的编译器的,另一套是C#写的用于开发NativeX的IDE的。用来写编译器的文法在严格的同时还要指定错误信息的产生过程,而用于IDE的语法分析器就比较宽松一点了。

    首先是C++版本的:
 1                     linking            = (ALIAS >> (ID + (DOT >> ID))[ToLinking]);
 2 
 3                     primitive        = TRUE[ToTrue] | FALSE[ToFalse]
 4                                     | ACHAR[ToAChar] | WCHAR[ToWChar]
 5                                     | ASTRING[ToAString] | WSTRING[ToWString]
 6                                     | FLOAT[ToFloat] | DOUBLE[ToDouble]
 7                                     | NULL_VALUE[ToNull]
 8                                     | EXCEPTION_VALUE[ToException]
 9                                     | INTEGER[ToInteger]
10                                     ;
11 
12                     reference        = (ID + (LT(NeedLt) >> type(NeedTypeExpression) << GT(NeedGt)) + (COLON(NeedColon) + COLON(NeedColon) >> ID(NeedID)))[ToBasicInstanceFunctionExpression]
13                                     | (ID + (LT(NeedLt) + list(opt(type + *(COMMA >> type))) << GT(NeedGt)))[ToInstanciatedExpression]
14                                     | ID[ToReference]
15                                     ;
16 
17                     exp0            = primitive(NeedExpression)
18                                     | reference
19                                     | RESULT[ToResult]
20                                     | (CAST + (LT(NeedLt) >> type << GT(NeedGt)) + (OPEN_BRACE(NeedOpenBrace) >> exp << CLOSE_BRACE(NeedCloseBrace)))[ToCastExpression]
21                                     | (OPEN_BRACE >> exp << CLOSE_BRACE(NeedCloseBrace))
22                                     ;
23 
24                     exp1            = lrec(exp0 +  *(
25                                                     (OPEN_ARRAY + exp << CLOSE_ARRAY(NeedCloseArray))
26                                                     | (OPEN_BRACE + list(opt(exp + *(COMMA >> exp)))[UpgradeArguments] << CLOSE_BRACE(NeedCloseBrace))
27                                                     | ((DOT | POINTER) + ID[ToReference])
28                                                     | ((INCREASE | DECREASE)[UpgradePostfix])
29                                                     ), ToPostUnary);
30                     exp2            = exp1 | ((INCREASE | DECREASE | BIT_AND | MUL | SUB | BIT_NOT | NOT) + exp2)[ToPreUnary];
31                     exp3            = lrec(exp2 + *((MUL | DIV | MOD) + exp2), ToBinary);
32                     exp4            = lrec(exp3 + *((ADD | SUB) + exp3), ToBinary);
33                     exp5            = lrec(exp4 + *((LT+LT | GT+GT) + exp4), ToBinary2);
34                     exp6            = lrec(exp5 + *((LT | GT | LE | GE) + exp5), ToBinary);
35                     exp7            = lrec(exp6 + *((EQ | NE) + exp6), ToBinary);
36                     exp8            = lrec(exp7 + *(BIT_AND + exp7), ToBinary);
37                     exp9            = lrec(exp8 + *(XOR + exp8), ToBinary);
38                     exp10            = lrec(exp9 + *(BIT_OR + exp9), ToBinary);
39                     exp11            = lrec(exp10 + *(AND + exp10), ToBinary);
40                     exp12            = lrec(exp11 + *(OR + exp11), ToBinary);
41                     exp                = lrec(exp12 + *((OP_ASSIGN | ASSIGN) + exp12), ToBinary);
42 
43                     functionType    = (FUNCTION(NeedType) + type + (OPEN_BRACE(NeedOpenBrace) >> list(opt(type + *(COMMA >> type))) << CLOSE_BRACE(NeedCloseBrace)))[ToFunctionType];
44                     primType        = functionType
45                                     | ((PRIM_TYPE | ID)[ToNamedType] + (LT(NeedLt) + list(opt(type + *(COMMA >> type))) << GT(NeedGt)))[ToInstanciatedGenericType]
46                                     | (PRIM_TYPE | ID)[ToNamedType]
47                                     ;
48 
49                     type            = lrec(primType + *(MUL | (OPEN_ARRAY >> INTEGER << CLOSE_ARRAY)), ToDecoratedType);
50 
51                     statement        = SEMICOLON(NeedStatement)[ToEmptyStat]
52                                     | (exp + SEMICOLON(NeedSemicolon))[ToExprStat]
53                                     | (VARIABLE + type + ID(NeedID) + opt(ASSIGN >> exp) << SEMICOLON(NeedSemicolon))[ToVarStat]
54                                     | (IF + (OPEN_BRACE(NeedOpenBrace) >> exp << CLOSE_BRACE(NeedCloseBrace)) + statement + opt(ELSE >> statement))[ToIfStat]
55                                     | (BREAK << SEMICOLON(NeedSemicolon))[ToBreakStat]
56                                     | (CONTINUE << SEMICOLON(NeedSemicolon))[ToContinueStat]
57                                     | (EXIT << SEMICOLON(NeedSemicolon))[ToReturnStat]
58                                     | (OPEN_STAT + list(*statement) << CLOSE_STAT(NeedCloseStat))[ToCompositeStat]
59                                     | (DO + statement + (WHILE(NeedWhile) >> OPEN_BRACE(NeedOpenBrace) >> exp << CLOSE_BRACE(NeedCloseBrace) << SEMICOLON(NeedSemicolon)))[ToDoWhileStat]
60                                     | (LOOP + statement)[ToLoopStat]
61                                     | (WHILE + (OPEN_BRACE(NeedOpenBrace) >> exp << CLOSE_BRACE(NeedCloseBrace)) + statement + opt(WHEN >> OPEN_BRACE(NeedOpenBrace) >> exp << CLOSE_BRACE(NeedCloseBrace) << SEMICOLON(NeedSemicolon)))[ToWhileStat]
62                                     | (FOR + list(*statement) + (WHEN(NeedWhen) >> OPEN_BRACE(NeedOpenBrace) >> exp << CLOSE_BRACE(NeedCloseBrace)) + (WITH(NeedWith) >> list(*statement)) + (DO(NeedDo) >> statement))[ToForStat]
63                                     | (TRY + (statement + (CATCH(NeedCatch) >> statement)))[ToTryCatch]
64                                     | (THROW + opt(exp) << SEMICOLON(NeedSemicolon))[ToThrow]
65                                     ;
66 
67                     instanceType    = (PRIM_TYPE | ID)[ToNamedType]
68                                     ;
69 
70                     functionDeclaration
71                                     = (FUNCTION + type + ID(NeedID) + (OPEN_BRACE(NeedOpenBrace) >> plist(opt((type + ID(NeedID)) + *(COMMA >> (type + ID(NeedID))))) << CLOSE_BRACE(NeedCloseBrace)) + opt(linking << SEMICOLON(NeedSemicolon)) + opt(statement))[ToFuncDecl]
72                                     ;
73 
74                     nonGenericDeclaration        
75                                     = (VARIABLE + type + ID(NeedID) + opt(linking) + opt(ASSIGN >> exp) << SEMICOLON(NeedSemicolon))[ToVarDecl]
76                                     | (TYPE + ID + (ASSIGN(NeedAssign) >> type) << SEMICOLON(NeedSemicolon))[ToTypedefDecl]
77                                     | (STRUCTURE + ID(NeedID) << SEMICOLON(NeedSemicolon))[ToStructPreDecl]
78                                     | (STRUCTURE + ID(NeedID) + opt(linking) + (OPEN_STAT(NeedOpenStruct) >> *(type + ID(NeedID) << SEMICOLON(NeedSemicolon)) << CLOSE_STAT(NeedCloseStruct)))[ToStructDecl]
79                                     | (INSTANCE >> (instanceType + (COLON(NeedColon) >> ID << SEMICOLON(NeedSemicolon))))[ToInstancePreDecl]
80                                     | ((INSTANCE >> (instanceType + (COLON(NeedColon) >> ID)))+(OPEN_STAT(NeedOpenConcept)>>*((ID(NeedID)+(ASSIGN(NeedAssign)>>reference)<<SEMICOLON(NeedSemicolon)))[ToFunctionInstance]<<CLOSE_STAT(NeedCloseConcept)))[ToInstanceDecl]
81                                     | functionDeclaration
82                                     | (FOREIGN >> functionDeclaration)[ToForeignFunctionDecl]
83                                     ;
84 
85                     Node<TokenInput<RegexToken>, ParsingList<RegexToken>> genericHead
86                                     = (GENERIC>>LT(NeedLt)>>plist(ID(NeedID)+*(COMMA>>ID(NeedID)))<<GT(NeedGt))
87                                     ;
88                     Node<TokenInput<RegexToken>, ParsingPair<RegexToken, RegexToken>> genericConstraintClause
89                                     = ID(NeedID) + (COLON(NeedColon) >> ID(NeedID))
90                                     ;
91                     Node<TokenInput<RegexToken>, ParsingList<ParsingPair<RegexToken, RegexToken>>> genericConstraint
92                                     = WHERE >> (plist(genericConstraintClause + *(COMMA >> genericConstraintClause)))
93                                     ;
94                     declaration        = nonGenericDeclaration
95                                     | (CONCEPT>>ID(NeedID)+(COLON(NeedColon)>>ID(NeedID))+opt(linking)+(OPEN_STAT(NeedOpenConcept)>>*((ID(NeedID)+(ASSIGN(NeedAssign)>>functionType)<<SEMICOLON(NeedSemicolon)))[ToFunctionConcept]<<CLOSE_STAT(NeedCloseConcept)))[ToConceptDecl]
96                                     | (genericHead+opt(genericConstraint)+nonGenericDeclaration(NeedDeclaration))[ToGeneric]
97                                     ;
98 
99                     unit            = ((UNIT(NeedUnit) >> ID(NeedID) << SEMICOLON(NeedSemicolon)) + list(opt(USES >> (ID(NeedID) + *(COMMA >> ID(NeedID))) << SEMICOLON(NeedSemicolon))) + list(*declaration))[ToUnit];


    其次是C#版本的:
  1             var ID = id("Developer.LanguageServices.NativeX.NativeXTokenizer.IdToken");
  2             var STRING = id("Developer.LanguageServices.NativeX.NativeXTokenizer.StringToken");
  3             var NUMBER = id("Developer.LanguageServices.NativeX.NativeXTokenizer.NumberToken");
  4 
  5             var REFERENCE_TYPE = rule<NativeXReferenceType>("ReferenceType");
  6             var FUNCTION_TYPE = rule<NativeXFunctionType>("FunctionType");
  7             var INSTANCIATED_TYPE = rule<NativeXInstanciatedType>("InstanciatedType");
  8             var PRIMITIVE_TYPE = rule<NativeXType>("PrimitiveType");
  9             var TYPE = rule<NativeXType>("Type");
 10 
 11             var PRIMITIVE = rule<NativeXPrimitiveExpression>("Primitive");
 12             var INSTANCE_FUNCTION_REFERENCE = rule<NativeXInstanceFunctionExpression>("InstanceFunctionReference");
 13             var INSTANCIATED_REFERENCE = rule<NativeXInstanciatedExpression>("InstanciatedReference");
 14             var IDENTIFIER_REFERENCE = rule<NativeXReferenceExpression>("IdentifierReference");
 15             var REFERENCE = rule<NativeXExpression>("Reference");
 16             var RESULT = rule<NativeXFunctionResultExpression>("Result");
 17             var EXCEPTION = rule<NativeXExceptionExpression>("Exception");
 18             var CAST = rule<NativeXCastingExpression>("Casting");
 19             var EXP0 = rule<NativeXExpression>("EXP0");
 20             var EXP1 = rule<NativeXExpression>("EXP1");
 21             var UNARY = rule<NativeXUnaryExpression>("Unary");
 22             var EXP2 = rule<NativeXExpression>("EXP2");
 23             var EXP_BINS = Enumerable.Range(311).Select(i => rule<NativeXExpression>("EXP" + i.ToString())).ToArray();
 24             var EXPRESSION = rule<NativeXExpression>("Expression");
 25 
 26             var EMPTY_STATEMENT = rule<NativeXEmptyStatement>("EmptyStatement");
 27             var EXPRESSION_STATEMENT = rule<NativeXExpressionStatement>("ExpressionStatement");
 28             var VARIABLE_STATEMENT = rule<NativeXVariableStatement>("VariableStatement");
 29             var IF_STATEMENT = rule<NativeXIfStatement>("IfStatement");
 30             var BREAK_STATEMENT = rule<NativeXBreakStatement>("BreakStatement");
 31             var CONTINUE_STATEMENT = rule<NativeXContinueStatement>("ContinueStatement");
 32             var EXIT_STATEMENT = rule<NativeXReturnStatement>("ExitStatement");
 33             var COMPOSITE_STATEMENT = rule<NativeXCompositeStatement>("CompositeStatement");
 34             var DO_WHILE_STATEMENT = rule<NativeXWhileStatement>("DoWhileStatement");
 35             var LOOP_STATEMENT = rule<NativeXWhileStatement>("LoopStatement");
 36             var WHILE_DO_STATEMENT = rule<NativeXWhileStatement>("WhileDoStatement");
 37             var FOR_STATEMENT = rule<NativeXForStatement>("ForStatement");
 38             var TRY_CATCH_STATEMENT = rule<NativeXTryCatchStatement>("TryCatchStatement");
 39             var THROW_STATEMENT = rule<NativeXThrowStatement>("ThrowStatement");
 40             var STATEMENT = rule<NativeXStatement>("Statement");
 41 
 42             var STRUCTURE_MEMBER = rule<NativeXNameTypePair>("StructureMemberItem");
 43             var INSTANCE_FUNCTION = rule<NativeXNameExpressionPair>("InstanceFunctionItem");
 44             var CONCEPT_FUNCTION = rule<NativeXNameTypePair>("ConceptFunctionItem");
 45             var GENERIC_PARAMETER = rule<NativeXGenericParameter>("GenericParameterItem");
 46             var GENERIC_CONSTRAINT = rule<NativeXGenericConstraint>("GenericConstraintItem");
 47             var LINKING = rule<NativeXLinking>("Linking");
 48 
 49             var FUNCTION_DECLARATION = rule<NativeXFunctionDeclaration>("FunctionDeclaration");
 50             var TYPE_RENAME_DECLARATION = rule<NativeXTypeRenameDeclaration>("TypeRenameDeclaration");
 51             var VARIABLE_DECLARATION = rule<NativeXVariableDeclaration>("VariableDeclaration");
 52             var STRUCTURE_DECLARATION = rule<NativeXStructureDeclaration>("StructureDeclaration");
 53             var INSTANCE_DECLARATION = rule<NativeXInstanceDeclaration>("InstanceDeclaration");
 54             var CONCEPT_DECLARATION = rule<NativeXConceptDeclaration>("ConceptDeclaration");
 55 
 56             var GENERIC_DECLARATION = rule<NativeXDeclaration>("GenericDeclaration");
 57             var NON_GENERIC_DECLARATION = rule<NativeXDeclaration>("NonGenericDeclaration");
 58             var DECLARATION = rule<NativeXDeclaration>("Declaration");
 59 
 60             var USE = rule<NativeXUses>("UseUnitItem");
 61             var UNIT = rule<NativeXUnit>("Unit");
 62 
 63             {
 64                 USE.Infer(
 65                     ID["UnitName"]
 66                     );
 67 
 68                 UNIT.Infer(
 69                     tok("unit"+ ID["Name"+ tok(";")
 70                     + opt(tok("uses"+ list<NativeXUses>(tok(","), USE)["UsesUnits"+ tok(";"))
 71                     + list<NativeXDeclaration>(DECLARATION)["Declarations"]
 72                     );
 73             }
 74             {
 75                 STRUCTURE_MEMBER.Infer(
 76                     TYPE["Type"+ ID["Name"]
 77                     );
 78 
 79                 INSTANCE_FUNCTION.Infer(
 80                     ID["Name"+ tok("="+ EXPRESSION["Expression"]
 81                     );
 82 
 83                 CONCEPT_FUNCTION.Infer(
 84                     ID["Name"+ tok("="+ TYPE["Type"]
 85                     );
 86 
 87                 GENERIC_PARAMETER.Infer(
 88                     ID["ParameterName"]
 89                     );
 90 
 91                 GENERIC_CONSTRAINT.Infer(
 92                     ID["ParameterName"+ tok(":"+ ID["ConceptName"]
 93                     );
 94 
 95                 LINKING.Infer(
 96                     tok("alias"+ ID["LinkingAssembly"+ tok("."+ ID["LinkingSymbol"]
 97                     );
 98             }
 99             {
100                 FUNCTION_DECLARATION.Infer(
101                     opt(tok("foreign")["Foreign""true"])
102                     + tok("function"+ TYPE["ReturnType"+ ID["Name"+ tok("("+ list<NativeXNameTypePair>(tok(","), STRUCTURE_MEMBER)["Parameters"+ tok(")")
103                     + opt(LINKING["Linking"])
104                     + (tok(";"| STATEMENT["Statement"])
105                     );
106 
107                 VARIABLE_DECLARATION.Infer(
108                     tok("variable"+ TYPE["Type"+ ID["Name"+ opt(LINKING["Linking"]) + opt(tok("="+ EXPRESSION["Initializer"]) + tok(";")
109                     );
110 
111                 TYPE_RENAME_DECLARATION.Infer(
112                     tok("type"+ ID["Name"+ tok("="+ TYPE["Type"+ tok(";")
113                     );
114 
115                 STRUCTURE_DECLARATION.Infer(
116                     tok("structure"+ ID["Name"]
117                     + (
118                         tok(";")
119                         | (
120                             opt(LINKING["Linking"]) + tok("{"+ list<NativeXNameTypePair>(ret(STRUCTURE_MEMBER) + tok(";"))["Members"+ tok("}")
121                           )
122                        )
123                     );
124 
125                 INSTANCE_DECLARATION.Infer(
126                     tok("instance"+ REFERENCE_TYPE["Type"+ tok(":"+ ID["ConceptName"]
127                     + (
128                         tok(";")
129                         | (
130                             tok("{"+ list<NativeXNameExpressionPair>(ret(INSTANCE_FUNCTION) + tok(";"))["Functions"+ tok("}")
131                           )
132                       )
133                     );
134 
135                 CONCEPT_DECLARATION.Infer(
136                     tok("concept"+ ID["ConceptType"+ tok(":"+ ID["Name"+ opt(LINKING["Linking"]) + tok("{"+ list<NativeXNameTypePair>(ret(CONCEPT_FUNCTION) + tok(";"))["Functions"+ tok("}")
137                     );
138             }
139             {
140                 NON_GENERIC_DECLARATION.Infer(
141                     ret(FUNCTION_DECLARATION)
142                     | ret(TYPE_RENAME_DECLARATION)
143                     | ret(VARIABLE_DECLARATION)
144                     | ret(STRUCTURE_DECLARATION)
145                     | ret(INSTANCE_DECLARATION)
146                     | ret(CONCEPT_DECLARATION)
147                     );
148 
149                 GENERIC_DECLARATION.Infer(
150                     tok("generic"+ tok("<"+ list<NativeXGenericParameter>(tok(","), GENERIC_PARAMETER)["GenericParameters"+ tok(">")
151                     + opt(tok("where"+ list<NativeXGenericConstraint>(tok(","), GENERIC_CONSTRAINT)["GenericConstraints"])
152                     + ret(NON_GENERIC_DECLARATION)
153                     );
154 
155                 DECLARATION.Infer(
156                     ret(GENERIC_DECLARATION) | ret(NON_GENERIC_DECLARATION)
157                     );
158             }
159             {
160                 EMPTY_STATEMENT.Infer(
161                     tok(";")
162                     );
163 
164                 EXPRESSION_STATEMENT.Infer(
165                     EXPRESSION["Expression"+ tok(";")
166                     );
167 
168                 VARIABLE_STATEMENT.Infer(
169                     tok("variable"+ TYPE["Type"+ ID["Name"+ opt(tok("="+ EXPRESSION["Initializer"]) + tok(";")
170                     );
171 
172                 IF_STATEMENT.Infer(
173                     tok("if"+ tok("("+ EXPRESSION["Condition"+ tok(")"+ STATEMENT["TrueStatement"+ opt(tok("else"+ STATEMENT["FalseStatement"])
174                     );
175 
176                 BREAK_STATEMENT.Infer(
177                     tok("break"+ tok(";")
178                     );
179 
180                 CONTINUE_STATEMENT.Infer(
181                     tok("continue"+ tok(";")
182                     );
183 
184                 EXIT_STATEMENT.Infer(
185                     tok("exit"+ tok(";")
186                     );
187 
188                 COMPOSITE_STATEMENT.Infer(
189                     tok("{"+ list<NativeXStatement>(STATEMENT)["Statements"+ tok("}")
190                     );
191 
192                 DO_WHILE_STATEMENT.Infer(
193                     tok("do"+ STATEMENT["Statement"+ tok("while"+ tok("("+ EXPRESSION["EndCondition"+ tok(")"+ tok(";")
194                     );
195 
196                 LOOP_STATEMENT.Infer(
197                     tok("loop"+ STATEMENT["Statement"]
198                     );
199 
200                 WHILE_DO_STATEMENT.Infer(
201                     tok("while"+ tok("("+ EXPRESSION["BeginCondition"+ tok(")"+ STATEMENT["Statement"+ opt(tok("when"+ tok("("+ EXPRESSION["EndCondition"+ tok(")"+ tok(";"))
202                     );
203 
204                 FOR_STATEMENT.Infer(
205                     tok("for"+ list<NativeXStatement>(STATEMENT)["Initializer"]
206                     + tok("when"+ tok("("+ EXPRESSION["Condition"+ tok(")")
207                     + tok("with"+ list<NativeXStatement>(STATEMENT)["SideEffect"]
208                     + tok("do"+ STATEMENT["Statement"]
209                     );
210 
211                 TRY_CATCH_STATEMENT.Infer(
212                     tok("try"+ STATEMENT["TryStatement"+ tok("catch"+ STATEMENT["CatchStatement"]
213                     );
214 
215                 THROW_STATEMENT.Infer(
216                     tok("throw"+ opt(EXPRESSION["ExceptionExpression"]) + tok(";")
217                     );
218 
219                 STATEMENT.Infer(
220                     ret(EMPTY_STATEMENT)
221                     | ret(VARIABLE_STATEMENT)
222                     | ret(IF_STATEMENT)
223                     | ret(BREAK_STATEMENT)
224                     | ret(CONTINUE_STATEMENT)
225                     | ret(EXIT_STATEMENT)
226                     | ret(COMPOSITE_STATEMENT)
227                     | ret(DO_WHILE_STATEMENT)
228                     | ret(LOOP_STATEMENT)
229                     | ret(WHILE_DO_STATEMENT)
230                     | ret(FOR_STATEMENT)
231                     | ret(TRY_CATCH_STATEMENT)
232                     | ret(THROW_STATEMENT)
233                     | ret(EXPRESSION_STATEMENT)
234                     );
235             }
236             {
237                 PRIMITIVE.Infer(
238                     STRING["Code"| NUMBER["Code"| toks("true""false""null")["Code"]
239                     );
240 
241                 INSTANCE_FUNCTION_REFERENCE.Infer(
242                     ID["ConceptName"+ tok("<"+ TYPE["Type"+ tok(">"+ tok(":"+ tok(":"+ ID["FunctionName"]
243                     );
244 
245                 INSTANCIATED_REFERENCE.Infer(
246                     ID["ReferencedName"+ tok("<"+ list<NativeXType>(tok(","), TYPE)["GenericArguments"+ tok(">")
247                     );
248 
249                 IDENTIFIER_REFERENCE.Infer(
250                     ID["ReferencedName"]
251                     );
252 
253                 REFERENCE.Infer(
254                     ret(INSTANCE_FUNCTION_REFERENCE) | ret(INSTANCIATED_REFERENCE) | ret(IDENTIFIER_REFERENCE)
255                     );
256 
257                 RESULT.Infer(
258                     tok("result")
259                     );
260 
261                 EXCEPTION.Infer(
262                     tok("exception")
263                     );
264 
265                 CAST.Infer(
266                     tok("cast"+ tok("<"+ TYPE["Type"+ tok(">"+ tok("("+ EXPRESSION["Operand"+ tok(")")
267                     );
268 
269                 EXP0.Infer(
270                     ret(RESULT) | ret(EXCEPTION) | ret(CAST) | ret(PRIMITIVE) | ret(REFERENCE) | tok("("+ ret(EXPRESSION) + tok(")")
271                     );
272 
273                 EXP1.Infer(
274                     ret(leftrecg(
275                             EXP0,
276                             g<NativeXSubscribeExpression>("Operand", tok("["+ EXPRESSION["Subscribe"+ tok("]")),
277                             g<NativeXInvokeExpression>("Function", tok("("+ list<NativeXExpression>(tok(","), EXPRESSION)["Arguments"+ tok(")")),
278                             g<NativeXMemberExpression>("Operand", tok("."+ ID["MemberName"]),
279                             g<NativeXPointerMemberExpression>("Operand", tok("->"+ ID["MemberName"]),
280                             g<NativeXPostUnaryExpression>("Operand", toks("++""--")["Operator"])
281                         ))
282                     );
283 
284                 UNARY.Infer(
285                     ((toks("++""--""&""*""-""!""~")["Operator"])) + EXP2["Operand"]
286                     );
287 
288                 EXP2.Infer(
289                     ret(EXP1) | ret(UNARY)
290                     );
291 
292                 {
293                     string[][] binaryOperators = new string[][]{
294                         new string[]{"*""/""%"},
295                         new string[]{"+""-"},
296                         new string[]{"<<"">>"},
297                         new string[]{"<""<="">"">="},
298                         new string[]{"==""!="},
299                         new string[]{"&"},
300                         new string[]{"^"},
301                         new string[]{"|"},
302                         new string[]{"&&"},
303                         new string[]{"||"},
304                         new string[]{"+=""-=""*=""/=""%=""<<="">>=""&=""/=""&&=""||=""="}
305                     };
306                     ParserNode shiftNode = (tok("<"+ tok("<"))["Operator""\"<<\""| (tok(">"+ tok(">"))["Operator""\">>\""];
307                     ParserNode[] operatorNodes = binaryOperators
308                         .Select(ops => ops.First() == "<<" ? shiftNode : toks(ops)["Operator"])
309                         .ToArray();
310                     ParserNode[] previousNode = new ParserNode[] { EXP2 }
311                         .Concat(EXP_BINS.Take(EXP_BINS.Length - 1))
312                         .ToArray();
313                     for (int i = 0; i < EXP_BINS.Length; i++)
314                     {
315                         EXP_BINS[i].Infer(
316                             ret(leftrec<NativeXBinaryExpression>(previousNode[i]["LeftOperand"], operatorNodes[i] + previousNode[i]["RightOperand"]))
317                             );
318                     }
319                 }
320 
321                 EXPRESSION.Infer(
322                     ret(EXP_BINS.Last())
323                     );
324             }
325             {
326                 REFERENCE_TYPE.Infer(
327                     ID["ReferencedName"]
328                     );
329 
330                 FUNCTION_TYPE.Infer(
331                     tok("function"+ TYPE["ReturnType"+ tok("("+ list<NativeXType>(tok(","), TYPE)["Parameters"+ tok(")")
332                     );
333 
334                 INSTANCIATED_TYPE.Infer(
335                     REFERENCE_TYPE["ElementType"+ tok("<"+ list<NativeXType>(tok(","), TYPE)["GenericArguments"+ tok(">")
336                     );
337 
338                 PRIMITIVE_TYPE.Infer(
339                     ret(FUNCTION_TYPE) | ret(INSTANCIATED_TYPE) | ret(REFERENCE_TYPE)
340                     );
341 
342                 TYPE.Infer(
343                     ret(leftrecg(
344                             PRIMITIVE_TYPE,
345                             g<NativeXPointerType>("ElementType", tok("*")),
346                             g<NativeXArrayType>("ElementType", tok("["+ PRIMITIVE["Size"+ tok("]"))
347                         ))
348                     );
349             }


    我们可以看出C++的编译器版本的文法注重分析的过程以及报告错误,而C#的IDE版本的文法注重如何构建树。C++版本的文法可以直接被执行(如同boost::spirit),而C#版本的文法是拿来生成语法分析器的代码的(如同yacc和antlr)。C#版本的文法虽然完整了,不过里面还没有容错的方法。一般来说容错有两种关键内容,分别是在遇到某些记号序列的时候强制分析下去(自动纠正错误),和在遇到某些记号序列的时候强制分析结束(譬如表达式遇到了“)”就肯定是要结束的了,如果出现“structure”就要直接回溯到最上层了,因为接下去就是structure的声明,函数都结束了……)。IDE版本的文法需要能够高度容错的原因是它分析的往往是写了一半的代码,而且还要在适当的时候能给出适当的提示,因此就要求这个语法分析器可以分析一些残缺不全的代码并且给出相应的残缺不全的语法树,但是结构必须是大体上正确才行。

    这一步研究结束之后,基本上IDE就只剩下界面的问题了。反正用一颗树来做语义分析已经是炉火纯青了,不过我们知道那些用来做智能提示的界面其实也不是那么好做的……
    接下来的研究重点就是如何将容错的具体方法在文法上表达出来,以及生成容错相关的代码了。
posted on 2010-10-23 12:34 陈梓瀚(vczh) 阅读(4920) 评论(4)  编辑 收藏 引用 所属分类: 开发自己的IDE

评论:
# re: 开发自己的IDE(八) 2010-10-23 18:04 | iloveprogramme
顶大师  回复  更多评论
  
# re: 开发自己的IDE(八) 2010-10-23 21:34 | 溪流
天书呀天书~~  回复  更多评论
  
# re: 开发自己的IDE(八) 2010-10-24 10:58 | zhaoyg
看不懂,但还是顶了  回复  更多评论
  
# re: 开发自己的IDE(八) 2010-10-25 22:23 | mm
好强大!!!  回复  更多评论
  

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理