1 // THIS FILE IS GENERATED
2 // WARNING! All changes made in this file will be lost!
3 
4 #include "factparser.h"
5 
6 
7 #include "factlexer.h"
8 #include <QString>
9 #include <QDebug>
10 
11 namespace fact
12 {
13 
tokenize(const QString & contents)14 void Parser::tokenize( const QString& contents )
15 {
16     m_contents = contents;
17     Lexer lexer( this, contents );
18 
19     int kind = Parser::Token_EOF;
20     do
21     {
22         kind = lexer.nextTokenKind();
23 
24         if ( !kind ) // when the lexer returns 0, the end of file is reached
25             kind = Parser::Token_EOF;
26 
27         Parser::Token &t = tokenStream->next();
28         t.kind = kind;
29         if ( t.kind == Parser::Token_EOF )
30         {
31             t.begin = -1;
32             t.end = -1;
33         }
34         else
35         {
36             t.begin = lexer.tokenBegin();
37             t.end = lexer.tokenEnd();
38         }
39 
40         if ( m_debug )
41         {
42             qDebug() << kind << "(" << t.begin << "," << t.end << ")::" << tokenText(t.begin, t.end);
43         }
44 
45     }
46     while ( kind != Parser::Token_EOF );
47 
48     this->yylex(); // produce the look ahead token
49 }
50 
tokenText(qint64 begin,qint64 end) const51 QString Parser::tokenText( qint64 begin, qint64 end ) const
52 {
53     return m_contents.mid((int)begin, (int)end-begin+1);
54 }
55 
reportProblem(Parser::ProblemType type,const QString & message)56 void Parser::reportProblem( Parser::ProblemType type, const QString& message )
57 {
58     if (type == Error)
59         qDebug() << "** ERROR:" << message;
60     else if (type == Warning)
61         qDebug() << "** WARNING:" << message;
62     else if (type == Info)
63         qDebug() << "** Info:" << message;
64 }
65 
66 // custom error recovery
expectedToken(int,qint64,const QString & name)67 void Parser::expectedToken(int /*expected*/, qint64 /*where*/, const QString& name)
68 {
69     reportProblem(
70         Parser::Error,
71         QString("Expected token \"%1\"").arg(name));
72 }
73 
expectedSymbol(int,const QString & name)74 void Parser::expectedSymbol(int /*expected_symbol*/, const QString& name)
75 {
76     qint64 line;
77     qint64 col;
78     size_t index = tokenStream->index()-1;
79     Token &token = tokenStream->token(index);
80     qDebug() << "token starts at:" << token.begin;
81     qDebug() << "index is:" << index;
82     tokenStream->startPosition(index, &line, &col);
83     QString tokenValue = tokenText(token.begin, token.end);
84     reportProblem(
85         Parser::Error,
86         QString("Expected symbol \"%1\" (current token: \"%2\" [%3] at line: %4 col: %5)")
87         .arg(name)
88         .arg(token.kind != 0 ? tokenValue : "EOF")
89         .arg(token.kind)
90         .arg(line)
91         .arg(col));
92 }
93 
setDebug(bool debug)94 void Parser::setDebug( bool debug )
95 {
96     m_debug = debug;
97 }
98 
99 } // end of namespace fact
100 
101 
102 namespace fact
103 {
104 
parseAssignmentStatement(AssignmentStatementAst ** yynode)105 bool Parser::parseAssignmentStatement(AssignmentStatementAst **yynode)
106 {
107     *yynode = create<AssignmentStatementAst>();
108 
109     (*yynode)->startToken = tokenStream->index() - 1;
110     (*yynode)->id = -1;
111 
112     if (yytoken == Token_IDENTIFIER)
113     {
114         if (yytoken != Token_IDENTIFIER)
115         {
116             expectedToken(yytoken, Token_IDENTIFIER, "identifier");
117             return false;
118         }
119         (*yynode)->id = tokenStream->index() - 1;
120         yylex();
121 
122         if (yytoken != Token_ASSIGN)
123         {
124             expectedToken(yytoken, Token_ASSIGN, "=");
125             return false;
126         }
127         yylex();
128 
129         ExpressionAst *__node_0 = 0;
130         if (!parseExpression(&__node_0))
131         {
132             expectedSymbol(AstNode::ExpressionKind, "expression");
133             return false;
134         }
135         (*yynode)->expr = __node_0;
136 
137         if (yytoken != Token_SEMICOLON)
138         {
139             expectedToken(yytoken, Token_SEMICOLON, ";");
140             return false;
141         }
142         yylex();
143 
144     }
145     else
146     {
147         return false;
148     }
149 
150     (*yynode)->endToken = tokenStream->index() - 2;
151 
152     return true;
153 }
154 
parseBlockStatement(BlockStatementAst ** yynode)155 bool Parser::parseBlockStatement(BlockStatementAst **yynode)
156 {
157     *yynode = create<BlockStatementAst>();
158 
159     (*yynode)->startToken = tokenStream->index() - 1;
160 
161     if (yytoken == Token_LBRACE)
162     {
163         if (yytoken != Token_LBRACE)
164         {
165             expectedToken(yytoken, Token_LBRACE, "{");
166             return false;
167         }
168         yylex();
169 
170         while (yytoken == Token_IF
171                || yytoken == Token_IDENTIFIER
172                || yytoken == Token_RETURN
173                || yytoken == Token_LBRACE)
174         {
175             StatementAst *__node_1 = 0;
176             if (!parseStatement(&__node_1))
177             {
178                 expectedSymbol(AstNode::StatementKind, "statement");
179                 return false;
180             }
181             (*yynode)->stmtSequence = snoc((*yynode)->stmtSequence, __node_1, memoryPool);
182 
183         }
184         if (yytoken != Token_RBRACE)
185         {
186             expectedToken(yytoken, Token_RBRACE, "}");
187             return false;
188         }
189         yylex();
190 
191     }
192     else
193     {
194         return false;
195     }
196 
197     (*yynode)->endToken = tokenStream->index() - 2;
198 
199     return true;
200 }
201 
parseBody(BodyAst ** yynode)202 bool Parser::parseBody(BodyAst **yynode)
203 {
204     *yynode = create<BodyAst>();
205 
206     (*yynode)->startToken = tokenStream->index() - 1;
207 
208     if (yytoken == Token_LBRACE)
209     {
210         if (yytoken != Token_LBRACE)
211         {
212             expectedToken(yytoken, Token_LBRACE, "{");
213             return false;
214         }
215         yylex();
216 
217         while (yytoken == Token_VAR)
218         {
219             DeclarationAst *__node_2 = 0;
220             if (!parseDeclaration(&__node_2))
221             {
222                 expectedSymbol(AstNode::DeclarationKind, "declaration");
223                 return false;
224             }
225             (*yynode)->declSequence = snoc((*yynode)->declSequence, __node_2, memoryPool);
226 
227         }
228         while (yytoken == Token_IF
229                || yytoken == Token_IDENTIFIER
230                || yytoken == Token_RETURN
231                || yytoken == Token_LBRACE)
232         {
233             StatementAst *__node_3 = 0;
234             if (!parseStatement(&__node_3))
235             {
236                 expectedSymbol(AstNode::StatementKind, "statement");
237                 return false;
238             }
239             (*yynode)->stmtSequence = snoc((*yynode)->stmtSequence, __node_3, memoryPool);
240 
241         }
242         if (yytoken != Token_RBRACE)
243         {
244             expectedToken(yytoken, Token_RBRACE, "}");
245             return false;
246         }
247         yylex();
248 
249     }
250     else
251     {
252         return false;
253     }
254 
255     (*yynode)->endToken = tokenStream->index() - 2;
256 
257     return true;
258 }
259 
parseCondition(ConditionAst ** yynode)260 bool Parser::parseCondition(ConditionAst **yynode)
261 {
262     *yynode = create<ConditionAst>();
263 
264     (*yynode)->startToken = tokenStream->index() - 1;
265 
266     if (yytoken == Token_NUMBER
267         || yytoken == Token_IDENTIFIER)
268     {
269         ExpressionAst *__node_4 = 0;
270         if (!parseExpression(&__node_4))
271         {
272             expectedSymbol(AstNode::ExpressionKind, "expression");
273             return false;
274         }
275         (*yynode)->leftExpr = __node_4;
276 
277         if (yytoken != Token_EQUAL)
278         {
279             expectedToken(yytoken, Token_EQUAL, "==");
280             return false;
281         }
282         yylex();
283 
284         ExpressionAst *__node_5 = 0;
285         if (!parseExpression(&__node_5))
286         {
287             expectedSymbol(AstNode::ExpressionKind, "expression");
288             return false;
289         }
290         (*yynode)->rightExpr = __node_5;
291 
292     }
293     else
294     {
295         return false;
296     }
297 
298     (*yynode)->endToken = tokenStream->index() - 2;
299 
300     return true;
301 }
302 
parseDeclaration(DeclarationAst ** yynode)303 bool Parser::parseDeclaration(DeclarationAst **yynode)
304 {
305     *yynode = create<DeclarationAst>();
306 
307     (*yynode)->startToken = tokenStream->index() - 1;
308 
309     if (yytoken == Token_VAR)
310     {
311         if (yytoken != Token_VAR)
312         {
313             expectedToken(yytoken, Token_VAR, "var");
314             return false;
315         }
316         yylex();
317 
318         VariableAst *__node_6 = 0;
319         if (!parseVariable(&__node_6))
320         {
321             expectedSymbol(AstNode::VariableKind, "variable");
322             return false;
323         }
324         (*yynode)->var = __node_6;
325 
326         while (yytoken == Token_COMMA)
327         {
328             if (yytoken != Token_COMMA)
329             {
330                 expectedToken(yytoken, Token_COMMA, ",");
331                 return false;
332             }
333             yylex();
334 
335             VariableAst *__node_7 = 0;
336             if (!parseVariable(&__node_7))
337             {
338                 expectedSymbol(AstNode::VariableKind, "variable");
339                 return false;
340             }
341             (*yynode)->var = __node_7;
342 
343         }
344         if (yytoken != Token_SEMICOLON)
345         {
346             expectedToken(yytoken, Token_SEMICOLON, ";");
347             return false;
348         }
349         yylex();
350 
351     }
352     else
353     {
354         return false;
355     }
356 
357     (*yynode)->endToken = tokenStream->index() - 2;
358 
359     return true;
360 }
361 
parseExpression(ExpressionAst ** yynode)362 bool Parser::parseExpression(ExpressionAst **yynode)
363 {
364     *yynode = create<ExpressionAst>();
365 
366     (*yynode)->startToken = tokenStream->index() - 1;
367 
368     if (yytoken == Token_NUMBER
369         || yytoken == Token_IDENTIFIER)
370     {
371         MultExpressionAst *__node_8 = 0;
372         if (!parseMultExpression(&__node_8))
373         {
374             expectedSymbol(AstNode::MultExpressionKind, "multExpression");
375             return false;
376         }
377         (*yynode)->leftExpr = __node_8;
378 
379         while (yytoken == Token_MINUS)
380         {
381             if (yytoken != Token_MINUS)
382             {
383                 expectedToken(yytoken, Token_MINUS, "-");
384                 return false;
385             }
386             yylex();
387 
388             MultExpressionAst *__node_9 = 0;
389             if (!parseMultExpression(&__node_9))
390             {
391                 expectedSymbol(AstNode::MultExpressionKind, "multExpression");
392                 return false;
393             }
394             (*yynode)->rightExpr = __node_9;
395 
396         }
397     }
398     else
399     {
400         return false;
401     }
402 
403     (*yynode)->endToken = tokenStream->index() - 2;
404 
405     return true;
406 }
407 
parseFunctionDefinition(FunctionDefinitionAst ** yynode)408 bool Parser::parseFunctionDefinition(FunctionDefinitionAst **yynode)
409 {
410     *yynode = create<FunctionDefinitionAst>();
411 
412     (*yynode)->startToken = tokenStream->index() - 1;
413     (*yynode)->id = -1;
414 
415     if (yytoken == Token_FUNCTION)
416     {
417         if (yytoken != Token_FUNCTION)
418         {
419             expectedToken(yytoken, Token_FUNCTION, "function");
420             return false;
421         }
422         yylex();
423 
424         if (yytoken != Token_IDENTIFIER)
425         {
426             expectedToken(yytoken, Token_IDENTIFIER, "identifier");
427             return false;
428         }
429         (*yynode)->id = tokenStream->index() - 1;
430         yylex();
431 
432         if (yytoken != Token_LPAREN)
433         {
434             expectedToken(yytoken, Token_LPAREN, "(");
435             return false;
436         }
437         yylex();
438 
439         if (yytoken == Token_IDENTIFIER)
440         {
441             if (yytoken != Token_IDENTIFIER)
442             {
443                 expectedToken(yytoken, Token_IDENTIFIER, "identifier");
444                 return false;
445             }
446             (*yynode)->paramSequence = snoc((*yynode)->paramSequence, tokenStream->index() - 1, memoryPool);
447             yylex();
448 
449             while (yytoken == Token_COMMA)
450             {
451                 if (yytoken != Token_COMMA)
452                 {
453                     expectedToken(yytoken, Token_COMMA, ",");
454                     return false;
455                 }
456                 yylex();
457 
458                 if (yytoken != Token_IDENTIFIER)
459                 {
460                     expectedToken(yytoken, Token_IDENTIFIER, "identifier");
461                     return false;
462                 }
463                 (*yynode)->paramSequence = snoc((*yynode)->paramSequence, tokenStream->index() - 1, memoryPool);
464                 yylex();
465 
466             }
467         }
468         else if (true /*epsilon*/)
469         {
470         }
471         else
472         {
473             return false;
474         }
475         if (yytoken != Token_RPAREN)
476         {
477             expectedToken(yytoken, Token_RPAREN, ")");
478             return false;
479         }
480         yylex();
481 
482         BodyAst *__node_10 = 0;
483         if (!parseBody(&__node_10))
484         {
485             expectedSymbol(AstNode::BodyKind, "body");
486             return false;
487         }
488         (*yynode)->body = __node_10;
489 
490     }
491     else
492     {
493         return false;
494     }
495 
496     (*yynode)->endToken = tokenStream->index() - 2;
497 
498     return true;
499 }
500 
parseIfStatement(IfStatementAst ** yynode)501 bool Parser::parseIfStatement(IfStatementAst **yynode)
502 {
503     *yynode = create<IfStatementAst>();
504 
505     (*yynode)->startToken = tokenStream->index() - 1;
506 
507     if (yytoken == Token_IF)
508     {
509         if (yytoken != Token_IF)
510         {
511             expectedToken(yytoken, Token_IF, "if");
512             return false;
513         }
514         yylex();
515 
516         if (yytoken != Token_LPAREN)
517         {
518             expectedToken(yytoken, Token_LPAREN, "(");
519             return false;
520         }
521         yylex();
522 
523         ConditionAst *__node_11 = 0;
524         if (!parseCondition(&__node_11))
525         {
526             expectedSymbol(AstNode::ConditionKind, "condition");
527             return false;
528         }
529         (*yynode)->cond = __node_11;
530 
531         if (yytoken != Token_RPAREN)
532         {
533             expectedToken(yytoken, Token_RPAREN, ")");
534             return false;
535         }
536         yylex();
537 
538         StatementAst *__node_12 = 0;
539         if (!parseStatement(&__node_12))
540         {
541             expectedSymbol(AstNode::StatementKind, "statement");
542             return false;
543         }
544         (*yynode)->ifStmt = __node_12;
545 
546         if (yytoken == Token_ELSE)
547         {
548             if (yytoken != Token_ELSE)
549             {
550                 expectedToken(yytoken, Token_ELSE, "else");
551                 return false;
552             }
553             yylex();
554 
555             StatementAst *__node_13 = 0;
556             if (!parseStatement(&__node_13))
557             {
558                 expectedSymbol(AstNode::StatementKind, "statement");
559                 return false;
560             }
561             (*yynode)->elseStmt = __node_13;
562 
563         }
564         else if (true /*epsilon*/)
565         {
566         }
567         else
568         {
569             return false;
570         }
571     }
572     else
573     {
574         return false;
575     }
576 
577     (*yynode)->endToken = tokenStream->index() - 2;
578 
579     return true;
580 }
581 
parseMultExpression(MultExpressionAst ** yynode)582 bool Parser::parseMultExpression(MultExpressionAst **yynode)
583 {
584     *yynode = create<MultExpressionAst>();
585 
586     (*yynode)->startToken = tokenStream->index() - 1;
587 
588     if (yytoken == Token_NUMBER
589         || yytoken == Token_IDENTIFIER)
590     {
591         PrimaryAst *__node_14 = 0;
592         if (!parsePrimary(&__node_14))
593         {
594             expectedSymbol(AstNode::PrimaryKind, "primary");
595             return false;
596         }
597         (*yynode)->leftExpr = __node_14;
598 
599         while (yytoken == Token_STAR)
600         {
601             if (yytoken != Token_STAR)
602             {
603                 expectedToken(yytoken, Token_STAR, "*");
604                 return false;
605             }
606             yylex();
607 
608             PrimaryAst *__node_15 = 0;
609             if (!parsePrimary(&__node_15))
610             {
611                 expectedSymbol(AstNode::PrimaryKind, "primary");
612                 return false;
613             }
614             (*yynode)->rightExpr = __node_15;
615 
616         }
617     }
618     else
619     {
620         return false;
621     }
622 
623     (*yynode)->endToken = tokenStream->index() - 2;
624 
625     return true;
626 }
627 
parsePrimary(PrimaryAst ** yynode)628 bool Parser::parsePrimary(PrimaryAst **yynode)
629 {
630     *yynode = create<PrimaryAst>();
631 
632     (*yynode)->startToken = tokenStream->index() - 1;
633     (*yynode)->num = -1;
634     (*yynode)->id = -1;
635 
636     if (yytoken == Token_NUMBER
637         || yytoken == Token_IDENTIFIER)
638     {
639         if (yytoken == Token_NUMBER)
640         {
641             if (yytoken != Token_NUMBER)
642             {
643                 expectedToken(yytoken, Token_NUMBER, "integer literal");
644                 return false;
645             }
646             (*yynode)->num = tokenStream->index() - 1;
647             yylex();
648 
649         }
650         else if (yytoken == Token_IDENTIFIER)
651         {
652             if (yytoken != Token_IDENTIFIER)
653             {
654                 expectedToken(yytoken, Token_IDENTIFIER, "identifier");
655                 return false;
656             }
657             (*yynode)->id = tokenStream->index() - 1;
658             yylex();
659 
660             if (yytoken == Token_LPAREN)
661             {
662                 if (yytoken != Token_LPAREN)
663                 {
664                     expectedToken(yytoken, Token_LPAREN, "(");
665                     return false;
666                 }
667                 yylex();
668 
669                 ExpressionAst *__node_16 = 0;
670                 if (!parseExpression(&__node_16))
671                 {
672                     expectedSymbol(AstNode::ExpressionKind, "expression");
673                     return false;
674                 }
675                 (*yynode)->argumentSequence = snoc((*yynode)->argumentSequence, __node_16, memoryPool);
676 
677                 while (yytoken == Token_COMMA)
678                 {
679                     if (yytoken != Token_COMMA)
680                     {
681                         expectedToken(yytoken, Token_COMMA, ",");
682                         return false;
683                     }
684                     yylex();
685 
686                     ExpressionAst *__node_17 = 0;
687                     if (!parseExpression(&__node_17))
688                     {
689                         expectedSymbol(AstNode::ExpressionKind, "expression");
690                         return false;
691                     }
692                     (*yynode)->argumentSequence = snoc((*yynode)->argumentSequence, __node_17, memoryPool);
693 
694                 }
695                 if (yytoken != Token_RPAREN)
696                 {
697                     expectedToken(yytoken, Token_RPAREN, ")");
698                     return false;
699                 }
700                 yylex();
701 
702             }
703             else if (true /*epsilon*/)
704             {
705             }
706             else
707             {
708                 return false;
709             }
710         }
711         else
712         {
713             return false;
714         }
715     }
716     else
717     {
718         return false;
719     }
720 
721     (*yynode)->endToken = tokenStream->index() - 2;
722 
723     return true;
724 }
725 
parseProgram(ProgramAst ** yynode)726 bool Parser::parseProgram(ProgramAst **yynode)
727 {
728     *yynode = create<ProgramAst>();
729 
730     (*yynode)->startToken = tokenStream->index() - 1;
731 
732     if (yytoken == Token_FUNCTION || yytoken == Token_EOF)
733     {
734         while (yytoken == Token_FUNCTION)
735         {
736             FunctionDefinitionAst *__node_18 = 0;
737             if (!parseFunctionDefinition(&__node_18))
738             {
739                 expectedSymbol(AstNode::FunctionDefinitionKind, "functionDefinition");
740                 return false;
741             }
742             (*yynode)->funSequence = snoc((*yynode)->funSequence, __node_18, memoryPool);
743 
744         }
745         if (Token_EOF != yytoken)
746         {
747             return false;
748         }
749     }
750     else
751     {
752         return false;
753     }
754 
755     (*yynode)->endToken = tokenStream->index() - 2;
756 
757     return true;
758 }
759 
parseReturnStatement(ReturnStatementAst ** yynode)760 bool Parser::parseReturnStatement(ReturnStatementAst **yynode)
761 {
762     *yynode = create<ReturnStatementAst>();
763 
764     (*yynode)->startToken = tokenStream->index() - 1;
765 
766     if (yytoken == Token_RETURN)
767     {
768         if (yytoken != Token_RETURN)
769         {
770             expectedToken(yytoken, Token_RETURN, "return");
771             return false;
772         }
773         yylex();
774 
775         ExpressionAst *__node_19 = 0;
776         if (!parseExpression(&__node_19))
777         {
778             expectedSymbol(AstNode::ExpressionKind, "expression");
779             return false;
780         }
781         (*yynode)->expr = __node_19;
782 
783         if (yytoken != Token_SEMICOLON)
784         {
785             expectedToken(yytoken, Token_SEMICOLON, ";");
786             return false;
787         }
788         yylex();
789 
790     }
791     else
792     {
793         return false;
794     }
795 
796     (*yynode)->endToken = tokenStream->index() - 2;
797 
798     return true;
799 }
800 
parseStatement(StatementAst ** yynode)801 bool Parser::parseStatement(StatementAst **yynode)
802 {
803     *yynode = create<StatementAst>();
804 
805     (*yynode)->startToken = tokenStream->index() - 1;
806 
807     if (yytoken == Token_IF
808         || yytoken == Token_IDENTIFIER
809         || yytoken == Token_RETURN
810         || yytoken == Token_LBRACE)
811     {
812         if (yytoken == Token_IDENTIFIER)
813         {
814             AssignmentStatementAst *__node_20 = 0;
815             if (!parseAssignmentStatement(&__node_20))
816             {
817                 expectedSymbol(AstNode::AssignmentStatementKind, "assignmentStatement");
818                 return false;
819             }
820             (*yynode)->assignStmt = __node_20;
821 
822         }
823         else if (yytoken == Token_IF)
824         {
825             IfStatementAst *__node_21 = 0;
826             if (!parseIfStatement(&__node_21))
827             {
828                 expectedSymbol(AstNode::IfStatementKind, "ifStatement");
829                 return false;
830             }
831             (*yynode)->ifStmt = __node_21;
832 
833         }
834         else if (yytoken == Token_LBRACE)
835         {
836             BlockStatementAst *__node_22 = 0;
837             if (!parseBlockStatement(&__node_22))
838             {
839                 expectedSymbol(AstNode::BlockStatementKind, "blockStatement");
840                 return false;
841             }
842             (*yynode)->blockStmt = __node_22;
843 
844         }
845         else if (yytoken == Token_RETURN)
846         {
847             ReturnStatementAst *__node_23 = 0;
848             if (!parseReturnStatement(&__node_23))
849             {
850                 expectedSymbol(AstNode::ReturnStatementKind, "returnStatement");
851                 return false;
852             }
853             (*yynode)->returnStmt = __node_23;
854 
855         }
856         else
857         {
858             return false;
859         }
860     }
861     else
862     {
863         return false;
864     }
865 
866     (*yynode)->endToken = tokenStream->index() - 2;
867 
868     return true;
869 }
870 
parseVariable(VariableAst ** yynode)871 bool Parser::parseVariable(VariableAst **yynode)
872 {
873     *yynode = create<VariableAst>();
874 
875     (*yynode)->startToken = tokenStream->index() - 1;
876     (*yynode)->id = -1;
877 
878     if (yytoken == Token_IDENTIFIER)
879     {
880         if (yytoken != Token_IDENTIFIER)
881         {
882             expectedToken(yytoken, Token_IDENTIFIER, "identifier");
883             return false;
884         }
885         (*yynode)->id = tokenStream->index() - 1;
886         yylex();
887 
888     }
889     else
890     {
891         return false;
892     }
893 
894     (*yynode)->endToken = tokenStream->index() - 2;
895 
896     return true;
897 }
898 
899 
900 } // end of namespace fact
901 
902