IMPLEMENTATION MODULE LookAhead;
 
FROM YaflCreator IMPORT Creators;
FROM YaflError IMPORT MainErrorHandler;
FROM YaflExpressions IMPORT Expression;
FROM YaflIdentifiers IMPORT IdentList;
FROM YaflLiteral IMPORT StringLiteral, IntegerLiteral, RealLiteral;
FROM YaflQuantifiers IMPORT Quantifier;
FROM YaflMethods IMPORT Formal;
FROM YaflPreconditions IMPORT PreCondition, PostCondition,
                              ClassInvariant,    LoopInvariant,
                              PostExpression,    AssertionExpressionList, 
                              PostExpressionList,
                              OldExpression;
IMPORT YaflPragmas;
FROM Streams IMPORT StdOut;     
FROM YaflType IMPORT InstType;


   CLASS LookAhead;
     INHERITS LexicalAnalyzer;

     VAR
       Creator: ObjectCreator;
       ThePragmaCreator: PragmaCreator;

     METHOD AcceptPreCondition: PreCondition;
       BEGIN
       IF CurrentToken = Pre THEN
         RESULT := Creator.CreatePreCondition(LineNr, ColNr);
         RESULT.Parse(THIS);
         END;
       END AcceptPreCondition;
       
     METHOD AcceptIdent: YaflIdentifiers.Ident;
       BEGIN
       RESULT.CREATE(LineNr, ColNr, VOID);
       RESULT.Parse(THIS);
       END AcceptIdent;
       
     METHOD AcceptPostCondition: PostCondition;
       BEGIN
       IF CurrentToken = Post THEN
         RESULT := Creator.CreatePostCondition(LineNr, ColNr);
         RESULT.Parse(THIS);
         END;
       END AcceptPostCondition;
       
     METHOD AcceptClassInvariant: ClassInvariant;
       BEGIN
       Accept (Invariant);
       IF Ok THEN
         RESULT := Creator.CreateClassInvariant(LineNr, ColNr);
         RESULT.Parse(THIS);
         END;
       END AcceptClassInvariant;
     
     METHOD AcceptQuantifier(Context: INTEGER): Quantifier;
       BEGIN
       RESULT := Creator.CreateQuantifier (LineNr, ColNr, Context);
       RESULT.Parse (THIS);
       END AcceptQuantifier;
       
     METHOD AcceptLoopInvariant: LoopInvariant;
       BEGIN
       IF CurrentToken = Invariant THEN
         RESULT := Creator.CreateLoopInvariant(LineNr, ColNr);
         RESULT.Parse(THIS);
         END;
       END AcceptLoopInvariant;
       
--     METHOD AcceptInfExpressionList (TheFather: NonTerminal): InfExpressionList;
--       VAR
--         TheExpr: TypedNonTerminal;
--       BEGIN
--       RESULT := Creator.CreateInfExpressionList;
--       RESULT.SetFather(TheFather);
--       TheExpr := AcceptInfExpression (PreConditionContext);
--       RESULT.Append(TheExpr);
--       TheFather.SetSon(TheExpr);
--       WHILE CurrentToken = Comma DO
--         GetToken;
--         TheExpr := AcceptInfExpression (PreConditionContext);
--         RESULT.Append(TheExpr);
--         TheFather.SetSon(TheExpr);
--         END;
--       END AcceptInfExpressionList;
       
-- XXJC (d)
     METHOD AcceptAssertionExpressionList (TheFather: NonTerminal): AssertionExpressionList;
       VAR
         TheExpr: TypedNonTerminal;
       BEGIN
       RESULT := Creator.CreateAssertionExpressionList;
       RESULT.SetFather(TheFather);
       TheExpr := AcceptExpression (PreConditionContext);
       RESULT.Append(TheExpr);
       TheFather.SetSon(TheExpr);
       WHILE CurrentToken = Comma DO
         GetToken;
         TheExpr := AcceptExpression (PreConditionContext);
         RESULT.Append(TheExpr);
         TheFather.SetSon(TheExpr);
         END;
       END AcceptAssertionExpressionList;
-- END XXJC (d)

     METHOD AcceptPostExpressionList (TheFather: NonTerminal): PostExpressionList;
       VAR
         TheExpr: TypedNonTerminal;
       BEGIN
       RESULT := Creator.CreatePostExpressionList;
       RESULT.SetFather(TheFather);
       TheExpr := AcceptExpression(PostConditionContext);
       RESULT.Append(TheExpr);
       TheFather.SetSon(TheExpr);
       WHILE CurrentToken = Comma DO
         GetToken;                       
         TheExpr := AcceptExpression(PostConditionContext);
         RESULT.Append(TheExpr);
         TheFather.SetSon(TheExpr);
         END;
       END AcceptPostExpressionList;
       
     METHOD AcceptPlainExpr: TypedNonTerminal;
       BEGIN
       RESULT := AcceptExpression(PlainExpressionContext);
       END AcceptPlainExpr;

     METHOD AcceptExpression(Context: INTEGER): TypedNonTerminal;
        VAR
          Expr: Expression;
          St: INTEGER;
        BEGIN
        RESULT := AcceptComparativeExpr(Context);
        St := CurrentToken;
        WHILE ( St = LexicalAnalyzer.Implies) OR (St = LexicalAnalyzer.Iff) DO
          GetToken;
          Expr.CREATE(LineNr, ColNr, Context);
          Expr.Set (RESULT, St, AcceptComparativeExpr(Context));
          RESULT := Expr; 
          St := CurrentToken;
          END;
        END AcceptExpression;
        
      METHOD AcceptComparativeExpr(Context: INTEGER): TypedNonTerminal;
        VAR
          Expr: Expression;
          St: INTEGER;
        BEGIN
        RESULT := AcceptSimpleExpr(Context);
        St := CurrentToken;
        IF ( St >= LexicalAnalyzer.Equal ) AND
           ( St <= LexicalAnalyzer.NonEqual ) THEN
          GetToken;
          Expr.CREATE(LineNr, ColNr, Context);
          Expr.Set (RESULT, St, AcceptSimpleExpr(Context));
          RESULT := Expr;
          END;
        END AcceptComparativeExpr;

      METHOD AcceptSimpleExpr(Context: INTEGER): TypedNonTerminal;
        VAR
          Expr: Expression;
          St: INTEGER;
        BEGIN
        RESULT := AcceptTerm(Context);
        St := CurrentToken;
        WHILE (St = LexicalAnalyzer.Or) OR
              (St = LexicalAnalyzer.Plus) OR
              (St = LexicalAnalyzer.Minus) DO
          GetToken;
          Expr.CREATE(LineNr, ColNr, Context);
          Expr.Set(RESULT, St, AcceptTerm(Context));
          RESULT := Expr;
          St := CurrentToken;
          END;
        END AcceptSimpleExpr;

      METHOD AcceptTerm(Context: INTEGER): TypedNonTerminal;
        VAR
          Expr: Expression;
          St: INTEGER;
        BEGIN
        RESULT := AcceptFactor(Context);
        St := CurrentToken;
        WHILE (St = LexicalAnalyzer.Star) OR
              (St = LexicalAnalyzer.Slash) OR
              (St = LexicalAnalyzer.Mod) OR
              (St = LexicalAnalyzer.And) DO
          GetToken;
          Expr.CREATE(LineNr, ColNr, Context);
          Expr.Set (RESULT, St, AcceptFactor(Context));
          RESULT := Expr;
          St := CurrentToken;
          END;
        END AcceptTerm;

      METHOD AcceptFactor(Context: INTEGER): TypedNonTerminal;
        VAR
          Expr: Expression;
          TheOldExpr: OldExpression;
          St: INTEGER;
        BEGIN
        St := CurrentToken;
        CASE St OF
          LexicalAnalyzer.LeftParen:
            GetToken;
            RESULT := AcceptExpression(Context);
            Accept (LexicalAnalyzer.RightParen);
            END;
          LexicalAnalyzer.Minus:
            GetToken;
            Expr.CREATE(LineNr, ColNr, Context);
            Expr.Set (AcceptFactor(Context), St, VOID);
            RESULT := Expr;
            END;   
          LexicalAnalyzer.Old:
            TheOldExpr.CREATE(LineNr, ColNr, Context);
            TheOldExpr.Parse(THIS);
            RESULT := TheOldExpr;
            IF Context <> PostConditionContext THEN
              Error("OLD Expression Not Allowed in this context");
              END;
            END;   
          LexicalAnalyzer.Not:
            GetToken;
            Expr.CREATE(LineNr, ColNr, Context);
            Expr.Set (AcceptFactor(Context), St, VOID);
            RESULT := Expr;
            END;
          LexicalAnalyzer.Ident:
            RESULT := AcceptDesig(Context);
            END;
          LexicalAnalyzer.Integer, 
          LexicalAnalyzer.Real, 
          LexicalAnalyzer.StringToken:
            RESULT := AcceptLiteral(Context);
            END;
          LexicalAnalyzer.All,
          LexicalAnalyzer.ForAll,
          LexicalAnalyzer.ThereIs,
          LexicalAnalyzer.First,
          LexicalAnalyzer.Last:
            RESULT := AcceptQuantifier(Context);
            END;
         ELSE
          Error ("Factor expected");
          END;
        END AcceptFactor;

     METHOD AcceptLiteral(Context: INTEGER): TypedNonTerminal;
       BEGIN
       CASE CurrentToken OF
         Integer:      
           RESULT := Creators.Object.CreateIntegerLiteral (LineNr, ColNr, 
                                                           Context,
                                                           CurrentInteger);
           GetToken;
           END;
         Real:
           RESULT := Creators.Object.CreateRealLiteral (LineNr, ColNr, 
                                                           Context,
                                                           CurrentReal);
           GetToken;
           END;
         StringToken:
           RESULT := Creators.Object.CreateStringLiteral (LineNr, ColNr, 
                                                           Context,
                                                           CurrentString);
           GetToken;
           END;
        ELSE
         Error ("Literal expected");
         END;
       END AcceptLiteral;

     METHOD AcceptType: Type;
       VAR
         Tmp: InstType;
       BEGIN
       Tmp.CREATE(LineNr, ColNr);
       RESULT := Tmp;
       RESULT.Parse(THIS);
       END AcceptType;

     METHOD AcceptDefinitionModule:DefinitionModule;
       BEGIN
       RESULT := Creator.CreateDefinitionModule;
       RESULT.Parse(THIS);
       END AcceptDefinitionModule;

     METHOD AcceptImplementationModule:ImplementationModule;
       BEGIN
       RESULT := Creator.CreateImplementationModule;
       MainErrorHandler.SetRef (RESULT);
       RESULT.Parse(THIS);
       END AcceptImplementationModule;

     METHOD AcceptImplementationModuleImportList: ImportList;
       VAR
         ImpModule: ImplementationModule;
       BEGIN
       ImpModule := Creator.CreateImplementationModule;
       MainErrorHandler.SetRef (ImpModule);
       ImpModule.ParseUntilImportList(THIS);
       RESULT := ImpModule.GetImportList;
       END AcceptImplementationModuleImportList;

     METHOD AcceptImportList: ImportList;
       BEGIN
       RESULT := Creator.CreateImportList(LineNr, ColNr);
       RESULT.Parse (THIS);
       END AcceptImportList;

     METHOD AcceptImportClause: ImportClause;
       BEGIN
       RESULT.CREATE(LineNr, ColNr);
       RESULT.Parse(THIS);
       END AcceptImportClause;

     METHOD AcceptClassDefinition: ClassDefinition;
       BEGIN
       RESULT := Creator.CreateClassDefinition(LineNr, ColNr);
       RESULT.Parse(THIS);
       END AcceptClassDefinition;

     METHOD AcceptClassImplementation: ClassImplementation;
       BEGIN
       RESULT := Creator.CreateClassImplementation(LineNr, ColNr);
       RESULT.Parse(THIS);
       END AcceptClassImplementation;

     METHOD AcceptDeclaration(Implementation: BOOLEAN): DeclList;
       VAR
         St: INTEGER;
         Result: DeclList (Declaration);
       BEGIN
       Result.CREATE;
       St := CurrentToken;
       IF St <> LexicalAnalyzer.End THEN
         IF Implementation THEN
           CASE St OF
             LexicalAnalyzer.Const:
               RESULT := AcceptConstDeclarationList;
               END;
             LexicalAnalyzer.Var:
               RESULT := AcceptVarDeclaration;
               END;
             LexicalAnalyzer.Inline:
               Result.Append(AcceptInLineDeclaration);
               END;
             LexicalAnalyzer.PragmaToken:
               RESULT := AcceptPragmaList;
               END;
             LexicalAnalyzer.Once,
             LexicalAnalyzer.Class:
               Result.Append(AcceptClassImplementation);
               END;
             LexicalAnalyzer.Redefine,
             LexicalAnalyzer.Deferred,
             LexicalAnalyzer.Method:
               Result.Append(AcceptMethodImplementation);
               END;
             LexicalAnalyzer.Invariant,
             LexicalAnalyzer.Begin:
               -- nothing to do in this case
               END;
            ELSE
             Error("Declaration expected");
             END;
          ELSE
           CASE St OF
             LexicalAnalyzer.Once,
             LexicalAnalyzer.Class:
               Result.Append(AcceptClassDefinition);
               END;
             LexicalAnalyzer.Const:
               RESULT := AcceptConstDeclarationList;
               END;
             LexicalAnalyzer.PragmaToken:
               RESULT := AcceptPragmaList;
               END;
             LexicalAnalyzer.Redefine,
             LexicalAnalyzer.Deferred,
             LexicalAnalyzer.Method:
               Result.Append(AcceptMethodDefinition);
               END;
             LexicalAnalyzer.Invariant:
               -- nothing to do in this case
               END;
            ELSE
             Error("Declaration expected");
             END;
           END;
         END;
       IF RESULT = VOID THEN
         RESULT := Result;
         END;
       END AcceptDeclaration;

     METHOD AcceptDeclarationList (Implementation: BOOLEAN;
                                   Context: INTEGER): DeclList(Declaration);
       VAR
         GoOn: BOOLEAN;
         Decl: DeclList;
         BEGIN
       GoOn := TRUE;
       RESULT.CREATE;
       WHILE GoOn DO
         Decl := AcceptDeclaration (Implementation);
         FOR i := 0 TO Decl.Size - 1 DO
           RESULT.Append (Decl.Get(i));
           END;
         GoOn := (Decl.Size > 0) AND Ok;
         END;
       END AcceptDeclarationList;

     METHOD AcceptIdentList: YaflIdentifiers.IdentList;
       BEGIN
       RESULT.CREATE;
       RESULT.Append(AcceptIdent);
       WHILE CurrentToken = LexicalAnalyzer.Comma DO
         GetToken;
         RESULT.Append (AcceptIdent);
         END;
       END AcceptIdentList;

     METHOD AcceptQualIdent: YaflIdentifiers.QualIdent;
       BEGIN
       RESULT.CREATE(LineNr, ColNr);
       RESULT.Parse(THIS);
       END AcceptQualIdent;

     METHOD AcceptClassFormals: ClassFormalSet;
       BEGIN
       IF CurrentToken = LexicalAnalyzer.LeftParen THEN
         RESULT.CREATE(LineNr, ColNr);
         RESULT.Parse(THIS);
         END;
       END AcceptClassFormals;

     METHOD AcceptClassActuals: ClassActualSet;
       BEGIN
       IF CurrentToken = LexicalAnalyzer.LeftParen THEN
         RESULT.CREATE(LineNr, ColNr);
         RESULT.Parse(THIS);
         END;
       END AcceptClassActuals;

     METHOD AcceptStatement: Statement;
       VAR
         St: INTEGER;
         NTDesig: Desig;
         Assign: Assignment;
         MethInv: MethodInvStatement;
       BEGIN
       St := CurrentToken;
       CASE St OF
         LexicalAnalyzer.While:
           RESULT := AcceptLoopStatement;
           END;
         LexicalAnalyzer.If:
           RESULT := AcceptIfStatement;
           END;
         LexicalAnalyzer.For:
           RESULT := AcceptLoopStatement;
           END;
         LexicalAnalyzer.Case:
           RESULT := AcceptCaseStatement;
           END;
         LexicalAnalyzer.What:
           RESULT := AcceptWhatStatement;
           END;
         LexicalAnalyzer.Debug:
           RESULT := AcceptDebugStatement;
           END;
         LexicalAnalyzer.Assert:
           RESULT := AcceptAssertStatement;
           END;
         LexicalAnalyzer.Inline:
           RESULT := AcceptInLineStatement;
           END;
         LexicalAnalyzer.Ident:
           NTDesig := AcceptDesig (PlainExpressionContext);
           IF CurrentToken = LexicalAnalyzer.Becomes THEN

             -- Assignment
             GetToken;
             Assign.CREATE(LineNr, ColNr, NTDesig);
             Assign.ParseRightSide(THIS);
             RESULT := Assign;
            ELSE

             -- Method invocation
             MethInv.CREATE (LineNr, ColNr, NTDesig);
             MethInv.Parse(THIS);
             RESULT := MethInv;
             END;
           END;
        ELSE
         Accept(Ident);
         END;
       END AcceptStatement;

     METHOD AcceptIfAltList: NTList(IfAlt);
       BEGIN
       WHILE CurrentToken = LexicalAnalyzer.Elsif DO
         IF RESULT = VOID THEN
           RESULT.CREATE;
           END;
         RESULT.Append (AcceptIfAlt);
         END;
       END AcceptIfAltList;

     METHOD AcceptIfAlt: IfAlt;
       BEGIN
       RESULT.CREATE(LineNr, ColNr);
       RESULT.Parse(THIS);
       END AcceptIfAlt;

     METHOD AcceptElseAlt: StatementList;
       BEGIN
       IF CurrentToken = LexicalAnalyzer.Else THEN
         GetToken;
         RESULT := AcceptStatementList;
         END;
       END AcceptElseAlt;

     METHOD AcceptCaseAltList: NTList(CaseAlt);
       VAR
         St: INTEGER;
       BEGIN
       St := CurrentToken;
       WHILE Ok AND (St <> LexicalAnalyzer.Else)
                AND (St <> LexicalAnalyzer.End) DO
	 IF RESULT = VOID THEN
           RESULT.CREATE;
	   END;
         RESULT.Append (AcceptCaseAlt);
         St := CurrentToken;
         END;
       END AcceptCaseAltList;

     METHOD AcceptCaseAlt: CaseAlt;
       BEGIN
       RESULT.CREATE(LineNr, ColNr);
       RESULT.Parse(THIS);
       END AcceptCaseAlt;

     METHOD AcceptWhatAltList: NTList(WhatAlt);
       VAR
         St: INTEGER;
       BEGIN
       RESULT.CREATE;
       RESULT.Append (AcceptWhatAlt);
       St := CurrentToken;
       WHILE (St <> LexicalAnalyzer.Else) AND (St <> LexicalAnalyzer.End) AND
             Ok DO
         RESULT.Append (AcceptWhatAlt);
         St := CurrentToken;
         END;
       END AcceptWhatAltList;

     METHOD AcceptWhatAlt: WhatAlt;
       BEGIN
       RESULT.CREATE(LineNr, ColNr);
       RESULT.Parse(THIS);
       END AcceptWhatAlt;

     METHOD AcceptCaseTag: CaseTag;
       BEGIN
       RESULT.CREATE(LineNr, ColNr);
       RESULT.Parse(THIS);
       END AcceptCaseTag;

     METHOD AcceptBrExprList: ExpressionList;
       VAR
         Nt: TypedNonTerminal;
       BEGIN
       WHILE Ok AND (CurrentToken = LexicalAnalyzer.LeftBracket) DO
         IF RESULT = VOID THEN
           RESULT.CREATE;
           END;
         Nt := AcceptBrExpr;
         IF Nt <> VOID THEN
           RESULT.Append (Nt);
           END;
         END;
       END AcceptBrExprList;

     METHOD AcceptBrExpr: TypedNonTerminal;
       BEGIN
       Accept (LexicalAnalyzer.LeftBracket);
       RESULT := AcceptPlainExpr;
       Accept (LexicalAnalyzer.RightBracket);
       END AcceptBrExpr;

     METHOD AcceptDesigElement (Context: INTEGER): DesigElement;
       BEGIN
       RESULT := Creator.CreateDesigElement(LineNr, ColNr, Context);
       RESULT.Parse(THIS);
       END AcceptDesigElement;

     METHOD AcceptDesig (Context: INTEGER): Desig;
       BEGIN
       RESULT := Creator.CreateDesig(LineNr, ColNr, Context);
       RESULT.Parse(THIS);
       END AcceptDesig;
       
     METHOD AcceptSetSpecification: SetSpecification;
       BEGIN
       RESULT := Creator.CreateSetSpecification(LineNr, ColNr);
       RESULT.Parse (THIS);
       END AcceptSetSpecification;

   METHOD AcceptStatementList: StatementList;
     VAR
       St: INTEGER;
       Stmt: Statement;
     BEGIN
     St := CurrentToken;
     RESULT.CREATE(LineNr, ColNr);
     WHILE Ok AND (St <> LexicalAnalyzer.Else) AND (St <> LexicalAnalyzer.End)
              AND (St <> LexicalAnalyzer.Elsif) DO
       Stmt := AcceptStatement;
       IF Stmt <> VOID THEN
         RESULT.Append (Stmt);
         END;
       Accept (LexicalAnalyzer.SemiColon);
       St := CurrentToken;
       IF NOT Ok THEN
         GetToken;
         END;
       END;
     IF RESULT.Size = 0 THEN
       RESULT.Append(AcceptNopStatement);
       END;
     END AcceptStatementList;

     METHOD AcceptNopStatement: NopStatement;
       BEGIN
       RESULT.CREATE(LineNr, ColNr);
       RESULT.Parse(THIS);
       END AcceptNopStatement;

-- XXJC (d)
     METHOD AcceptActuals(Context: INTEGER): ActualList;
       BEGIN
       Accept (LexicalAnalyzer.LeftParen);
       RESULT.CREATE;
       RESULT.Append (AcceptActual(Context));
       WHILE Ok AND (CurrentToken = LexicalAnalyzer.Comma) DO
         GetToken;
         RESULT.Append (AcceptActual(Context));
         END;
       Accept (LexicalAnalyzer.RightParen);
       END AcceptActuals;

     METHOD AcceptActual(Context: INTEGER): Actual;
       BEGIN
       RESULT.CREATE(LineNr, ColNr, Context);
       RESULT.Parse(THIS);
       END AcceptActual;
-- END XXJC (d)

     METHOD AcceptMethodDefinition: MethodDefinition;
       BEGIN
       RESULT := Creator.CreateMethodDefinition(LineNr, ColNr);
       RESULT.Parse (THIS);
       END AcceptMethodDefinition;

     METHOD AcceptMethodImplementation: MethodImplementation;
       BEGIN
       RESULT := Creator.CreateMethodImplementation(LineNr, ColNr);
       RESULT.Parse (THIS);
       END AcceptMethodImplementation;

     METHOD AcceptLocals: DeclList (SingleDataItem);
       BEGIN
       RESULT := AcceptVarDeclaration;
       END AcceptLocals;

     METHOD AcceptFormalList: FormalList;
     
       METHOD AcceptBunch (Res: FormalList);
         VAR
           TheType: Type;
           Id: IdentList;
           TheFormal: Formal;
           BEGIN
         Id := AcceptIdentList;
         Accept (LexicalAnalyzer.Colon);
         TheType := AcceptType;
         IF Ok THEN
           FOR i := 0 TO Id.Size - 1 DO
             TheFormal.CREATE (Id.Get(i), 
                               TheType, 
                               ReadOnly := TRUE, 
                               Once := FALSE);
             Res.Append (TheFormal);           
             END;
           END;
         END AcceptBunch;
         
       BEGIN
       RESULT.CREATE;
       IF CurrentToken = LexicalAnalyzer.LeftParen THEN
         GetToken;
         AcceptBunch(RESULT);
         WHILE Ok AND (CurrentToken = LexicalAnalyzer.SemiColon) DO
           GetToken;
           AcceptBunch(RESULT);
           END;
         Accept (LexicalAnalyzer.RightParen);
         END;
       END AcceptFormalList;

     METHOD AcceptReturn: Type;
       BEGIN
       IF CurrentToken = LexicalAnalyzer.Colon THEN
         GetToken;
         RESULT := AcceptType;
         END;
       END AcceptReturn;

     METHOD AcceptConstDeclarationList: DeclList(ConstDeclaration);
       BEGIN
       Accept (LexicalAnalyzer.Const);
       RESULT.CREATE;
       WHILE Ok AND (CurrentToken = Ident) DO
         RESULT.Append (AcceptSingleConstDeclaration);
         END;
       END AcceptConstDeclarationList;

     METHOD AcceptSingleConstDeclaration: ConstDeclaration;
       BEGIN
       RESULT.CREATE(LineNr, ColNr);
       RESULT.Parse(THIS);
       END AcceptSingleConstDeclaration;
              
     METHOD AcceptPragma: Pragma;
       BEGIN
       IF CurrentToken = Ident THEN
         RESULT := ThePragmaCreator.CreatePragma (CurrentIdent, 
                                                  LineNr, ColNr);
         IF RESULT = VOID THEN
           RESULT.CREATE (LineNr, ColNr);
           END;
         RESULT.SetId (CurrentIdent);
         GetToken;
         RESULT.Parse(THIS);
        ELSE
         Accept (Ident); -- Generates an error message
         END;
       END AcceptPragma;

     METHOD AcceptPragmaList: DeclList(Pragma);
       BEGIN
       Accept (PragmaToken);
       RESULT.CREATE;
       WHILE Ok AND (CurrentToken = LexicalAnalyzer.Ident) DO
         RESULT.Append (AcceptPragma);
         END;
       END AcceptPragmaList;

     METHOD AcceptVarDeclaration: DeclList (SingleDataItem);
       VAR
         Id: IdentList;
         OnceFlag: BOOLEAN;
         Single: SingleDataItem;
         TheType: Type;
         BEGIN
       RESULT.CREATE;
       Accept (LexicalAnalyzer.Var);
       WHILE Ok AND (CurrentToken = LexicalAnalyzer.Ident) DO
         Id := AcceptIdentList;
         Accept (Colon);
         OnceFlag := CurrentToken = Once;
         IF OnceFlag THEN
           GetToken;
           END;
         TheType := AcceptType;
         FOR i := 0 TO Id.Size - 1 DO
           Single := Creator.CreateDataItem (Id.Get(i),
                                             TheType,
                                             ReadOnly := FALSE,
                                             OnceFlag);
           RESULT.Append (Single);
           END;
         Accept (SemiColon);
         END;
       END AcceptVarDeclaration;

     METHOD AcceptClassBody: StatementList;
       BEGIN
       IF CurrentToken = LexicalAnalyzer.Begin THEN
         GetToken;
         RESULT := AcceptStatementList;
         END;
       END AcceptClassBody;

     METHOD AcceptLoopStatement: LoopStatement;
       BEGIN
       RESULT.CREATE(LineNr, ColNr);
       RESULT.Parse (THIS);
       END AcceptLoopStatement;
       
     METHOD AcceptIfStatement: IfStatement;
       BEGIN
       RESULT.CREATE(LineNr, ColNr);
       RESULT.Parse (THIS);
       END AcceptIfStatement;

     METHOD AcceptCaseStatement: CaseStatement;
       BEGIN
       RESULT.CREATE(LineNr, ColNr);
       RESULT.Parse (THIS);
       END AcceptCaseStatement;

     METHOD AcceptWhatStatement: WhatStatement;
       BEGIN
       RESULT.CREATE(LineNr, ColNr);
       RESULT.Parse (THIS);
       END AcceptWhatStatement;

     METHOD AcceptDebugStatement: DebugStatement;
       BEGIN
       RESULT.CREATE(LineNr, ColNr);
       RESULT.Parse (THIS);
       END AcceptDebugStatement;

     METHOD AcceptAssertStatement: AssertStatement;
       BEGIN
       RESULT.CREATE(LineNr, ColNr);
       RESULT.Parse (THIS);
       END AcceptAssertStatement;

     METHOD AcceptInLineStatement: InLineStatement;
       BEGIN
       RESULT.CREATE(LineNr, ColNr);
       RESULT.Parse (THIS);
       END AcceptInLineStatement;

     METHOD AcceptInLineDeclaration: InLineDeclaration;
       BEGIN
       RESULT.CREATE(LineNr, ColNr);
       RESULT.Parse (THIS);
       END AcceptInLineDeclaration;

     REDEFINE METHOD CREATE(KeepComments: BOOLEAN);
       BEGIN
       BASE(KeepComments);                
       Creator := Creators.Object;
       ThePragmaCreator := Creators.Pragma;              
       END CREATE;

   END LookAhead;

END LookAhead;
