internal IAnalysisResult TryGetUserDefinedType(string typeName, int index)
        {
            // do a binary search to determine what node we're in
            IAnalysisResult type = null;

            _body.SetNamespace(null);
            // TODO: need to handle multiple results of the same name
            AstNode containingNode = GetContainingNode(_body, index);

            if (containingNode != null)
            {
                if (containingNode is IFunctionResult)
                {
                    if ((containingNode as IFunctionResult).Types.TryGetValue(typeName, out type))
                    {
                        return(type);
                    }
                }

                if (_body is IModuleResult)
                {
                    if ((_body as IModuleResult).Types.TryGetValue(typeName, out type) ||
                        (_body as IModuleResult).GlobalTypes.TryGetValue(typeName, out type))
                    {
                        return(type);
                    }
                }
            }

            // TODO: this could probably be done more efficiently by having each GeneroAst load globals and functions into
            // dictionaries stored on the IGeneroProject, instead of in each project entry.
            // However, this does required more upkeep when changes occur. Will look into it...
            if (_projEntry != null && _projEntry is IGeneroProjectEntry)
            {
                IGeneroProjectEntry genProj = _projEntry as IGeneroProjectEntry;
                if (genProj.ParentProject != null)
                {
                    foreach (var projEntry in genProj.ParentProject.ProjectEntries.Where(x => x.Value != genProj))
                    {
                        if (projEntry.Value.Analysis != null &&
                            projEntry.Value.Analysis.Body != null)
                        {
                            projEntry.Value.Analysis.Body.SetNamespace(null);
                            IModuleResult modRes = projEntry.Value.Analysis.Body as IModuleResult;
                            if (modRes != null)
                            {
                                // check global types

                                if (modRes.GlobalTypes.TryGetValue(typeName, out type))
                                {
                                    return(type);
                                }
                            }
                        }
                    }
                }
            }

            return(type);
        }
Ejemplo n.º 2
0
        public static bool TryParseNode(Genero4glParser parser, out OtherwiseStatement node,
                                        IModuleResult containingModule,
                                        List <Func <PrepareStatement, bool> > prepStatementBinders,
                                        Func <ReturnStatement, ParserResult> returnStatementBinder   = null,
                                        Action <IAnalysisResult, int, int> limitedScopeVariableAdder = null,
                                        List <TokenKind> validExitKeywords = null,
                                        IEnumerable <ContextStatementFactory> contextStatementFactories = null,
                                        ExpressionParsingOptions expressionOptions = null,
                                        HashSet <TokenKind> endKeywords            = null)
        {
            node = null;
            bool result = false;

            if (parser.PeekToken(TokenKind.OtherwiseKeyword))
            {
                result = true;
                node   = new OtherwiseStatement();
                parser.NextToken();
                node.StartIndex   = parser.Token.Span.Start;
                node.DecoratorEnd = parser.Token.Span.End;
                prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier);
                while (!parser.PeekToken(TokenKind.EndOfFile) &&
                       !parser.PeekToken(TokenKind.WhenKeyword) &&
                       !parser.PeekToken(TokenKind.OtherwiseKeyword) &&
                       !(parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.CaseKeyword, 2)))
                {
                    FglStatement statement;
                    if (parser.StatementFactory.TryParseNode(parser, out statement, containingModule, prepStatementBinders, returnStatementBinder,
                                                             limitedScopeVariableAdder, false, validExitKeywords, contextStatementFactories, expressionOptions) &&
                        statement != null)
                    {
                        AstNode4gl stmtNode = statement as AstNode4gl;
                        node.Children.Add(stmtNode.StartIndex, stmtNode);

                        if (statement is ExitStatement &&
                            (statement as ExitStatement).ExitType != TokenKind.CaseKeyword)
                        {
                            if (validExitKeywords != null && !validExitKeywords.Contains((statement as ExitStatement).ExitType))
                            {
                                parser.ReportSyntaxError("Invalid exit statement for case statement block detected.");
                            }
                        }
                    }
                    else if (parser.PeekToken(TokenKind.EndKeyword) && endKeywords != null && endKeywords.Contains(parser.PeekToken(2).Kind))
                    {
                        break;
                    }
                    else
                    {
                        parser.NextToken();
                    }
                }
                prepStatementBinders.RemoveAt(0);

                node.EndIndex = parser.Token.Span.End;
            }

            return(result);
        }
Ejemplo n.º 3
0
        internal IAnalysisResult GetMemberOfType(string name, object ast, bool vars, bool types, bool consts, bool funcs, out IProjectEntry definingProjEntry)
        {
            string projNamespace = string.Format("{0}", this.Name);
            string tempStart     = string.Format("{0}.", projNamespace);

            if (name.StartsWith(tempStart, StringComparison.OrdinalIgnoreCase))
            {
                name = name.Substring(tempStart.Length);
            }

            definingProjEntry = null;
            IAnalysisResult res = null;

            foreach (var projEntry in ProjectEntries)
            {
                if (projEntry.Value.Analysis != null &&
                    projEntry.Value.Analysis.Body != null)
                {
                    projEntry.Value.Analysis.Body.SetNamespace(projNamespace);
                    IModuleResult modRes = projEntry.Value.Analysis.Body as IModuleResult;
                    if (modRes != null)
                    {
                        // check global vars, types, and constants
                        if ((vars && modRes.GlobalVariables.TryGetValue(name, out res)) ||
                            (types && modRes.GlobalTypes.TryGetValue(name, out res)) ||
                            (consts && modRes.GlobalConstants.TryGetValue(name, out res)))
                        {
                            //found = true;
                            definingProjEntry = projEntry.Value;
                            break;
                        }

                        if (((vars && modRes.Variables.TryGetValue(name, out res)) ||
                             (types && modRes.Types.TryGetValue(name, out res)) ||
                             (consts && modRes.Constants.TryGetValue(name, out res))) && res.IsPublic)
                        {
                            definingProjEntry = projEntry.Value;
                            break;
                        }

                        // check project functions
                        IFunctionResult funcRes = null;
                        if (funcs && modRes.Functions.TryGetValue(name, out funcRes))
                        {
                            if (funcRes.AccessModifier == AccessModifier.Public)
                            {
                                res = funcRes;
                                //found = true;
                                definingProjEntry = projEntry.Value;
                                break;
                            }
                        }
                    }
                }
            }
            return(res);
        }
Ejemplo n.º 4
0
        public IEnumerable <MemberResult> GetMembers(GetMultipleMembersInput input)
        {
            string projNamespace        = string.Format("{0}", this.Name);
            List <MemberResult> members = new List <MemberResult>();

            foreach (var projEntry in ProjectEntries)
            {
                if (projEntry.Value.Analysis != null &&
                    projEntry.Value.Analysis.Body != null)
                {
                    projEntry.Value.Analysis.Body.SetNamespace(projNamespace);
                    IModuleResult modRes = projEntry.Value.Analysis.Body as IModuleResult;
                    if (modRes != null)
                    {
                        if (input.MemberType.HasFlag(MemberType.Variables))
                        {
                            members.AddRange(modRes.GlobalVariables.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, input.AST)));
                            members.AddRange(modRes.Variables.Where(x => x.Value.IsPublic).Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, input.AST)));
                            members.AddRange(projEntry.Value.GetIncludedFiles().Where(x => x.Analysis != null).SelectMany(x => x.Analysis.GetDefinedMembers(1, AstMemberType.Variables, input.IsMemberAccess)));
                        }

                        if (input.MemberType.HasFlag(MemberType.Types))
                        {
                            members.AddRange(modRes.GlobalTypes.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Class, input.AST)));
                            members.AddRange(modRes.Types.Where(x => x.Value.IsPublic).Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Class, input.AST)));
                            members.AddRange(projEntry.Value.GetIncludedFiles().Where(x => x.Analysis != null).SelectMany(x => x.Analysis.GetDefinedMembers(1, AstMemberType.UserDefinedTypes, input.IsMemberAccess)));
                        }

                        if (input.MemberType.HasFlag(MemberType.Constants))
                        {
                            members.AddRange(modRes.GlobalConstants.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Constant, input.AST)));
                            members.AddRange(modRes.Constants.Where(x => x.Value.IsPublic).Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Constant, input.AST)));
                            members.AddRange(projEntry.Value.GetIncludedFiles().Where(x => x.Analysis != null).SelectMany(x => x.Analysis.GetDefinedMembers(1, AstMemberType.Constants, input.IsMemberAccess)));
                        }

                        if (input.MemberType.HasFlag(MemberType.Functions))
                        {
                            members.AddRange(modRes.Functions.Where(x => x.Value.IsPublic).Select(x => new MemberResult(x.Key, x.Value, x.Value.FunctionType, input.AST)));
                            members.AddRange(projEntry.Value.GetIncludedFiles().Where(x => x.Analysis != null).SelectMany(x => x.Analysis.GetDefinedMembers(1, AstMemberType.Functions, input.IsMemberAccess)));
                        }
                    }
                }
            }

            return(members);
        }
Ejemplo n.º 5
0
        public static bool TryParseNode(Genero4glParser parser, out IfBlockContentsNode node,
                                        IModuleResult containingModule,
                                        List <Func <PrepareStatement, bool> > prepStatementBinders,
                                        Func <ReturnStatement, ParserResult> returnStatementBinder   = null,
                                        Action <IAnalysisResult, int, int> limitedScopeVariableAdder = null,
                                        List <TokenKind> validExitKeywords = null,
                                        IEnumerable <ContextStatementFactory> contextStatementFactories = null,
                                        ExpressionParsingOptions expressionOptions = null,
                                        HashSet <TokenKind> endKeywords            = null)
        {
            node            = new IfBlockContentsNode();
            node.StartIndex = parser.Token.Span.Start;
            prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier);
            while (!parser.PeekToken(TokenKind.EndOfFile) &&
                   !parser.PeekToken(TokenKind.ElseKeyword) &&
                   !(parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.IfKeyword, 2)))
            {
                FglStatement statement;
                if (parser.StatementFactory.TryParseNode(parser, out statement, containingModule, prepStatementBinders,
                                                         returnStatementBinder, limitedScopeVariableAdder, false, validExitKeywords,
                                                         contextStatementFactories, expressionOptions, endKeywords))
                {
                    AstNode4gl stmtNode = statement as AstNode4gl;
                    if (stmtNode != null && !node.Children.ContainsKey(stmtNode.StartIndex))
                    {
                        node.Children.Add(stmtNode.StartIndex, stmtNode);
                    }
                }
                else if (parser.PeekToken(TokenKind.EndKeyword) && endKeywords != null && endKeywords.Contains(parser.PeekToken(2).Kind))
                {
                    break;
                }
                else
                {
                    parser.NextToken();
                }
            }
            prepStatementBinders.RemoveAt(0);
            node.EndIndex = parser.Token.Span.End;

            return(true);
        }
Ejemplo n.º 6
0
        public IEnumerable <MemberResult> GetMembers(Genero4glAst ast, MemberType memberType, bool function)
        {
            string projNamespace        = string.Format("{0}", this.Name);
            List <MemberResult> members = new List <MemberResult>();

            foreach (var projEntry in ProjectEntries)
            {
                if (projEntry.Value.Analysis != null &&
                    projEntry.Value.Analysis.Body != null)
                {
                    projEntry.Value.Analysis.Body.SetNamespace(projNamespace);
                    IModuleResult modRes = projEntry.Value.Analysis.Body as IModuleResult;
                    if (modRes != null)
                    {
                        if (memberType.HasFlag(MemberType.Variables))
                        {
                            members.AddRange(modRes.GlobalVariables.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, ast)));
                            members.AddRange(modRes.Variables.Where(x => x.Value.IsPublic).Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, ast)));
                        }

                        if (memberType.HasFlag(MemberType.Types))
                        {
                            members.AddRange(modRes.GlobalTypes.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Class, ast)));
                            members.AddRange(modRes.Types.Where(x => x.Value.IsPublic).Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Class, ast)));
                        }

                        if (memberType.HasFlag(MemberType.Constants))
                        {
                            members.AddRange(modRes.GlobalConstants.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Constant, ast)));
                            members.AddRange(modRes.Constants.Where(x => x.Value.IsPublic).Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Constant, ast)));
                        }

                        if (memberType.HasFlag(MemberType.Functions))
                        {
                            members.AddRange(modRes.Functions.Where(x => x.Value.IsPublic).Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Method, ast)));
                        }
                    }
                }
            }

            return(members);
        }
Ejemplo n.º 7
0
        public static bool TryParseNode(Genero4glParser parser, out DialogBlock node,
                                        IModuleResult containingModule,
                                        List <Func <PrepareStatement, bool> > prepStatementBinders,
                                        Func <ReturnStatement, ParserResult> returnStatementBinder   = null,
                                        Action <IAnalysisResult, int, int> limitedScopeVariableAdder = null,
                                        List <TokenKind> validExitKeywords = null,
                                        IEnumerable <ContextStatementFactory> contextStatementFactories = null,
                                        HashSet <TokenKind> endKeywords = null)
        {
            node = null;
            bool result = false;

            if (parser.PeekToken(TokenKind.DialogKeyword))
            {
                result          = true;
                node            = new DialogBlock(true);
                node.Attributes = new List <DialogAttribute>();
                node.Subdialogs = new List <FglNameExpression>();
                parser.NextToken();
                node.StartIndex   = parser.Token.Span.Start;
                node.DecoratorEnd = parser.Token.Span.End;

                BuildDialogBlock(parser, node, containingModule, prepStatementBinders, returnStatementBinder, limitedScopeVariableAdder,
                                 validExitKeywords, contextStatementFactories, endKeywords);

                if (!(parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.DialogKeyword, 2)))
                {
                    parser.ReportSyntaxError("A dialog block must be terminated with \"end dialog\".");
                }
                else
                {
                    parser.NextToken(); // advance to the 'end' token
                    parser.NextToken(); // advance to the 'dialog' token
                    node.EndIndex = parser.Token.Span.End;
                }
            }

            return(result);
        }
Ejemplo n.º 8
0
        public static bool TryGetStatement(Genero4glParser parser, out FglStatement node, bool isArray,
                                           IModuleResult containingModule,
                                           List <Func <PrepareStatement, bool> > prepStatementBinders,
                                           Func <ReturnStatement, ParserResult> returnStatementBinder   = null,
                                           Action <IAnalysisResult, int, int> limitedScopeVariableAdder = null,
                                           List <TokenKind> validExitKeywords = null,
                                           IEnumerable <ContextStatementFactory> contextStatementFactories = null,
                                           HashSet <TokenKind> endKeywords = null)
        {
            bool result = false;

            node = null;

            DisplayStatement inputStmt;

            if ((result = TryGetDisplayStatement(parser, out inputStmt, isArray)))
            {
                node = inputStmt;
            }
            else
            {
                List <ContextStatementFactory> csfs = new List <ContextStatementFactory>();
                if (contextStatementFactories != null)
                {
                    csfs.AddRange(contextStatementFactories);
                }
                csfs.Add((x) =>
                {
                    DisplayStatement testNode;
                    TryGetDisplayStatement(x, out testNode, isArray, true);
                    return(testNode);
                });
                result = parser.StatementFactory.TryParseNode(parser, out node, containingModule, prepStatementBinders,
                                                              returnStatementBinder, limitedScopeVariableAdder, false, validExitKeywords, csfs, null, endKeywords);
            }

            return(result);
        }
Ejemplo n.º 9
0
        public static bool TryGetStatement(Genero4glParser parser, out FglStatement node,
                                           IModuleResult containingModule,
                                           ReportBlockNode reportNode,
                                           List <Func <PrepareStatement, bool> > prepStatementBinders,
                                           Func <ReturnStatement, ParserResult> returnStatementBinder   = null,
                                           Action <IAnalysisResult, int, int> limitedScopeVariableAdder = null,
                                           List <TokenKind> validExitKeywords = null,
                                           IEnumerable <ContextStatementFactory> contextStatementFactories = null)
        {
            bool result = false;

            node = null;

            if (!(result = TryGetReportStatement(parser, out node, reportNode)))
            {
                List <ContextStatementFactory> csfs = new List <ContextStatementFactory>();
                if (contextStatementFactories != null)
                {
                    csfs.AddRange(contextStatementFactories);
                }
                csfs.Add((x) =>
                {
                    FglStatement testNode;
                    TryGetReportStatement(x, out testNode, reportNode, true);
                    return(testNode);
                });
                result = parser.StatementFactory.TryParseNode(parser, out node, containingModule, prepStatementBinders, returnStatementBinder,
                                                              limitedScopeVariableAdder, false, validExitKeywords, csfs,
                                                              new ExpressionParsingOptions
                {
                    AllowStarParam = true,
                    AdditionalExpressionParsers = new ExpressionParser[] { (x) => ParseAggregateReportFunction(x, reportNode) }
                });
            }

            return(result);
        }
Ejemplo n.º 10
0
        internal static void BuildDialogBlock(Genero4glParser parser, DialogBlock node, IModuleResult containingModule,
                                              List <Func <PrepareStatement, bool> > prepStatementBinders,
                                              Func <ReturnStatement, ParserResult> returnStatementBinder   = null,
                                              Action <IAnalysisResult, int, int> limitedScopeVariableAdder = null,
                                              List <TokenKind> validExitKeywords = null,
                                              IEnumerable <ContextStatementFactory> contextStatementFactories = null,
                                              HashSet <TokenKind> endKeywords = null)
        {
            if (parser.PeekToken(TokenKind.AttributeKeyword) || parser.PeekToken(TokenKind.AttributesKeyword))
            {
                parser.NextToken();
                if (parser.PeekToken(TokenKind.LeftParenthesis))
                {
                    parser.NextToken();

                    // get the list of display or control attributes
                    DialogAttribute attrib;
                    while (DialogAttribute.TryParseNode(parser, out attrib))
                    {
                        node.Attributes.Add(attrib);
                        if (!parser.PeekToken(TokenKind.Comma))
                        {
                            break;
                        }
                        parser.NextToken();
                    }

                    if (parser.PeekToken(TokenKind.RightParenthesis))
                    {
                        parser.NextToken();
                    }
                    else
                    {
                        parser.ReportSyntaxError("Expecting right-paren in dialog attributes section.");
                    }
                }
                else
                {
                    parser.ReportSyntaxError("Expecting left-paren in dialog attributes section.");
                }
            }

            // parse input, construct, display or SUBDIALOG
            bool moreBlocks = true;
            List <ContextStatementFactory> csfs = new List <ContextStatementFactory>();

            if (contextStatementFactories != null)
            {
                csfs.AddRange(contextStatementFactories);
            }
            csfs.Add((x) =>
            {
                DialogStatement testNode;
                DialogStatementFactory.TryGetDialogStatement(x, out testNode, true);
                return(testNode);
            });
            prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier);
            while (moreBlocks)
            {
                switch (parser.PeekToken().Kind)
                {
                case TokenKind.InputKeyword:
                {
                    InputBlock inputBlock;
                    if (InputBlock.TryParseNode(parser, out inputBlock, containingModule, prepStatementBinders, returnStatementBinder,
                                                limitedScopeVariableAdder, validExitKeywords, csfs, endKeywords) && inputBlock != null)
                    {
                        node.Children.Add(inputBlock.StartIndex, inputBlock);
                    }
                    else
                    {
                        parser.ReportSyntaxError("Invalid input block found in dialog statement.");
                    }
                    break;
                }

                case TokenKind.ConstructKeyword:
                {
                    ConstructBlock constructBlock;
                    if (ConstructBlock.TryParseNode(parser, out constructBlock, containingModule, prepStatementBinders, returnStatementBinder,
                                                    limitedScopeVariableAdder, validExitKeywords, csfs, endKeywords) && constructBlock != null)
                    {
                        node.Children.Add(constructBlock.StartIndex, constructBlock);
                    }
                    else
                    {
                        parser.ReportSyntaxError("Invalid construct block found in dialog statement.");
                    }
                    break;
                }

                case TokenKind.DisplayKeyword:
                {
                    DisplayBlock dispBlock;
                    if (DisplayBlock.TryParseNode(parser, out dispBlock, containingModule, prepStatementBinders, returnStatementBinder,
                                                  limitedScopeVariableAdder, validExitKeywords, csfs, endKeywords) && dispBlock != null)
                    {
                        node.Children.Add(dispBlock.StartIndex, dispBlock);
                    }
                    else
                    {
                        parser.ReportSyntaxError("Invalid display block found in dialog statement.");
                    }
                    break;
                }

                case TokenKind.SubdialogKeyword:
                {
                    parser.NextToken();
                    FglNameExpression nameExpr;
                    if (FglNameExpression.TryParseNode(parser, out nameExpr))
                    {
                        node.Subdialogs.Add(nameExpr);
                    }
                    else
                    {
                        parser.ReportSyntaxError("Invalid subdialog name found in dialog statement.");
                    }
                    break;
                }

                default:
                    moreBlocks = false;
                    break;
                }
            }
            prepStatementBinders.RemoveAt(0);

            List <TokenKind> validExits = new List <TokenKind>();

            if (validExitKeywords != null)
            {
                validExits.AddRange(validExits);
            }
            validExits.Add(TokenKind.DialogKeyword);

            HashSet <TokenKind> newEndKeywords = new HashSet <TokenKind>();

            if (endKeywords != null)
            {
                newEndKeywords.AddRange(endKeywords);
            }
            newEndKeywords.Add(TokenKind.DialogKeyword);

            // get the dialog control blocks
            prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier);
            while (!parser.PeekToken(TokenKind.EndOfFile) &&
                   !(parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.DialogKeyword, 2)))
            {
                DialogControlBlock icb;
                if (DialogControlBlock.TryParseNode(parser, out icb, containingModule, prepStatementBinders, returnStatementBinder,
                                                    limitedScopeVariableAdder, validExits, contextStatementFactories, newEndKeywords) && icb != null)
                {
                    if (icb.StartIndex < 0)
                    {
                        continue;
                    }
                    node.Children.Add(icb.StartIndex, icb);
                }
                else if (parser.PeekToken(TokenKind.EndKeyword) && endKeywords != null && endKeywords.Contains(parser.PeekToken(2).Kind))
                {
                    break;
                }
                else
                {
                    parser.NextToken();
                }
            }
            prepStatementBinders.RemoveAt(0);
        }
Ejemplo n.º 11
0
        public static bool TryParseNode(Genero4glParser parser, out DeclarativeDialogBlock node, IModuleResult containingModule)
        {
            node = null;
            bool           result      = false;
            AccessModifier?accMod      = null;
            string         accModToken = null;

            if (parser.PeekToken(TokenKind.PublicKeyword))
            {
                accMod      = AccessModifier.Public;
                accModToken = parser.PeekToken().Value.ToString();
            }
            else if (parser.PeekToken(TokenKind.PrivateKeyword))
            {
                accMod      = AccessModifier.Private;
                accModToken = parser.PeekToken().Value.ToString();
            }

            uint lookAheadBy = (uint)(accMod.HasValue ? 2 : 1);

            if (parser.PeekToken(TokenKind.DialogKeyword, lookAheadBy))
            {
                result = true;
                node   = new DeclarativeDialogBlock();
                if (accMod.HasValue)
                {
                    parser.NextToken();
                    node.AccessModifier = accMod.Value;
                }
                else
                {
                    node.AccessModifier = AccessModifier.Public;
                }

                parser.NextToken(); // move past the Function keyword
                node.StartIndex = parser.Token.Span.Start;

                // get the name
                if (parser.PeekToken(TokenCategory.Keyword) || parser.PeekToken(TokenCategory.Identifier))
                {
                    parser.NextToken();
                    node.Name          = parser.Token.Token.Value.ToString();
                    node.LocationIndex = parser.Token.Span.Start;
                    node.DecoratorEnd  = parser.Token.Span.End;
                }
                else
                {
                    parser.ReportSyntaxError("A declarative dialog must have a name.");
                }

                if (!parser.PeekToken(TokenKind.LeftParenthesis))
                {
                    parser.ReportSyntaxError("A declarative dialog must specify zero or more parameters in the form: ([param1][,...])");
                }
                else
                {
                    parser.NextToken();
                }

                // get the parameters
                while (parser.PeekToken(TokenCategory.Keyword) || parser.PeekToken(TokenCategory.Identifier))
                {
                    parser.NextToken();
                    string errMsg;
                    if (!node.AddArgument(parser.Token, out errMsg))
                    {
                        parser.ReportSyntaxError(errMsg);
                    }
                    if (parser.PeekToken(TokenKind.Comma))
                    {
                        parser.NextToken();
                    }

                    // TODO: probably need to handle "end" "function" case...won't right now
                }

                if (!parser.PeekToken(TokenKind.RightParenthesis))
                {
                    parser.ReportSyntaxError("A declarative dialog must specify zero or more parameters in the form: ([param1][,...])");
                }
                else
                {
                    parser.NextToken();
                }

                List <List <TokenKind> > breakSequences =
                    new List <List <TokenKind> >
                {
                    new List <TokenKind> {
                        TokenKind.InputKeyword
                    },
                    new List <TokenKind> {
                        TokenKind.ConstructKeyword
                    },
                    new List <TokenKind> {
                        TokenKind.DisplayKeyword
                    },
                    new List <TokenKind> {
                        TokenKind.EndKeyword, TokenKind.DialogKeyword
                    }
                };

                // only defines are allowed in declarative dialogs
                DefineNode defineNode;
                bool       matchedBreakSequence = false;
                while (DefineNode.TryParseDefine(parser, out defineNode, out matchedBreakSequence, breakSequences) && defineNode != null)
                {
                    node.Children.Add(defineNode.StartIndex, defineNode);
                    foreach (var def in defineNode.GetDefinitions())
                    {
                        foreach (var vardef in def.VariableDefinitions)
                        {
                            vardef.Scope = "local variable";
                            if (!node.Variables.ContainsKey(vardef.Name))
                            {
                                node.Variables.Add(vardef.Name, vardef);
                            }
                            else
                            {
                                parser.ReportSyntaxError(vardef.LocationIndex, vardef.LocationIndex + vardef.Name.Length, string.Format("Variable {0} defined more than once.", vardef.Name), Severity.Error);
                            }
                        }
                    }

                    if (parser.PeekToken(TokenKind.EndOfFile) ||
                        (parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.ReportKeyword, 2)))
                    {
                        break;
                    }

                    // if a break sequence was matched, we don't want to advance the token
                    if (!matchedBreakSequence)
                    {
                        // TODO: not sure whether to break or keep going...for right now, let's keep going until we hit the end keyword
                        parser.NextToken();
                    }
                }

                // we don't want the dialog piece itself to be outlinable, since it's a declarative block
                node.Dialog            = new DialogBlock(false);
                node.Dialog.Attributes = new List <DialogAttribute>();
                node.Dialog.Subdialogs = new List <FglNameExpression>();

                List <Func <PrepareStatement, bool> > prepStatementBinders = new List <Func <PrepareStatement, bool> >();
                prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier);
                DialogBlock.BuildDialogBlock(parser, node.Dialog, containingModule, prepStatementBinders);
                prepStatementBinders.RemoveAt(0);

                foreach (var child in node.Dialog.Children)
                {
                    node.Children.Add(child.Key, child.Value);
                }

                if (!parser.PeekToken(TokenKind.EndOfFile))
                {
                    parser.NextToken();
                    if (parser.PeekToken(TokenKind.DialogKeyword))
                    {
                        parser.NextToken();
                        node.EndIndex   = parser.Token.Span.End;
                        node.IsComplete = true;
                    }
                    else
                    {
                        parser.ReportSyntaxError(parser.Token.Span.Start, parser.Token.Span.End, "Invalid end of declarative dialog definition.");
                    }
                }
                else
                {
                    parser.ReportSyntaxError("Unexpected end of declarative dialog definition");
                }
            }

            return(result);
        }
Ejemplo n.º 12
0
        public static bool TryParseNode(Genero4glParser parser, out ForeachStatement node,
                                        IModuleResult containingModule,
                                        List <Func <PrepareStatement, bool> > prepStatementBinders,
                                        Func <ReturnStatement, ParserResult> returnStatementBinder   = null,
                                        Action <IAnalysisResult, int, int> limitedScopeVariableAdder = null,
                                        List <TokenKind> validExitKeywords = null,
                                        IEnumerable <ContextStatementFactory> contextStatementFactories = null,
                                        HashSet <TokenKind> endKeywords = null)
        {
            node = null;
            bool result = false;

            if (parser.PeekToken(TokenKind.ForeachKeyword))
            {
                result = true;
                node   = new ForeachStatement();
                parser.NextToken();
                node.StartIndex = parser.Token.Span.Start;
                node.InputVars  = new List <FglNameExpression>();
                node.OutputVars = new List <FglNameExpression>();

                FglNameExpression cid;
                if (FglNameExpression.TryParseNode(parser, out cid))
                {
                    node.CursorId = cid;
                }
                else
                {
                    parser.ReportSyntaxError("Invalid declared cursor id found in foreach statement.");
                }

                HashSet <TokenKind> inVarMods = new HashSet <TokenKind> {
                    TokenKind.InKeyword, TokenKind.OutKeyword, TokenKind.InOutKeyword
                };
                if (parser.PeekToken(TokenKind.UsingKeyword))
                {
                    parser.NextToken();
                    FglNameExpression inVar;
                    while (FglNameExpression.TryParseNode(parser, out inVar, TokenKind.Comma))
                    {
                        node.InputVars.Add(inVar);
                        if (inVarMods.Contains(parser.PeekToken().Kind))
                        {
                            parser.NextToken();
                        }
                        if (parser.PeekToken(TokenKind.Comma))
                        {
                            parser.NextToken();
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                if (parser.PeekToken(TokenKind.IntoKeyword))
                {
                    parser.NextToken();
                    FglNameExpression outVar;
                    while (FglNameExpression.TryParseNode(parser, out outVar, TokenKind.Comma))
                    {
                        node.InputVars.Add(outVar);
                        if (parser.PeekToken(TokenKind.Comma))
                        {
                            parser.NextToken();
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                node.DecoratorEnd = parser.Token.Span.End;

                if (parser.PeekToken(TokenKind.WithKeyword))
                {
                    parser.NextToken();
                    if (parser.PeekToken(TokenKind.ReoptimizationKeyword))
                    {
                        parser.NextToken();
                    }
                    else
                    {
                        parser.ReportSyntaxError("Expecting keyword \"reoptimization\" in open statement.");
                    }
                }

                List <TokenKind> validExits = new List <TokenKind>();
                if (validExitKeywords != null)
                {
                    validExits.AddRange(validExitKeywords);
                }
                validExits.Add(TokenKind.ForeachKeyword);

                HashSet <TokenKind> newEndKeywords = new HashSet <TokenKind>();
                if (endKeywords != null)
                {
                    newEndKeywords.AddRange(endKeywords);
                }
                newEndKeywords.Add(TokenKind.ForeachKeyword);

                prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier);
                while (!parser.PeekToken(TokenKind.EndOfFile) &&
                       !(parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.ForeachKeyword, 2)))
                {
                    FglStatement statement;
                    if (parser.StatementFactory.TryParseNode(parser, out statement, containingModule, prepStatementBinders,
                                                             returnStatementBinder, limitedScopeVariableAdder, false, validExits,
                                                             contextStatementFactories, null, newEndKeywords) && statement != null)
                    {
                        AstNode4gl stmtNode = statement as AstNode4gl;
                        node.Children.Add(stmtNode.StartIndex, stmtNode);

                        if (statement is ExitStatement &&
                            (statement as ExitStatement).ExitType != TokenKind.ForeachKeyword)
                        {
                            if (validExitKeywords == null || !validExitKeywords.Contains((statement as ExitStatement).ExitType))
                            {
                                parser.ReportSyntaxError("Invalid exit statement for for loop detected.");
                            }
                        }

                        if (statement is ContinueStatement &&
                            (statement as ContinueStatement).ContinueType != TokenKind.ForeachKeyword)
                        {
                            if (validExitKeywords == null || !validExitKeywords.Contains((statement as ContinueStatement).ContinueType))
                            {
                                parser.ReportSyntaxError("Invalid continue statement for for loop detected.");
                            }
                        }
                    }
                    else if (parser.PeekToken(TokenKind.EndKeyword) && endKeywords != null && endKeywords.Contains(parser.PeekToken(2).Kind))
                    {
                        break;
                    }
                    else
                    {
                        parser.NextToken();
                    }
                }
                prepStatementBinders.RemoveAt(0);

                if (!(parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.ForeachKeyword, 2)))
                {
                    parser.ReportSyntaxError("A foreach statement must be terminated with \"end foreach\".");
                }
                else
                {
                    parser.NextToken(); // advance to the 'end' token
                    parser.NextToken(); // advance to the 'foreach' token
                    node.EndIndex = parser.Token.Span.End;
                }
            }

            return(result);
        }
Ejemplo n.º 13
0
        public static bool TryParseNode(Genero4glParser parser, out CaseStatement node,
                                        IModuleResult containingModule,
                                        List <Func <PrepareStatement, bool> > prepStatementBinders,
                                        Func <ReturnStatement, ParserResult> returnStatementBinder   = null,
                                        Action <IAnalysisResult, int, int> limitedScopeVariableAdder = null,
                                        List <TokenKind> validExitKeywords = null,
                                        IEnumerable <ContextStatementFactory> contextStatementFactories = null,
                                        ExpressionParsingOptions expressionOptions = null,
                                        HashSet <TokenKind> endKeywords            = null)
        {
            node = null;
            bool result = false;

            if (parser.PeekToken(TokenKind.CaseKeyword))
            {
                result = true;
                node   = new CaseStatement();
                parser.NextToken();
                node.StartIndex = parser.Token.Span.Start;


                if (!parser.PeekToken(TokenKind.WhenKeyword))
                {
                    ExpressionNode tempExpr;
                    if (FglExpressionNode.TryGetExpressionNode(parser, out tempExpr, new List <TokenKind> {
                        TokenKind.WhenKeyword
                    }))
                    {
                        node.ConditionExpression = tempExpr;
                    }
                    else
                    {
                        parser.ReportSyntaxError("Invalid conditional expression found in case statement");
                    }
                }
                node.DecoratorEnd = parser.Token.Span.End;

                List <TokenKind> validExits = new List <TokenKind>();
                if (validExitKeywords != null)
                {
                    validExits.AddRange(validExitKeywords);
                }
                validExits.Add(TokenKind.CaseKeyword);

                HashSet <TokenKind> newEndKeywords = new HashSet <TokenKind>();
                if (endKeywords != null)
                {
                    newEndKeywords.AddRange(endKeywords);
                }
                newEndKeywords.Add(TokenKind.CaseKeyword);

                // need to allow multiple when statements
                bool whenCases = true;
                while (!parser.PeekToken(TokenKind.EndOfFile) &&
                       !(parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.CaseKeyword, 2)))
                {
                    WhenStatement whenStmt;
                    if (WhenStatement.TryParseNode(parser, out whenStmt, containingModule, prepStatementBinders,
                                                   returnStatementBinder, limitedScopeVariableAdder, validExits,
                                                   contextStatementFactories, expressionOptions, newEndKeywords) && whenStmt != null)
                    {
                        if (whenCases)
                        {
                            node.Children.Add(whenStmt.StartIndex, whenStmt);
                        }
                        else
                        {
                            parser.ReportSyntaxError("A when case cannot come after an otherwise case block.");
                            break;
                        }
                    }
                    else
                    {
                        OtherwiseStatement otherStmt;
                        if (OtherwiseStatement.TryParseNode(parser, out otherStmt, containingModule, prepStatementBinders, returnStatementBinder,
                                                            limitedScopeVariableAdder, validExits, contextStatementFactories, expressionOptions, newEndKeywords) && otherStmt != null)
                        {
                            whenCases = false;
                            node.Children.Add(otherStmt.StartIndex, otherStmt);
                        }
                        else
                        {
                            parser.ReportSyntaxError("Invalid statement detected within case statement block.");
                            break;
                        }
                    }
                }

                if (!(parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.CaseKeyword, 2)))
                {
                    parser.ReportSyntaxError("A case statement must be terminated with \"end case\".");
                }
                else
                {
                    parser.NextToken(); // advance to the 'end' token
                    parser.NextToken(); // advance to the 'case' token
                    node.EndIndex = parser.Token.Span.End;
                }
            }

            return(result);
        }
Ejemplo n.º 14
0
        public static bool TryParseNode(Genero4glParser parser, out ConstructBlock node,
                                        IModuleResult containingModule,
                                        List <Func <PrepareStatement, bool> > prepStatementBinders,
                                        Func <ReturnStatement, ParserResult> returnStatementBinder   = null,
                                        Action <IAnalysisResult, int, int> limitedScopeVariableAdder = null,
                                        List <TokenKind> validExitKeywords = null,
                                        IEnumerable <ContextStatementFactory> contextStatementFactories = null,
                                        HashSet <TokenKind> endKeywords = null)
        {
            node = null;
            bool result = false;

            if (parser.PeekToken(TokenKind.ConstructKeyword))
            {
                result = true;
                node   = new ConstructBlock();
                parser.NextToken();
                node.StartIndex = parser.Token.Span.Start;
                node.ColumnList = new List <FglNameExpression>();
                node.FieldList  = new List <FglNameExpression>();
                node.Attributes = new List <ConstructAttribute>();

                if (parser.PeekToken(TokenKind.ByKeyword))
                {
                    parser.NextToken();
                    if (parser.PeekToken(TokenKind.NameKeyword))
                    {
                        parser.NextToken();

                        // Implicit field mapping
                        node.IsImplicitMapping = true;
                    }
                    else
                    {
                        parser.ReportSyntaxError("Expected \"name\" token in construct statement.");
                    }
                }

                FglNameExpression varName;
                if (FglNameExpression.TryParseNode(parser, out varName))
                {
                    node.Variable = varName;
                }
                else
                {
                    parser.ReportSyntaxError("Invalid variable name found in construct statement.");
                }

                node.DecoratorEnd = parser.Token.Span.End;

                if (parser.PeekToken(TokenKind.OnKeyword))
                {
                    parser.NextToken();
                }
                else
                {
                    parser.ReportSyntaxError("Expecting \"on\" keyword in construct statement.");
                }

                FglNameExpression colName;
                while (FglNameExpression.TryParseNode(parser, out colName))
                {
                    node.ColumnList.Add(colName);
                    if (!parser.PeekToken(TokenKind.Comma))
                    {
                        break;
                    }
                    parser.NextToken();
                }

                if (!node.IsImplicitMapping)
                {
                    if (parser.PeekToken(TokenKind.FromKeyword))
                    {
                        parser.NextToken();

                        // read the field list
                        FglNameExpression nameExpr;
                        while (FglNameExpression.TryParseNode(parser, out nameExpr))
                        {
                            node.FieldList.Add(nameExpr);
                            if (!parser.PeekToken(TokenKind.Comma))
                            {
                                break;
                            }
                            parser.NextToken();
                        }
                    }
                    else
                    {
                        parser.ReportSyntaxError("Expected \"from\" token in construct statement.");
                    }
                }

                if (parser.PeekToken(TokenKind.AttributesKeyword) || parser.PeekToken(TokenKind.AttributeKeyword))
                {
                    parser.NextToken();
                    if (parser.PeekToken(TokenKind.LeftParenthesis))
                    {
                        parser.NextToken();

                        // get the list of display or control attributes
                        ConstructAttribute attrib;
                        while (ConstructAttribute.TryParseNode(parser, out attrib))
                        {
                            node.Attributes.Add(attrib);
                            if (!parser.PeekToken(TokenKind.Comma))
                            {
                                break;
                            }
                            parser.NextToken();
                        }

                        if (parser.PeekToken(TokenKind.RightParenthesis))
                        {
                            parser.NextToken();
                        }
                        else
                        {
                            parser.ReportSyntaxError("Expecting right-paren in construct attributes section.");
                        }
                    }
                    else
                    {
                        parser.ReportSyntaxError("Expecting left-paren in construct attributes section.");
                    }
                }

                if (parser.PeekToken(TokenKind.HelpKeyword))
                {
                    parser.NextToken();

                    // get the help number
                    ExpressionNode optionNumber;
                    if (FglExpressionNode.TryGetExpressionNode(parser, out optionNumber))
                    {
                        node.HelpNumber = optionNumber;
                    }
                    else
                    {
                        parser.ReportSyntaxError("Invalid help-number found in construct statement.");
                    }
                }

                List <TokenKind> validExits = new List <TokenKind>();
                if (validExitKeywords != null)
                {
                    validExits.AddRange(validExitKeywords);
                }
                validExits.Add(TokenKind.ConstructKeyword);

                HashSet <TokenKind> newEndKeywords = new HashSet <TokenKind>();
                if (endKeywords != null)
                {
                    newEndKeywords.AddRange(endKeywords);
                }
                newEndKeywords.Add(TokenKind.ConstructKeyword);

                bool hasControlBlocks = false;
                ConstructControlBlock icb;
                prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier);
                while (ConstructControlBlock.TryParseNode(parser, out icb, containingModule, prepStatementBinders, returnStatementBinder,
                                                          limitedScopeVariableAdder, validExits, contextStatementFactories, newEndKeywords) && icb != null)
                {
                    if (icb.StartIndex < 0)
                    {
                        continue;
                    }

                    node.Children.Add(icb.StartIndex, icb);
                    hasControlBlocks = true;
                    if (parser.PeekToken(TokenKind.EndOfFile) ||
                        (parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.ConstructKeyword, 2)))
                    {
                        break;
                    }
                }
                prepStatementBinders.RemoveAt(0);

                if (hasControlBlocks ||
                    (parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.ConstructKeyword, 2)))
                {
                    if (!(parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.ConstructKeyword, 2)))
                    {
                        parser.ReportSyntaxError("A construct block must be terminated with \"end construct\".");
                    }
                    else
                    {
                        parser.NextToken(); // advance to the 'end' token
                        parser.NextToken(); // advance to the 'construct' token
                        node.EndIndex = parser.Token.Span.End;
                    }
                }
            }

            return(result);
        }
Ejemplo n.º 15
0
        internal static bool TryParseNode(Genero4glParser parser, out CreateTableStatement node, IModuleResult containingModule)
        {
            node = null;
            bool result = false;
            bool temp   = false;

            int tempIndex = -1;

            if (parser.PeekToken(TokenKind.TempKeyword))
            {
                tempIndex = parser.Token.Span.Start;
                temp      = true;
                parser.NextToken();
            }

            if (parser.PeekToken(TokenKind.TableKeyword))
            {
                result         = true;
                node           = new CreateTableStatement();
                node.TempTable = temp;
                if (tempIndex >= 0)
                {
                    node.StartIndex = tempIndex;
                }
                else
                {
                    node.StartIndex = parser.Token.Span.Start;
                }
                parser.NextToken();

                if (parser.PeekToken(TokenKind.IfKeyword))
                {
                    parser.NextToken();
                    if (parser.PeekToken(TokenKind.NotKeyword))
                    {
                        parser.NextToken();
                        if (parser.PeekToken(TokenKind.ExistsKeyword))
                        {
                            parser.NextToken();
                        }
                        else
                        {
                            parser.ReportSyntaxError("Expecting \"exists\" keyword in create table statement.");
                        }
                    }
                    else
                    {
                        parser.ReportSyntaxError("Expecting \"not\" keyword in create table statement.");
                    }
                }

                FglNameExpression nameExpr;
                if (FglNameExpression.TryParseNode(parser, out nameExpr))
                {
                    node.TableName = nameExpr;
                }
                else
                {
                    parser.ReportSyntaxError("Invalid name found for create table statement.");
                }

                if (parser.PeekToken(TokenKind.LeftParenthesis))
                {
                    parser.NextToken();
                    CreatedTableColumn tableCol;
                    while (CreatedTableColumn.TryParseNode(parser, out tableCol) && tableCol != null)
                    {
                        node.Children.Add(tableCol.StartIndex, tableCol);
                        if (parser.PeekToken(TokenKind.Comma))
                        {
                            parser.NextToken();
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (parser.PeekToken(TokenKind.RightParenthesis))
                    {
                        parser.NextToken();
                    }
                    else
                    {
                        parser.ReportSyntaxError("Expected right-paren in create table statement.");
                    }

                    if (parser.PeekToken(TokenKind.WithKeyword))
                    {
                        parser.NextToken();
                        if (parser.PeekToken(TokenKind.NoKeyword))
                        {
                            parser.NextToken();
                            if (parser.PeekToken(TokenKind.LogKeyword))
                            {
                                parser.NextToken();
                            }
                            else
                            {
                                parser.ReportSyntaxError("Expecting \"log\" keyword in create table statement.");
                            }
                        }
                        else
                        {
                            parser.ReportSyntaxError("Expecting \"no\" keyword in create table statement.");
                        }
                    }

                    if (parser.PeekToken(TokenKind.InKeyword))
                    {
                        parser.NextToken();
                        if (FglNameExpression.TryParseNode(parser, out nameExpr))
                        {
                            node.TablespaceName = nameExpr;
                        }
                        else
                        {
                            parser.ReportSyntaxError("Invalid name found for create table statement.");
                        }
                    }

                    if (parser.PeekToken(TokenKind.ExtentKeyword))
                    {
                        parser.NextToken();
                        if (parser.PeekToken(TokenKind.SizeKeyword))
                        {
                            parser.NextToken();
                            ExpressionNode extSize;
                            if (FglExpressionNode.TryGetExpressionNode(parser, out extSize))
                            {
                                node.ExtentSize = extSize;
                            }
                            else
                            {
                                parser.ReportSyntaxError("Invalid expression found for extent size in create table statement.");
                            }
                        }
                        else
                        {
                            parser.ReportSyntaxError("Expecting \"size\" keyword in create table statement.");
                        }
                    }

                    if (parser.PeekToken(TokenKind.NextKeyword))
                    {
                        parser.NextToken();
                        if (parser.PeekToken(TokenKind.SizeKeyword))
                        {
                            parser.NextToken();
                            ExpressionNode extSize;
                            if (FglExpressionNode.TryGetExpressionNode(parser, out extSize))
                            {
                                node.NextSize = extSize;
                            }
                            else
                            {
                                parser.ReportSyntaxError("Invalid expression found for next size in create table statement.");
                            }
                        }
                        else
                        {
                            parser.ReportSyntaxError("Expecting \"size\" keyword in create table statement.");
                        }
                    }

                    if (parser.PeekToken(TokenKind.LockKeyword))
                    {
                        parser.NextToken();
                        if (parser.PeekToken(TokenKind.ModeKeyword))
                        {
                            parser.NextToken();
                            switch (parser.PeekToken().Kind)
                            {
                            case TokenKind.PageKeyword:
                                parser.NextToken();
                                break;

                            case TokenKind.RowKeyword:
                                parser.NextToken();
                                break;

                            default:
                                parser.ReportSyntaxError("Expecting \"page\" or \"row\" keyword in create table statement.");
                                break;
                            }
                        }
                        else
                        {
                            parser.ReportSyntaxError("Expecting \"mode\" keyword in create table statement.");
                        }
                    }
                }
                else
                {
                    parser.ReportSyntaxError("Expected left-paren in create table statement.");
                }

                containingModule.BindTableResult(node, parser);
            }
            return(result);
        }
Ejemplo n.º 16
0
        public static bool TryParseNode(Genero4glParser parser, out MenuOption node,
                                        IModuleResult containingModule,
                                        List <Func <PrepareStatement, bool> > prepStatementBinders,
                                        Func <ReturnStatement, ParserResult> returnStatementBinder   = null,
                                        Action <IAnalysisResult, int, int> limitedScopeVariableAdder = null,
                                        List <TokenKind> validExitKeywords = null,
                                        IEnumerable <ContextStatementFactory> contextStatementFactories = null,
                                        HashSet <TokenKind> endKeywords = null)
        {
            node = new MenuOption();
            bool result = true;

            prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier);

            switch (parser.PeekToken().Kind)
            {
            case TokenKind.Ampersand:
            {
                PreprocessorNode preNode;
                PreprocessorNode.TryParseNode(parser, out preNode);
                node.StartIndex = -1;
                break;
            }

            case TokenKind.CommandKeyword:
            {
                parser.NextToken();
                node.StartIndex = parser.Token.Span.Start;
                bool getOptionName = false;
                if (parser.PeekToken(TokenKind.KeyKeyword))
                {
                    parser.NextToken();
                    if (parser.PeekToken(TokenKind.LeftParenthesis))
                    {
                        parser.NextToken();
                        VirtualKey keyName;
                        if (VirtualKey.TryGetKey(parser, out keyName))
                        {
                            node.KeyName = keyName;
                        }
                        else
                        {
                            parser.ReportSyntaxError("Invalid key-name found in menu command option.");
                        }

                        if (parser.PeekToken(TokenKind.RightParenthesis))
                        {
                            parser.NextToken();
                        }
                        else
                        {
                            parser.ReportSyntaxError("Expecting right-paren in menu command option.");
                        }
                    }
                    else
                    {
                        parser.ReportSyntaxError("Expecting left-paren in menu command option.");
                    }
                    node.DecoratorEnd = parser.Token.Span.End;
                }
                else
                {
                    getOptionName = true;
                }


                // at this point we need to try to get a menu-statement. If it doesn't work, we have some other stuff to gather
                FglStatement menuStmt = null;
                if (getOptionName || !MenuStatementFactory.TryGetStatement(parser, out menuStmt, containingModule, prepStatementBinders, returnStatementBinder,
                                                                           limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, endKeywords))
                {
                    ExpressionNode optionName;
                    if (FglExpressionNode.TryGetExpressionNode(parser, out optionName))
                    {
                        node.OptionName = optionName;
                    }
                    else
                    {
                        parser.ReportSyntaxError("Invalid option-name found in menu command option.");
                    }

                    node.DecoratorEnd = parser.Token.Span.End;

                    if (parser.PeekToken(TokenCategory.StringLiteral) ||
                        parser.PeekToken(TokenCategory.Identifier))
                    {
                        ExpressionNode optionComment;
                        if (FglExpressionNode.TryGetExpressionNode(parser, out optionComment))
                        {
                            node.OptionComment = optionComment;
                        }
                    }
                    if (parser.PeekToken(TokenKind.HelpKeyword))
                    {
                        parser.NextToken();

                        ExpressionNode optionNumber;
                        if (FglExpressionNode.TryGetExpressionNode(parser, out optionNumber))
                        {
                            node.HelpNumber = optionNumber;
                        }
                        else
                        {
                            parser.ReportSyntaxError("Invalid help-number found in menu command option.");
                        }
                    }
                }
                else if (menuStmt != null)
                {
                    node.Children.Add(menuStmt.StartIndex, menuStmt);
                }

                while (MenuStatementFactory.TryGetStatement(parser, out menuStmt, containingModule, prepStatementBinders, returnStatementBinder,
                                                            limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, endKeywords))
                {
                    if (menuStmt != null && !node.Children.ContainsKey(menuStmt.StartIndex))
                    {
                        node.Children.Add(menuStmt.StartIndex, menuStmt);
                    }
                }

                break;
            }

            case TokenKind.OnKeyword:
            {
                parser.NextToken();
                node.StartIndex = parser.Token.Span.Start;
                if (parser.PeekToken(TokenKind.ActionKeyword))
                {
                    parser.NextToken();
                    FglNameExpression action;
                    if (FglNameExpression.TryParseNode(parser, out action))
                    {
                        node.ActionName = action;
                    }
                    else
                    {
                        parser.ReportSyntaxError("Invalid action-name found in menu option.");
                    }
                    node.DecoratorEnd = parser.Token.Span.End;
                    FglStatement menuStmt = null;
                    while (MenuStatementFactory.TryGetStatement(parser, out menuStmt, containingModule, prepStatementBinders, returnStatementBinder,
                                                                limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, endKeywords) && menuStmt != null)
                    {
                        node.Children.Add(menuStmt.StartIndex, menuStmt);
                    }
                }
                else if (parser.PeekToken(TokenKind.IdleKeyword))
                {
                    parser.NextToken();
                    ExpressionNode idleExpr;
                    if (FglExpressionNode.TryGetExpressionNode(parser, out idleExpr))
                    {
                        node.IdleSeconds = idleExpr;
                    }
                    else
                    {
                        parser.ReportSyntaxError("Invalid idle-seconds found in menu block.");
                    }
                    node.DecoratorEnd = parser.Token.Span.End;
                    FglStatement menuStmt = null;
                    while (MenuStatementFactory.TryGetStatement(parser, out menuStmt, containingModule, prepStatementBinders, returnStatementBinder,
                                                                limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, endKeywords) && menuStmt != null)
                    {
                        node.Children.Add(menuStmt.StartIndex, menuStmt);
                    }
                }
                else
                {
                    parser.ReportSyntaxError("Expecting \"action\" or \"idle\" keyword in menu option.");
                }
                break;
            }

            default:
                result = false;
                break;
            }
            prepStatementBinders.RemoveAt(0);

            node.EndIndex = parser.Token.Span.End;

            return(result);
        }
Ejemplo n.º 17
0
        public static bool TryParseNode(Genero4glParser parser, out DeclareStatement defNode, IModuleResult containingModule)
        {
            defNode = null;
            bool result = false;

            if (parser.PeekToken(TokenKind.DeclareKeyword))
            {
                result  = true;
                defNode = new DeclareStatement();
                parser.NextToken();
                defNode.StartIndex             = parser.Token.Span.Start;
                defNode._prepStatementResolver = containingModule.PreparedCursorResolver;

                if (parser.PeekToken(TokenCategory.Identifier) || parser.PeekToken(TokenCategory.Keyword))
                {
                    parser.NextToken();
                    defNode.Identifier = parser.Token.Token.Value.ToString();

                    if (parser.PeekToken(TokenKind.ScrollKeyword))
                    {
                        parser.NextToken();
                        defNode.Scroll = true;
                    }

                    if (parser.PeekToken(TokenKind.CursorKeyword))
                    {
                        parser.NextToken();

                        if (parser.PeekToken(TokenKind.WithKeyword))
                        {
                            parser.NextToken();
                            if (parser.PeekToken(TokenKind.HoldKeyword))
                            {
                                parser.NextToken();
                                defNode.WithHold = true;
                            }
                            else
                            {
                                parser.ReportSyntaxError("SQL declare statement missing \"hold\" keyword.");
                            }
                        }

                        if (parser.PeekToken(TokenKind.FromKeyword))
                        {
                            parser.NextToken();
                            // We have a string expression declare
                            ExpressionNode exprNode;
                            if (FglExpressionNode.TryGetExpressionNode(parser, out exprNode) /* && exprNode is StringExpressionNode*/ && exprNode != null)
                            {
                                defNode.Children.Add(exprNode.StartIndex, exprNode);
                                defNode.EndIndex = exprNode.EndIndex;

                                containingModule.BindCursorResult(defNode, parser);
                            }
                            else
                            {
                                parser.ReportSyntaxError("String expression not found for SQl declare statement");
                            }
                        }
                        else if (parser.PeekToken(TokenKind.ForKeyword))
                        {
                            parser.NextToken();
                            if (parser.PeekToken(TokenKind.SqlKeyword))
                            {
                                // we have a sql block declare
                                SqlBlockNode sqlBlock;
                                if (SqlBlockNode.TryParseSqlNode(parser, out sqlBlock) && sqlBlock != null)
                                {
                                    defNode.Children.Add(sqlBlock.StartIndex, sqlBlock);
                                    defNode.EndIndex   = sqlBlock.EndIndex;
                                    defNode.IsComplete = true;
                                    containingModule.BindCursorResult(defNode, parser);
                                }
                            }
                            else if (parser.PeekToken(TokenKind.SelectKeyword))
                            {
                                // we have a static sql select statement
                                FglStatement sqlStmt;
                                bool         dummy;
                                if (SqlStatementFactory.TryParseSqlStatement(parser, out sqlStmt, out dummy, TokenKind.SelectKeyword) && sqlStmt != null)
                                {
                                    defNode.Children.Add(sqlStmt.StartIndex, sqlStmt);
                                    defNode.EndIndex   = sqlStmt.EndIndex;
                                    defNode.IsComplete = true;
                                    containingModule.BindCursorResult(defNode, parser);
                                }
                                else
                                {
                                    parser.ReportSyntaxError("Static SQL declare statement must specify a SELECT statement.");
                                }
                            }
                            else if (parser.PeekToken(TokenCategory.Identifier) || parser.PeekToken(TokenCategory.Keyword))
                            {
                                // we have a prepared statment
                                parser.NextToken();
                                defNode.PreparedStatementId = parser.Token.Token.Value.ToString();
                                defNode.EndIndex            = parser.Token.Span.End;
                                defNode.IsComplete          = true;
                                containingModule.BindCursorResult(defNode, parser);
                            }
                            else
                            {
                                parser.ReportSyntaxError("Invalid token found in SQL declare statment.");
                            }
                        }
                        else
                        {
                            parser.ReportSyntaxError("SQL declare statement must have either \"for\" or \"from\" keyword.");
                        }
                    }
                    else
                    {
                        parser.ReportSyntaxError("SQL declare statement missing \"cursor\" keyword.");
                    }
                }
                else
                {
                    parser.ReportSyntaxError("SQL declare statement must specify an identifier to declare.");
                }
            }

            return(result);
        }
Ejemplo n.º 18
0
        public override IEnumerable <MemberResult> GetDefinedMembers(int index, AstMemberType memberType, bool isMemberAccess = false)
        {
            HashSet <MemberResult> members = new HashSet <MemberResult>();

            HashSet <GeneroPackage> includedPackages = new HashSet <GeneroPackage>();

            if (memberType.HasFlag(AstMemberType.SystemTypes) && !isMemberAccess)
            {
                // Built-in types
                members.AddRange(BuiltinTypes.Select(x => new MemberResult(Tokens.TokenKinds[x], GeneroMemberType.Keyword, this)));

                foreach (var package in Packages.Values.Where(x => _importedPackages[x.Name] && x.ContainsInstanceMembers &&
                                                              (this.LanguageVersion >= x.MinimumLanguageVersion && this.LanguageVersion <= x.MaximumLanguageVersion)))
                {
                    members.Add(new MemberResult(package.Name, GeneroMemberType.Module, this));
                    includedPackages.Add(package);
                }
            }
            if (memberType.HasFlag(AstMemberType.Constants) && !isMemberAccess)
            {
                members.AddRange(SystemConstants.Where(x => this.LanguageVersion >= x.Value.MinimumLanguageVersion && this.LanguageVersion <= x.Value.MaximumLanguageVersion)
                                 .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Keyword, this)));
                members.AddRange(SystemMacros.Where(x => this.LanguageVersion >= x.Value.MinimumLanguageVersion && this.LanguageVersion <= x.Value.MaximumLanguageVersion)
                                 .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Constant, this)));
            }
            if (memberType.HasFlag(AstMemberType.Variables) && !isMemberAccess)
            {
                members.AddRange(SystemVariables.Where(x => this.LanguageVersion >= x.Value.MinimumLanguageVersion && this.LanguageVersion <= x.Value.MaximumLanguageVersion)
                                 .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Keyword, this)));
            }
            if (memberType.HasFlag(AstMemberType.Functions) && !isMemberAccess)
            {
                members.AddRange(SystemFunctions.Where(x => this.LanguageVersion >= x.Value.MinimumLanguageVersion && this.LanguageVersion <= x.Value.MaximumLanguageVersion)
                                 .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Function, this)));
                foreach (var package in Packages.Values.Where(x => _importedPackages[x.Name] && x.ContainsStaticClasses &&
                                                              (this.LanguageVersion >= x.MinimumLanguageVersion && this.LanguageVersion <= x.MaximumLanguageVersion)))
                {
                    if (!includedPackages.Contains(package))
                    {
                        members.Add(new MemberResult(package.Name, GeneroMemberType.Module, this));
                    }
                }
            }

            // TODO: need to handle multiple results of the same name
            AstNode containingNode = GetContainingNode(_body, index);

            if (containingNode != null)
            {
                if (containingNode is IFunctionResult)
                {
                    if (memberType.HasFlag(AstMemberType.Variables))
                    {
                        members.AddRange((containingNode as IFunctionResult).Variables.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)));
                        foreach (var varList in (containingNode as IFunctionResult).LimitedScopeVariables)
                        {
                            foreach (var item in varList.Value)
                            {
                                if (item.Item2.IsInSpan(index))
                                {
                                    members.Add(new MemberResult(item.Item1.Name, item.Item1, GeneroMemberType.Instance, this));
                                    break;
                                }
                            }
                        }
                    }
                    if (memberType.HasFlag(AstMemberType.SystemTypes))
                    {
                        members.AddRange((containingNode as IFunctionResult).Types.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Class, this)));
                    }
                    if (memberType.HasFlag(AstMemberType.Constants))
                    {
                        members.AddRange((containingNode as IFunctionResult).Constants.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Constant, this)));
                    }
                    if (memberType.HasFlag(AstMemberType.Functions))
                    {
                        foreach (var res in (containingNode as IFunctionResult).Variables /*.Where(x => x.Value.HasChildFunctions(this))
                                                                                           */.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)))
                        {
                            if (!members.Contains(res))
                            {
                                members.Add(res);
                            }
                        }

                        foreach (var varList in (containingNode as IFunctionResult).LimitedScopeVariables)
                        {
                            foreach (var item in varList.Value)
                            {
                                if (item.Item2.IsInSpan(index))
                                {
                                    members.Add(new MemberResult(item.Item1.Name, item.Item1, GeneroMemberType.Instance, this));
                                    break;
                                }
                            }
                        }
                    }
                }

                if (_body is IModuleResult)
                {
                    // check for module vars, types, and constants (and globals defined in this module)
                    if (memberType.HasFlag(AstMemberType.Variables))
                    {
                        members.AddRange((_body as IModuleResult).Variables.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)));
                        members.AddRange((_body as IModuleResult).GlobalVariables.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)));
                    }
                    if (memberType.HasFlag(AstMemberType.UserDefinedTypes))
                    {
                        members.AddRange((_body as IModuleResult).Types.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Class, this)));
                        members.AddRange((_body as IModuleResult).GlobalTypes.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Class, this)));
                    }
                    if (memberType.HasFlag(AstMemberType.Constants))
                    {
                        members.AddRange((_body as IModuleResult).Constants.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Constant, this)));
                        members.AddRange((_body as IModuleResult).GlobalConstants.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Constant, this)));
                    }
                    if (memberType.HasFlag(AstMemberType.Dialogs))
                    {
                        members.AddRange((_body as IModuleResult).Functions.Where(x => x.Value is DeclarativeDialogBlock)
                                         .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Dialog, this)));
                        members.AddRange((_body as IModuleResult).FglImports.Select(x => new MemberResult(x, GeneroMemberType.Module, this)));
                    }
                    if (memberType.HasFlag(AstMemberType.Reports))
                    {
                        members.AddRange((_body as IModuleResult).Functions.Where(x => x.Value is ReportBlockNode)
                                         .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Report, this)));
                    }
                    if (memberType.HasFlag(AstMemberType.Functions))
                    {
                        members.AddRange((_body as IModuleResult).Functions
                                         .Where(x => !(x.Value is ReportBlockNode) && !(x.Value is DeclarativeDialogBlock))
                                         .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Method, this)));
                        foreach (var res in (_body as IModuleResult).Variables /*.Where(x => x.Value.HasChildFunctions(this))
                                                                                */.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)))
                        {
                            if (!members.Contains(res))
                            {
                                members.Add(res);
                            }
                        }
                        foreach (var res in (_body as IModuleResult).GlobalVariables /*.Where(x => x.Value.HasChildFunctions(this))
                                                                                      */.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)))
                        {
                            if (!members.Contains(res))
                            {
                                members.Add(res);
                            }
                        }
                    }

                    // Tables and cursors are module specific, and cannot be accessed via fgl import
                    if (memberType.HasFlag(AstMemberType.DeclaredCursors) ||
                        memberType.HasFlag(AstMemberType.PreparedCursors) ||
                        memberType.HasFlag(AstMemberType.Tables))
                    {
                        if (memberType.HasFlag(AstMemberType.DeclaredCursors))
                        {
                            members.AddRange((_body as IModuleResult).Cursors.Where(x => x.Value is DeclareStatement).Select(x => new MemberResult(x.Value.Name, x.Value, GeneroMemberType.Cursor, this)));
                        }
                        if (memberType.HasFlag(AstMemberType.PreparedCursors))
                        {
                            members.AddRange((_body as IModuleResult).Cursors.Where(x => x.Value is PrepareStatement).Select(x => new MemberResult(x.Value.Name, x.Value, GeneroMemberType.Cursor, this)));
                        }
                        if (memberType.HasFlag(AstMemberType.Tables))
                        {
                            members.AddRange((_body as IModuleResult).Tables.Select(x => new MemberResult(x.Value.Name, x.Value, GeneroMemberType.DbTable, this)));
                        }
                    }
                    else
                    {
                        members.AddRange((_body as IModuleResult).FglImports.Select(x => new MemberResult(x, GeneroMemberType.Module, this)));
                    }
                }
            }

            // TODO: this could probably be done more efficiently by having each GeneroAst load globals and functions into
            // dictionaries stored on the IGeneroProject, instead of in each project entry.
            // However, this does required more upkeep when changes occur. Will look into it...
            if (_projEntry != null && _projEntry is IGeneroProjectEntry)
            {
                IGeneroProjectEntry genProj = _projEntry as IGeneroProjectEntry;
                if (genProj.ParentProject != null &&
                    !genProj.FilePath.ToLower().EndsWith(".inc"))
                {
                    foreach (var projEntry in genProj.ParentProject.ProjectEntries.Where(x => x.Value != genProj))
                    {
                        if (projEntry.Value.Analysis != null &&
                            projEntry.Value.Analysis.Body != null)
                        {
                            projEntry.Value.Analysis.Body.SetNamespace(null);
                            IModuleResult modRes = projEntry.Value.Analysis.Body as IModuleResult;
                            if (modRes != null)
                            {
                                // check global types
                                // TODO: need to add an option to enable/disable legacy linking (to not reference other modules' non-public members
                                if (memberType.HasFlag(AstMemberType.Variables))
                                {
                                    members.AddRange(modRes.GlobalVariables.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)));
                                    members.AddRange(modRes.Variables.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)));
                                }
                                if (memberType.HasFlag(AstMemberType.UserDefinedTypes))
                                {
                                    members.AddRange(modRes.GlobalTypes.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Class, this)));
                                    members.AddRange(modRes.Types.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Class, this)));
                                }
                                if (memberType.HasFlag(AstMemberType.Constants))
                                {
                                    members.AddRange(modRes.GlobalConstants.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Constant, this)));
                                    members.AddRange(modRes.Constants.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Constant, this)));
                                }
                                if (memberType.HasFlag(AstMemberType.Dialogs))
                                {
                                    members.AddRange(modRes.Functions.Where(x => x.Value is DeclarativeDialogBlock)
                                                     .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Dialog, this)));
                                }
                                if (memberType.HasFlag(AstMemberType.Reports))
                                {
                                    members.AddRange(modRes.Functions.Where(x => x.Value is ReportBlockNode)
                                                     .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Report, this)));
                                }
                                if (memberType.HasFlag(AstMemberType.Functions))
                                {
                                    members.AddRange(modRes.Functions.Where(x => !(x.Value is ReportBlockNode) && !(x.Value is DeclarativeDialogBlock))
                                                     .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Method, this)));
                                    foreach (var res in modRes.GlobalVariables/*.Where(x =>
                                                                               * {
                                                                               * return x.Value.HasChildFunctions(this);
                                                                               * })*/
                                             .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)))
                                    {
                                        if (!members.Contains(res))
                                        {
                                            members.Add(res);
                                        }
                                    }
                                    foreach (var res in modRes.Variables/*.Where(x =>
                                                                         * {
                                                                         * return x.Value.HasChildFunctions(this);
                                                                         * })*/
                                             .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)))
                                    {
                                        if (!members.Contains(res))
                                        {
                                            members.Add(res);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (memberType.HasFlag(AstMemberType.Functions))
            {
                _includePublicFunctions = true; // allow for deferred adding of public functions
            }

            if (memberType.HasFlag(AstMemberType.Tables))
            {
                _includeDatabaseTables = true;  // allow for deferred adding of external database tables
            }

            members.AddRange(this.ProjectEntry.GetIncludedFiles().Where(x => x.Analysis != null).SelectMany(x => x.Analysis.GetDefinedMembers(1, memberType)));

            return(members);
        }
Ejemplo n.º 19
0
        public static bool TryParseNode(Genero4glParser parser, out DisplayBlock node,
                                        IModuleResult containingModule,
                                        List <Func <PrepareStatement, bool> > prepStatementBinders,
                                        Func <ReturnStatement, ParserResult> returnStatementBinder   = null,
                                        Action <IAnalysisResult, int, int> limitedScopeVariableAdder = null,
                                        List <TokenKind> validExitKeywords = null,
                                        IEnumerable <ContextStatementFactory> contextStatementFactories = null,
                                        HashSet <TokenKind> endKeywords = null)
        {
            node = null;
            bool result = false;

            if (parser.PeekToken(TokenKind.DisplayKeyword))
            {
                result = true;
                node   = new DisplayBlock();
                parser.NextToken();
                node.StartIndex   = parser.Token.Span.Start;
                node.Attributes   = new List <DisplayAttribute>();
                node.ByNameFields = new List <FglNameExpression>();
                node.FieldSpecs   = new List <FglNameExpression>();
                node.DecoratorEnd = parser.Token.Span.End;

                if (parser.PeekToken(TokenKind.ByKeyword))
                {
                    parser.NextToken();
                    if (parser.PeekToken(TokenKind.NameKeyword))
                    {
                        parser.NextToken();

                        // get the bynamefields
                        FglNameExpression nameExpr;
                        while (FglNameExpression.TryParseNode(parser, out nameExpr))
                        {
                            node.ByNameFields.Add(nameExpr);
                            if (!parser.PeekToken(TokenKind.Comma))
                            {
                                break;
                            }
                            parser.NextToken();
                        }

                        node.DecoratorEnd = parser.Token.Span.End;

                        // get the optional attributes
                        if (parser.PeekToken(TokenKind.AttributesKeyword) || parser.PeekToken(TokenKind.AttributeKeyword))
                        {
                            parser.NextToken();
                            if (parser.PeekToken(TokenKind.LeftParenthesis))
                            {
                                parser.NextToken();
                                DisplayAttribute attrib;
                                while (DisplayAttribute.TryParseNode(parser, out attrib, node.IsArray))
                                {
                                    node.Attributes.Add(attrib);
                                    if (!parser.PeekToken(TokenKind.Comma))
                                    {
                                        break;
                                    }
                                    parser.NextToken();
                                }

                                if (parser.PeekToken(TokenKind.RightParenthesis))
                                {
                                    parser.NextToken();
                                }
                                else
                                {
                                    parser.ReportSyntaxError("Expecting right-paren in display attributes section.");
                                }
                            }
                            else
                            {
                                parser.ReportSyntaxError("Expecting left-paren in display attributes section.");
                            }
                        }
                        node.EndIndex = parser.Token.Span.End;
                    }
                    else
                    {
                        parser.ReportSyntaxError("Expected \"name\" keyword in display statement.");
                    }
                }
                else if (parser.PeekToken(TokenKind.ArrayKeyword))
                {
                    parser.NextToken();
                    node.IsArray = true;

                    FglNameExpression arrName;
                    if (FglNameExpression.TryParseNode(parser, out arrName))
                    {
                        node.ArrayName = arrName;
                    }
                    else
                    {
                        parser.ReportSyntaxError("Invalid array name found in display array statement.");
                    }

                    node.DecoratorEnd = parser.Token.Span.End;

                    if (parser.PeekToken(TokenKind.ToKeyword))
                    {
                        parser.NextToken();
                        if (FglNameExpression.TryParseNode(parser, out arrName))
                        {
                            node.ScreenArrayName = arrName;
                        }
                        else
                        {
                            parser.ReportSyntaxError("Invalid array name found in display array statement.");
                        }

                        if (parser.PeekToken(TokenKind.HelpKeyword))
                        {
                            parser.NextToken();

                            // get the help number
                            ExpressionNode optionNumber;
                            if (FglExpressionNode.TryGetExpressionNode(parser, out optionNumber))
                            {
                                node.HelpNumber = optionNumber;
                            }
                            else
                            {
                                parser.ReportSyntaxError("Invalid help-number found in input statement.");
                            }
                        }

                        // get the optional attributes
                        if (parser.PeekToken(TokenKind.AttributesKeyword) || parser.PeekToken(TokenKind.AttributeKeyword))
                        {
                            parser.NextToken();
                            if (parser.PeekToken(TokenKind.LeftParenthesis))
                            {
                                parser.NextToken();
                                DisplayAttribute attrib;
                                while (DisplayAttribute.TryParseNode(parser, out attrib, node.IsArray))
                                {
                                    node.Attributes.Add(attrib);
                                    if (!parser.PeekToken(TokenKind.Comma))
                                    {
                                        break;
                                    }
                                    parser.NextToken();
                                }

                                if (parser.PeekToken(TokenKind.RightParenthesis))
                                {
                                    parser.NextToken();
                                }
                                else
                                {
                                    parser.ReportSyntaxError("Expecting right-paren in display attributes section.");
                                }
                            }
                            else
                            {
                                parser.ReportSyntaxError("Expecting left-paren in display attributes section.");
                            }
                        }

                        List <TokenKind> validExits = new List <TokenKind>();
                        if (validExitKeywords != null)
                        {
                            validExits.AddRange(validExitKeywords);
                        }
                        validExits.Add(TokenKind.DisplayKeyword);

                        HashSet <TokenKind> newEndKeywords = new HashSet <TokenKind>();
                        if (endKeywords != null)
                        {
                            newEndKeywords.AddRange(endKeywords);
                        }
                        newEndKeywords.Add(TokenKind.DisplayKeyword);

                        bool hasControlBlocks = false;
                        DisplayControlBlock icb;
                        prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier);
                        while (DisplayControlBlock.TryParseNode(parser, out icb, containingModule, hasControlBlocks, node.IsArray, prepStatementBinders,
                                                                returnStatementBinder, limitedScopeVariableAdder, validExits, contextStatementFactories, newEndKeywords) && icb != null)
                        {
                            // check for include file sign
                            if (icb.StartIndex < 0)
                            {
                                continue;
                            }

                            node.Children.Add(icb.StartIndex, icb);
                            hasControlBlocks = true;
                            if (parser.PeekToken(TokenKind.EndOfFile) ||
                                (parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.DisplayKeyword, 2)))
                            {
                                break;
                            }
                        }
                        prepStatementBinders.RemoveAt(0);

                        if (hasControlBlocks ||
                            (parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.DisplayKeyword, 2)))
                        {
                            if (!(parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.DisplayKeyword, 2)))
                            {
                                parser.ReportSyntaxError("A display block must be terminated with \"end display\".");
                            }
                            else
                            {
                                parser.NextToken(); // advance to the 'end' token
                                parser.NextToken(); // advance to the 'display' token
                                node.EndIndex = parser.Token.Span.End;
                            }
                        }
                    }
                    else
                    {
                        parser.ReportSyntaxError("Expected \"to\" keyword in display array statement.");
                    }
                }
                else
                {
                    // get the expression(s)
                    ExpressionNode mainExpression = null;
                    while (true)
                    {
                        ExpressionNode expr;
                        if (!FglExpressionNode.TryGetExpressionNode(parser, out expr, new List <TokenKind> {
                            TokenKind.ToKeyword, TokenKind.AttributeKeyword, TokenKind.AttributesKeyword
                        }))
                        {
                            parser.ReportSyntaxError("Display statement must have one or more comma-separated expressions.");
                            break;
                        }
                        if (mainExpression == null)
                        {
                            mainExpression = expr;
                        }
                        else
                        {
                            mainExpression.AppendExpression(expr);
                        }

                        if (!parser.PeekToken(TokenKind.Comma))
                        {
                            break;
                        }
                        parser.NextToken();
                    }

                    if (mainExpression != null)
                    {
                        node.Expression = mainExpression;
                    }
                    else
                    {
                        parser.ReportSyntaxError("Invalid expression found in display statement.");
                    }

                    if (parser.PeekToken(TokenKind.ToKeyword))
                    {
                        parser.NextToken();

                        // get the field specs
                        FglNameExpression nameExpr;
                        while (FglNameExpression.TryParseNode(parser, out nameExpr))
                        {
                            node.FieldSpecs.Add(nameExpr);
                            if (!parser.PeekToken(TokenKind.Comma))
                            {
                                break;
                            }
                            parser.NextToken();
                        }

                        // get the optional attributes
                        if (parser.PeekToken(TokenKind.AttributesKeyword) || parser.PeekToken(TokenKind.AttributeKeyword))
                        {
                            parser.NextToken();
                            if (parser.PeekToken(TokenKind.LeftParenthesis))
                            {
                                parser.NextToken();
                                DisplayAttribute attrib;
                                while (DisplayAttribute.TryParseNode(parser, out attrib, node.IsArray))
                                {
                                    node.Attributes.Add(attrib);
                                    if (!parser.PeekToken(TokenKind.Comma))
                                    {
                                        break;
                                    }
                                    parser.NextToken();
                                }

                                if (parser.PeekToken(TokenKind.RightParenthesis))
                                {
                                    parser.NextToken();
                                }
                                else
                                {
                                    parser.ReportSyntaxError("Expecting right-paren in input attributes section.");
                                }
                            }
                            else
                            {
                                parser.ReportSyntaxError("Expecting left-paren in display attributes section.");
                            }
                        }
                    }

                    node.EndIndex = parser.Token.Span.End;
                }
            }

            return(result);
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Gets the variables the given expression evaluates to.  Variables include parameters, locals, and fields assigned on classes, modules and instances.
        ///
        /// Variables are classified as either definitions or references.  Only parameters have unique definition points - all other types of variables
        /// have only one or more references.
        ///
        /// index is a 0-based absolute index into the file.
        /// </summary>
        public override IEnumerable <IAnalysisVariable> GetVariablesByIndex(string exprText, int index, IFunctionInformationProvider functionProvider,
                                                                            IDatabaseInformationProvider databaseProvider, IProgramFileProvider programFileProvider,
                                                                            bool isFunctionCallOrDefinition)
        {
            _functionProvider    = functionProvider;
            _databaseProvider    = databaseProvider;
            _programFileProvider = programFileProvider;

            List <IAnalysisVariable> vars = new List <IAnalysisVariable>();

            _body.SetNamespace(null);
            AstNode containingNode = GetContainingNode(_body, index);

            if (containingNode != null)
            {
                if (!isFunctionCallOrDefinition)
                {
                    if (containingNode is IFunctionResult)
                    {
                        // Check for local vars, types, and constants
                        IFunctionResult func = containingNode as IFunctionResult;
                        IAnalysisResult res;

                        if (func.Variables.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(this.ResolveLocation(res), VariableType.Definition));
                        }

                        if (func.Types.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(this.ResolveLocation(res), VariableType.Definition));
                        }

                        if (func.Constants.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(this.ResolveLocation(res), VariableType.Definition));
                        }

                        List <Tuple <IAnalysisResult, IndexSpan> > limitedScopeVars;
                        if (func.LimitedScopeVariables.TryGetValue(exprText, out limitedScopeVars))
                        {
                            foreach (var item in limitedScopeVars)
                            {
                                if (item.Item2.IsInSpan(index))
                                {
                                    vars.Add(new AnalysisVariable(this.ResolveLocation(res), VariableType.Reference));
                                }
                            }
                        }
                    }
                }

                if (_body is IModuleResult)
                {
                    // check for module vars, types, and constants (and globals defined in this module)
                    IModuleResult   mod = _body as IModuleResult;
                    IAnalysisResult res;

                    if (!isFunctionCallOrDefinition)
                    {
                        if (mod.Variables.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(this.ResolveLocation(res), VariableType.Definition));
                        }

                        if (mod.Types.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(this.ResolveLocation(res), VariableType.Definition));
                        }

                        if (mod.Constants.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(this.ResolveLocation(res), VariableType.Definition));
                        }

                        if (mod.GlobalVariables.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(this.ResolveLocation(res), VariableType.Definition));
                        }

                        if (mod.GlobalTypes.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(this.ResolveLocation(res), VariableType.Definition));
                        }

                        if (mod.GlobalConstants.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(this.ResolveLocation(res), VariableType.Definition));
                        }

                        // check for cursors in this module
                        if (mod.Cursors.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(this.ResolveLocation(res), VariableType.Definition));
                        }
                    }
                    else
                    {
                        // check for module functions
                        IFunctionResult funcRes;
                        if (mod.Functions.TryGetValue(exprText, out funcRes))
                        {
                            vars.Add(new AnalysisVariable(this.ResolveLocation(funcRes), VariableType.Definition, funcRes.Name, 1));
                        }
                    }
                }
            }

            // TODO: this could probably be done more efficiently by having each GeneroAst load globals and functions into
            // dictionaries stored on the IGeneroProject, instead of in each project entry.
            // However, this does required more upkeep when changes occur. Will look into it...
            if (_projEntry != null && _projEntry is IGeneroProjectEntry)
            {
                IGeneroProjectEntry genProj = _projEntry as IGeneroProjectEntry;
                if (genProj.ParentProject != null &&
                    !genProj.FilePath.ToLower().EndsWith(".inc"))
                {
                    foreach (var projEntry in genProj.ParentProject.ProjectEntries.Where(x => x.Value != genProj))
                    {
                        if (projEntry.Value.Analysis != null &&
                            projEntry.Value.Analysis.Body != null)
                        {
                            projEntry.Value.Analysis.Body.SetNamespace(null);
                            IModuleResult modRes = projEntry.Value.Analysis.Body as IModuleResult;
                            if (modRes != null)
                            {
                                if (!isFunctionCallOrDefinition)
                                {
                                    // check global vars, types, and constants
                                    // TODO: need to introduce option to enable/disable legacy linking
                                    IAnalysisResult res;
                                    if (modRes.GlobalVariables.TryGetValue(exprText, out res) || modRes.Variables.TryGetValue(exprText, out res))
                                    {
                                        vars.Add(new AnalysisVariable(projEntry.Value.Analysis.ResolveLocation(res), VariableType.Definition));
                                    }

                                    if (modRes.GlobalTypes.TryGetValue(exprText, out res) || modRes.Types.TryGetValue(exprText, out res))
                                    {
                                        vars.Add(new AnalysisVariable(projEntry.Value.Analysis.ResolveLocation(res), VariableType.Definition));
                                    }

                                    if (modRes.GlobalConstants.TryGetValue(exprText, out res) || modRes.Constants.TryGetValue(exprText, out res))
                                    {
                                        vars.Add(new AnalysisVariable(projEntry.Value.Analysis.ResolveLocation(res), VariableType.Definition));
                                    }

                                    // check for cursors in this module
                                    if (modRes.Cursors.TryGetValue(exprText, out res))
                                    {
                                        vars.Add(new AnalysisVariable(projEntry.Value.Analysis.ResolveLocation(res), VariableType.Definition));
                                    }
                                }
                                else
                                {
                                    // check for module functions
                                    IFunctionResult funcRes;
                                    if (modRes.Functions.TryGetValue(exprText, out funcRes))
                                    {
                                        vars.Add(new AnalysisVariable(projEntry.Value.Analysis.ResolveLocation(funcRes), VariableType.Definition, funcRes.Name, 1));
                                    }
                                }
                            }
                        }
                    }
                }
            }

            /* TODO:
             * Need to check for:
             * 1) Temp tables
             * 2) DB Tables and columns
             * 3) Record fields
             */

            if (isFunctionCallOrDefinition && _functionProvider != null)
            {
                var funcRes = _functionProvider.GetFunction(exprText);
                if (funcRes != null)
                {
                    vars.AddRange(funcRes.Select(x => new AnalysisVariable(x.Location, VariableType.Definition, x.Name, 2)));
                }

                IFunctionResult funcResult;
                if (SystemFunctions.TryGetValue(exprText, out funcResult))
                {
                    vars.Add(new AnalysisVariable(funcResult.Location, VariableType.Definition, funcResult.Name, 2));
                }
            }

            // try an imported module
            if (Body is IModuleResult && ProjectEntry != null)
            {
                if ((Body as IModuleResult).FglImports.Contains(exprText))
                {
                    // need to get the ast for the other project entry
                    var refProjKVP = (ProjectEntry as IGeneroProjectEntry).ParentProject.ReferencedProjects.Values.FirstOrDefault(
                        x =>
                    {
                        var fn = Path.GetFileNameWithoutExtension(x.Directory);
                        return(fn?.Equals(exprText, StringComparison.OrdinalIgnoreCase) ?? false);
                    });
                    if (refProjKVP is IAnalysisResult)
                    {
                        IGeneroProject definingProject = refProjKVP;
                        vars.Add(new AnalysisVariable(new LocationInfo(definingProject.Directory, 1), VariableType.Definition));
                    }
                }
            }

            if (exprText.Contains('.') && vars.Count == 0)
            {
                IGeneroProject  definingProj;
                IProjectEntry   projEntry;
                bool            dummyDef;
                IAnalysisResult res = GetValueByIndex(exprText, index, functionProvider, databaseProvider, _programFileProvider, isFunctionCallOrDefinition, out dummyDef, out definingProj, out projEntry);
                if (res != null)
                {
                    LocationInfo locInfo = null;
                    if (definingProj != null || projEntry != null)
                    {
                        locInfo = ResolveLocationInternal(definingProj, projEntry, res);
                    }
                    else
                    {
                        locInfo = this.ResolveLocation(res);
                    }
                    if (locInfo != null &&
                        (
                            (locInfo.Index > 0 || (locInfo.Line > 0 && locInfo.Column > 0)) ||
                            !string.IsNullOrWhiteSpace(locInfo.DefinitionURL)
                        )
                        )
                    {
                        vars.Add(new AnalysisVariable(locInfo, VariableType.Definition));
                    }
                }
            }

            if (_body is IModuleResult &&
                _projEntry is IGeneroProjectEntry)
            {
                string   dotPiece  = exprText;
                string[] dotPieces = exprText.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
                if (dotPieces.Length > 1)
                {
                    dotPiece = dotPieces[0];
                }
                if ((_body as IModuleResult).FglImports.Contains(dotPiece))
                {
                    // need to get the ast for the other project entry
                    var refProjKVP = (_projEntry as IGeneroProjectEntry).ParentProject.ReferencedProjects.Values.FirstOrDefault(
                        x =>
                    {
                        var fn = Path.GetFileName(x.Directory);
                        return(fn?.Equals(dotPiece, StringComparison.OrdinalIgnoreCase) ?? false);
                    });
                    if (refProjKVP is IAnalysisResult)
                    {
                        IProjectEntry   dummyEntry;
                        bool            dummyDef;
                        IAnalysisResult res = GetValueByIndex(exprText, index, functionProvider, databaseProvider, _programFileProvider, isFunctionCallOrDefinition, out dummyDef, out refProjKVP, out dummyEntry);
                        if (res != null)
                        {
                            LocationInfo locInfo = null;
                            locInfo = refProjKVP != null?ResolveLocationInternal(refProjKVP, dummyEntry, res) : this.ResolveLocation(res);

                            if (locInfo != null && (locInfo.Index > 0 || (locInfo.Line > 0 && locInfo.Column > 0)))
                            {
                                vars.Add(new AnalysisVariable(locInfo, VariableType.Definition));
                            }
                        }
                    }
                }
            }

            if (!isFunctionCallOrDefinition)
            {
                foreach (var includeFile in this.ProjectEntry.GetIncludedFiles())
                {
                    IAnalysisResult res;
                    if (includeFile.Analysis != null &&
                        includeFile.Analysis.Body is IModuleResult)
                    {
                        includeFile.Analysis.Body.SetNamespace(null);
                        var mod = includeFile.Analysis.Body as IModuleResult;
                        if (mod.Types.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(ResolveLocationInternal(null, includeFile, res), VariableType.Definition));
                        }
                        if (mod.Constants.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(ResolveLocationInternal(null, includeFile, res), VariableType.Definition));
                        }
                    }
                }
            }

            return(vars);
        }
Ejemplo n.º 21
0
        public static IAnalysisResult GetValueByIndex(string exprText, int index, Genero4glAst ast, out IGeneroProject definingProject, out IProjectEntry projectEntry, out bool isDeferredFunction,
                                                      FunctionProviderSearchMode searchInFunctionProvider = FunctionProviderSearchMode.NoSearch, bool isFunctionCallOrDefinition = false,
                                                      bool getTypes = true, bool getVariables = true, bool getConstants = true)
        {
            isDeferredFunction = false;
            definingProject    = null;
            projectEntry       = null;
            //_functionProvider = functionProvider;
            //_databaseProvider = databaseProvider;
            //_programFileProvider = programFileProvider;

            AstNode containingNode = null;

            if (ast != null)
            {
                containingNode = GetContainingNode(ast.Body, index);
                ast.Body.SetNamespace(null);
            }

            IAnalysisResult res = null;
            int             tmpIndex = 0;
            int             bracketDepth = 0;
            bool            doSearch = false;
            bool            resetStartIndex = false;
            int             startIndex = 0, endIndex = 0;
            bool            noEndIndexSet = false;

            if (exprText == null)
            {
                return(null);
            }

            while (tmpIndex < exprText.Length)
            {
                if (resetStartIndex)
                {
                    startIndex      = tmpIndex;
                    resetStartIndex = false;
                    if (startIndex + 1 > exprText.Length)
                    {
                        break;
                    }
                }

                doSearch = false;
                switch (exprText[tmpIndex])
                {
                case '.':
                {
                    if (bracketDepth == 0)
                    {
                        endIndex = tmpIndex - 1;
                        if (endIndex >= startIndex)
                        {
                            // we have our 'piece'
                            doSearch = true;
                        }
                        if (exprText[startIndex] == '.')
                        {
                            startIndex++;
                        }
                    }
                    tmpIndex++;
                }
                break;

                case '[':
                    if (noEndIndexSet)
                    {
                        noEndIndexSet = false;
                    }
                    else
                    {
                        if (bracketDepth == 0)
                        {
                            endIndex = tmpIndex - 1;
                        }
                    }
                    bracketDepth++;
                    tmpIndex++;
                    break;

                case ']':
                {
                    bracketDepth--;
                    if (bracketDepth == 0)
                    {
                        if (exprText.Length <= tmpIndex + 1 ||
                            exprText[tmpIndex + 1] != '[')
                        {
                            // we have our first 'piece'
                            doSearch = true;
                        }
                        else
                        {
                            noEndIndexSet = true;
                        }
                    }
                    tmpIndex++;
                }
                break;

                default:
                {
                    if (bracketDepth == 0 && (tmpIndex + 1 == exprText.Length))
                    {
                        endIndex = tmpIndex;
                        doSearch = true;
                    }
                    tmpIndex++;
                }
                break;
                }

                if (!doSearch)
                {
                    continue;
                }

                // we can do our search
                var dotPiece = exprText.Substring(startIndex, (endIndex - startIndex) + 1);
                if (dotPiece.Contains('('))
                {
                    // remove the params piece
                    int remIndex = dotPiece.IndexOf('(');
                    dotPiece = dotPiece.Substring(0, remIndex);
                }

                bool lookForFunctions = isFunctionCallOrDefinition && (endIndex + 1 == exprText.Length);

                resetStartIndex = true;

                if (res != null)
                {
                    if (ast != null)
                    {
                        var gmi = new GetMemberInput
                        {
                            Name       = dotPiece,
                            AST        = ast,
                            IsFunction = lookForFunctions
                        };
                        IAnalysisResult tempRes = res.GetMember(gmi);
                        if (gmi.DefiningProject != null && definingProject != gmi.DefiningProject)
                        {
                            definingProject = gmi.DefiningProject;
                        }
                        if (gmi.ProjectEntry != null && projectEntry != gmi.ProjectEntry)
                        {
                            projectEntry = gmi.ProjectEntry;
                        }
                        res = tempRes;
                        if (tempRes == null)
                        {
                            res = null;
                            break;
                        }
                    }
                    else
                    {
                        res = null;
                        break;
                    }
                }
                else
                {
                    IFunctionResult funcRes;
                    if (!lookForFunctions)
                    {
                        if (SystemVariables.TryGetValue(dotPiece, out res) ||
                            SystemConstants.TryGetValue(dotPiece, out res) ||
                            SystemMacros.TryGetValue(dotPiece, out res))
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if (SystemFunctions.TryGetValue(dotPiece, out funcRes))
                        {
                            res = funcRes;
                            continue;
                        }

                        if (ast != null && ast._functionProvider != null && ast._functionProvider.Name.Equals(dotPiece, StringComparison.OrdinalIgnoreCase))
                        {
                            res = ast._functionProvider;
                            continue;
                        }
                    }

                    if (containingNode != null && containingNode is IFunctionResult)
                    {
                        IFunctionResult func = containingNode as IFunctionResult;
                        if ((getVariables && func.Variables.TryGetValue(dotPiece, out res)))
                        {
                            continue;
                        }
                        if (!lookForFunctions)
                        {
                            // Check for local vars, types, and constants
                            if ((getTypes && func.Types.TryGetValue(dotPiece, out res)) ||
                                (getConstants && func.Constants.TryGetValue(dotPiece, out res)))
                            {
                                continue;
                            }

                            List <Tuple <IAnalysisResult, IndexSpan> > limitedScopeVars;
                            if ((getVariables && func.LimitedScopeVariables.TryGetValue(dotPiece, out limitedScopeVars)))
                            {
                                foreach (var item in limitedScopeVars)
                                {
                                    if (item.Item2.IsInSpan(index))
                                    {
                                        res = item.Item1;

                                        break;
                                    }
                                }
                                if (res != null)
                                {
                                    continue;
                                }
                            }
                        }
                    }

                    if (ast != null && ast.Body is IModuleResult)
                    {
                        IModuleResult mod = ast.Body as IModuleResult;
                        if (!lookForFunctions)
                        {
                            // check for module vars, types, and constants (and globals defined in this module)
                            if ((getVariables && (mod.Variables.TryGetValue(dotPiece, out res) || mod.GlobalVariables.TryGetValue(dotPiece, out res))) ||
                                (getTypes && (mod.Types.TryGetValue(dotPiece, out res) || mod.GlobalTypes.TryGetValue(dotPiece, out res))) ||
                                (getConstants && (mod.Constants.TryGetValue(dotPiece, out res) || mod.GlobalConstants.TryGetValue(dotPiece, out res))))
                            {
                                continue;
                            }

                            // check for cursors in this module
                            if (mod.Cursors.TryGetValue(dotPiece, out res))
                            {
                                continue;
                            }
                        }
                        else
                        {
                            // check for module functions
                            if (mod.Functions.TryGetValue(dotPiece, out funcRes))
                            {
                                // check for any function info collected at the project entry level, and update the function's documentation with that.
                                if (ast._projEntry != null && ast._projEntry is IGeneroProjectEntry)
                                {
                                    var commentInfo = (ast._projEntry as IGeneroProjectEntry).GetFunctionInfo(funcRes.Name);
                                    if (commentInfo != null)
                                    {
                                        funcRes.SetCommentDocumentation(commentInfo);
                                    }
                                }
                                res = funcRes;
                                continue;
                            }
                        }
                    }

                    // TODO: this could probably be done more efficiently by having each GeneroAst load globals and functions into
                    // dictionaries stored on the IGeneroProject, instead of in each project entry.
                    // However, this does required more upkeep when changes occur. Will look into it...
                    if (ast != null && ast.ProjectEntry != null && ast.ProjectEntry is IGeneroProjectEntry)
                    {
                        IGeneroProjectEntry genProj = ast.ProjectEntry as IGeneroProjectEntry;
                        if (genProj.ParentProject != null &&
                            !genProj.FilePath.ToLower().EndsWith(".inc"))
                        {
                            bool found = false;
                            foreach (var projEntry in genProj.ParentProject.ProjectEntries.Where(x => x.Value != genProj))
                            {
                                if (projEntry.Value.Analysis != null &&
                                    projEntry.Value.Analysis.Body != null)
                                {
                                    projEntry.Value.Analysis.Body.SetNamespace(null);
                                    IModuleResult modRes = projEntry.Value.Analysis.Body as IModuleResult;
                                    if (modRes != null)
                                    {
                                        if (!lookForFunctions)
                                        {
                                            // check global vars, types, and constants
                                            // TODO: need option to enable/disable legacy linking
                                            if ((getVariables && (modRes.Variables.TryGetValue(dotPiece, out res) || modRes.GlobalVariables.TryGetValue(dotPiece, out res))) ||
                                                (getTypes && (modRes.Types.TryGetValue(dotPiece, out res) || modRes.GlobalTypes.TryGetValue(dotPiece, out res))) ||
                                                (getConstants && (modRes.Constants.TryGetValue(dotPiece, out res) || modRes.GlobalConstants.TryGetValue(dotPiece, out res))))
                                            {
                                                found = true;
                                                break;
                                            }

                                            // check for cursors in this module
                                            if (modRes.Cursors.TryGetValue(dotPiece, out res))
                                            {
                                                found = true;
                                                break;
                                            }
                                        }
                                        else
                                        {
                                            // check project functions
                                            if (modRes.Functions.TryGetValue(dotPiece, out funcRes))
                                            {
                                                if (funcRes.AccessModifier == AccessModifier.Public)
                                                {
                                                    res   = funcRes;
                                                    found = true;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                            if (found)
                            {
                                continue;
                            }
                        }
                    }

                    // check for classes
                    GeneroPackage package;
                    if (Packages.TryGetValue(dotPiece, out package))
                    {
                        res = package;
                        continue;
                    }

                    /* TODO:
                     * Need to check for:
                     * 1) Temp tables
                     */

                    // Nothing found yet...
                    // If our containing node is at the function or globals level, we need to go deeper
                    if (containingNode != null &&
                        (containingNode is GlobalsNode ||
                         containingNode is FunctionBlockNode ||
                         containingNode is ReportBlockNode))
                    {
                        containingNode = GetContainingNode(containingNode, index);
                    }
                    // check for record field
                    if (containingNode != null &&
                        (containingNode is DefineNode ||
                         containingNode is TypeDefNode))
                    {
                        containingNode = GetContainingNode(containingNode, index);

                        if (containingNode != null &&
                            (containingNode is VariableDefinitionNode ||
                             containingNode is TypeDefinitionNode) &&
                            containingNode.Children.Count == 1 &&
                            containingNode.Children[containingNode.Children.Keys[0]] is TypeReference)
                        {
                            var typeRef = containingNode.Children[containingNode.Children.Keys[0]] as TypeReference;
                            while (typeRef != null &&
                                   typeRef.Children.Count == 1)
                            {
                                if (typeRef.Children[typeRef.Children.Keys[0]] is RecordDefinitionNode)
                                {
                                    var         recNode = typeRef.Children[typeRef.Children.Keys[0]] as RecordDefinitionNode;
                                    VariableDef recField;
                                    if (recNode.MemberDictionary.TryGetValue(exprText, out recField))
                                    {
                                        res = recField;
                                        break;
                                    }
                                    else
                                    {
                                        recField = recNode.MemberDictionary.Where(x => x.Value.LocationIndex < index)
                                                   .OrderByDescending(x => x.Value.LocationIndex)
                                                   .Select(x => x.Value)
                                                   .FirstOrDefault();
                                        if (recField != null)
                                        {
                                            typeRef = recField.Type;
                                        }
                                        else
                                        {
                                            break;
                                        }
                                    }
                                }
                                else if (typeRef.Children[typeRef.Children.Keys[0]] is TypeReference)
                                {
                                    typeRef = typeRef.Children[typeRef.Children.Keys[0]] as TypeReference;
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }

                    // try an imported module
                    if (ast != null && ast.Body is IModuleResult &&
                        ast.ProjectEntry != null && ast.ProjectEntry != null)
                    {
                        if ((ast.Body as IModuleResult).FglImports.Contains(dotPiece))
                        {
                            // need to get the ast for the other project entry
                            var refProjKVP = (ast.ProjectEntry as IGeneroProjectEntry).ParentProject.ReferencedProjects.Values.FirstOrDefault(
                                x =>
                            {
                                var fn = Path.GetFileNameWithoutExtension(x.Directory);
                                return(fn?.Equals(dotPiece, StringComparison.OrdinalIgnoreCase) ?? false);
                            });
                            if (refProjKVP is IAnalysisResult)
                            {
                                definingProject = refProjKVP;
                                res             = refProjKVP as IAnalysisResult;
                                continue;
                            }

                            IAnalysisResult sysImportMod;
                            // check the system imports
                            if (SystemImportModules.TryGetValue(dotPiece, out sysImportMod))
                            {
                                res = sysImportMod;
                                continue;
                            }
                        }
                    }

                    if (!lookForFunctions)
                    {
                        // try include files
                        var foundInclude = false;
                        if (ast?.ProjectEntry != null)
                        {
                            foreach (var includeFile in ast.ProjectEntry.GetIncludedFiles())
                            {
                                if (includeFile.Analysis?.Body is IModuleResult)
                                {
                                    var mod = includeFile.Analysis.Body as IModuleResult;
                                    if ((getTypes && (mod.Types.TryGetValue(dotPiece, out res) || mod.GlobalTypes.TryGetValue(dotPiece, out res))) ||
                                        (getConstants && (mod.Constants.TryGetValue(dotPiece, out res) || mod.GlobalConstants.TryGetValue(dotPiece, out res))))
                                    {
                                        foundInclude = true;
                                        break;
                                    }
                                }
                            }
                        }
                        if (foundInclude)
                        {
                            continue;
                        }

                        if (ast?._databaseProvider != null)
                        {
                            res = ast._databaseProvider.GetTable(dotPiece);
                            if (res != null)
                            {
                                continue;
                            }
                        }
                    }

                    // Only do a public function search if the dotPiece is the whole text we're searching for
                    // I.e. no namespaces
                    if (lookForFunctions && dotPiece == exprText)
                    {
                        if (searchInFunctionProvider == FunctionProviderSearchMode.Search)
                        {
                            if (res == null && ast?._functionProvider != null)
                            {
                                // check for the function name in the function provider
                                var funcs = ast._functionProvider.GetFunction(dotPiece);
                                if (funcs != null)
                                {
                                    res = funcs.FirstOrDefault();
                                    if (res != null)
                                    {
                                        continue;
                                    }
                                }
                            }
                        }
                        else if (searchInFunctionProvider == FunctionProviderSearchMode.Deferred)
                        {
                            isDeferredFunction = true;
                        }
                    }

                    if (res == null)
                    {
                        break;
                    }
                }
            }

            return(res);
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Gets information about the available signatures for the given expression.
        /// </summary>
        /// <param name="exprText">The expression to get signatures for.</param>
        /// <param name="index">The 0-based absolute index into the file.</param>
        public override IEnumerable <IFunctionResult> GetSignaturesByIndex(string exprText, int index, IReverseTokenizer revTokenizer, IFunctionInformationProvider functionProvider)
        {
            _functionProvider = functionProvider;

            // First see if we're in the process of defining a function
            List <MemberResult> dummyList;

            if (TryFunctionDefContext(index, revTokenizer, out dummyList))
            {
                return(null);
            }

            /*
             * Need to check for:
             * 1) Functions within the current module
             * 2) Functions within the current project
             * 3) Public functions
             */
            if (_body is IModuleResult)
            {
                _body.SetNamespace(null);
                // check for module vars, types, and constants (and globals defined in this module)
                IModuleResult mod = _body as IModuleResult;

                // check for module functions
                IFunctionResult funcRes;
                if (mod.Functions.TryGetValue(exprText, out funcRes))
                {
                    return(new IFunctionResult[1] {
                        funcRes
                    });
                }
            }

            if (_projEntry != null && _projEntry is IGeneroProjectEntry)
            {
                IGeneroProjectEntry genProj = _projEntry as IGeneroProjectEntry;
                if (genProj.ParentProject != null &&
                    !genProj.FilePath.ToLower().EndsWith(".inc"))
                {
                    foreach (var projEntry in genProj.ParentProject.ProjectEntries.Where(x => x.Value != genProj))
                    {
                        if (projEntry.Value.Analysis != null &&
                            projEntry.Value.Analysis.Body != null)
                        {
                            projEntry.Value.Analysis.Body.SetNamespace(null);
                            IModuleResult modRes = projEntry.Value.Analysis.Body as IModuleResult;
                            if (modRes != null)
                            {
                                // check project functions
                                IFunctionResult funcRes;
                                if (modRes.Functions.TryGetValue(exprText, out funcRes))
                                {
                                    if (funcRes.AccessModifier == AccessModifier.Public)
                                    {
                                        return new IFunctionResult[1] {
                                                   funcRes
                                        }
                                    }
                                    ;
                                }
                            }
                        }
                    }
                }
            }

            // Check for class methods
            IGeneroProject  dummyProj;
            IProjectEntry   dummyProjEntry;
            bool            dummyDef;
            IAnalysisResult member = GetValueByIndex(exprText, index, _functionProvider, _databaseProvider, _programFileProvider, true, out dummyDef, out dummyProj, out dummyProjEntry);

            if (member is IFunctionResult)
            {
                return(new IFunctionResult[1] {
                    member as IFunctionResult
                });
            }
            else if (member is VariableDef &&
                     (member as VariableDef).Type != null)
            {
                var typeRef = (member as VariableDef).Type;
                if (typeRef.ResolvedType != null && typeRef.ResolvedType is TypeDefinitionNode)
                {
                    var tdn = typeRef.ResolvedType as TypeDefinitionNode;
                    if (tdn.TypeRef != null && tdn.TypeRef is FunctionTypeReference)
                    {
                        return(new IFunctionResult[1] {
                            tdn.TypeRef as FunctionTypeReference
                        });
                    }
                }
            }

            if (_functionProvider != null)
            {
                // check for the function name in the function provider
                var func = _functionProvider.GetFunction(exprText);
                if (func != null)
                {
                    return(func);
                }
            }

            return(null);
        }
Ejemplo n.º 23
0
        public static bool TryParseNode(Genero4glParser parser, out DialogControlBlock node,
                                        IModuleResult containingModule,
                                        List <Func <PrepareStatement, bool> > prepStatementBinders,
                                        Func <ReturnStatement, ParserResult> returnStatementBinder   = null,
                                        Action <IAnalysisResult, int, int> limitedScopeVariableAdder = null,
                                        List <TokenKind> validExitKeywords = null,
                                        IEnumerable <ContextStatementFactory> contextStatementFactories = null,
                                        HashSet <TokenKind> endKeywords = null)
        {
            node            = new DialogControlBlock();
            node.StartIndex = parser.Token.Span.Start;
            node.KeyNames   = new List <VirtualKey>();
            bool result = true;

            switch (parser.PeekToken().Kind)
            {
            case TokenKind.Ampersand:
            {
                // handle include file
                PreprocessorNode preNode;
                PreprocessorNode.TryParseNode(parser, out preNode);
                node.StartIndex = -1;
                break;
            }

            case TokenKind.BeforeKeyword:
            case TokenKind.AfterKeyword:
                parser.NextToken();
                if (parser.PeekToken(TokenKind.DialogKeyword))
                {
                    parser.NextToken();
                    node.Type = DialogControlBlockType.Dialog;
                }
                else
                {
                    parser.ReportSyntaxError("Expected \"dialog\" keyword in dialog statement.");
                }
                break;

            case TokenKind.CommandKeyword:
            {
                parser.NextToken();
                node.Type = DialogControlBlockType.Command;

                if (parser.PeekToken(TokenKind.KeyKeyword))
                {
                    parser.NextToken();
                    if (parser.PeekToken(TokenKind.LeftParenthesis))
                    {
                        parser.NextToken();
                        VirtualKey vKey;
                        while (VirtualKey.TryGetKey(parser, out vKey))
                        {
                            node.KeyNames.Add(vKey);
                            if (parser.PeekToken(TokenKind.Comma))
                            {
                                break;
                            }
                            parser.NextToken();
                        }
                    }
                    else
                    {
                        parser.ReportSyntaxError("Expecting left-paren in dialog statement.");
                    }
                }

                ExpressionNode FglNameExpression;
                if (FglExpressionNode.TryGetExpressionNode(parser, out FglNameExpression))
                {
                    node.OptionName = FglNameExpression;
                }
                else
                {
                    parser.ReportSyntaxError("Invalid expression found in dialog statement.");
                }

                if (!parser.PeekToken(TokenKind.HelpKeyword) && parser.PeekToken(TokenCategory.StringLiteral))
                {
                    ExpressionNode commentExpr;
                    if (FglExpressionNode.TryGetExpressionNode(parser, out commentExpr, new List <TokenKind> {
                            TokenKind.HelpKeyword
                        }))
                    {
                        node.OptionComment = commentExpr;
                    }
                    else
                    {
                        parser.ReportSyntaxError("Invalid expression found in dialog statement.");
                    }
                }

                if (parser.PeekToken(TokenKind.HelpKeyword))
                {
                    parser.NextToken();
                    ExpressionNode optionNumber;
                    if (FglExpressionNode.TryGetExpressionNode(parser, out optionNumber))
                    {
                        node.HelpNumber = optionNumber;
                    }
                    else
                    {
                        parser.ReportSyntaxError("Invalid expression found in dialog statement.");
                    }
                }

                break;
            }

            case TokenKind.OnKeyword:
            {
                parser.NextToken();
                switch (parser.PeekToken().Kind)
                {
                case TokenKind.ActionKeyword:
                    parser.NextToken();
                    node.Type = DialogControlBlockType.Action;
                    FglNameExpression nameExpr;
                    if (FglNameExpression.TryParseNode(parser, out nameExpr))
                    {
                        node.ActionName = nameExpr;
                    }
                    else
                    {
                        parser.ReportSyntaxError("Invalid name found in dialog statement.");
                    }
                    break;

                case TokenKind.KeyKeyword:
                    parser.NextToken();
                    node.Type = DialogControlBlockType.Key;
                    if (parser.PeekToken(TokenKind.LeftParenthesis))
                    {
                        parser.NextToken();
                        VirtualKey vKey;
                        while (VirtualKey.TryGetKey(parser, out vKey))
                        {
                            node.KeyNames.Add(vKey);
                            if (parser.PeekToken(TokenKind.Comma))
                            {
                                break;
                            }
                            parser.NextToken();
                        }
                    }
                    else
                    {
                        parser.ReportSyntaxError("Expecting left-paren in dialog statement.");
                    }
                    break;

                case TokenKind.IdleKeyword:
                    parser.NextToken();
                    node.Type = DialogControlBlockType.Idle;
                    // get the idle seconds
                    ExpressionNode idleExpr;
                    if (FglExpressionNode.TryGetExpressionNode(parser, out idleExpr))
                    {
                        node.IdleSeconds = idleExpr;
                    }
                    else
                    {
                        parser.ReportSyntaxError("Invalid idle-seconds found in dialog statement.");
                    }
                    break;

                default:
                    parser.ReportSyntaxError("Unexpected token found in dialog control block.");
                    break;
                }
                break;
            }

            default:
                break;
            }

            if (result && node.StartIndex >= 0)
            {
                // get the dialog statements
                FglStatement inputStmt;
                prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier);
                while (DialogStatementFactory.TryGetStatement(parser, out inputStmt, containingModule, prepStatementBinders, returnStatementBinder,
                                                              limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, endKeywords) && inputStmt != null)
                {
                    node.Children.Add(inputStmt.StartIndex, inputStmt);
                }
                prepStatementBinders.RemoveAt(0);

                if (node.Type == DialogControlBlockType.None && node.Children.Count == 0)
                {
                    result = false;
                }
            }

            return(result);
        }
Ejemplo n.º 24
0
        public static bool TryParseNode(Genero4glParser parser, out MenuBlock node,
                                        IModuleResult containingModule,
                                        List <Func <PrepareStatement, bool> > prepStatementBinders,
                                        Func <ReturnStatement, ParserResult> returnStatementBinder   = null,
                                        Action <IAnalysisResult, int, int> limitedScopeVariableAdder = null,
                                        List <TokenKind> validExitKeywords = null,
                                        IEnumerable <ContextStatementFactory> contextStatementFactories = null,
                                        HashSet <TokenKind> endKeywords = null)
        {
            node = null;
            bool result = false;

            if (parser.PeekToken(TokenKind.MenuKeyword))
            {
                result = true;
                node   = new MenuBlock();
                parser.NextToken();
                node.StartIndex = parser.Token.Span.Start;
                node.Attributes = new List <ExpressionNode>();

                if (parser.PeekToken(TokenCategory.StringLiteral))
                {
                    parser.NextToken();
                    node.MenuTitle = parser.Token.Token.Value.ToString();
                }

                node.DecoratorEnd = parser.Token.Span.End;

                if (parser.PeekToken(TokenKind.AttributesKeyword) ||
                    parser.PeekToken(TokenKind.AttributeKeyword))
                {
                    parser.NextToken();
                    if (parser.PeekToken(TokenKind.LeftParenthesis))
                    {
                        parser.NextToken();
                        ExpressionNode expr;
                        while (FglExpressionNode.TryGetExpressionNode(parser, out expr, new List <TokenKind> {
                            TokenKind.Comma, TokenKind.RightParenthesis
                        }))
                        {
                            node.Attributes.Add(expr);
                            if (!parser.PeekToken(TokenKind.Comma))
                            {
                                break;
                            }
                            parser.NextToken();
                        }

                        if (parser.PeekToken(TokenKind.RightParenthesis))
                        {
                            parser.NextToken();
                        }
                        else
                        {
                            parser.ReportSyntaxError("Expecting right-paren for menu attributes.");
                        }
                    }
                    else
                    {
                        parser.ReportSyntaxError("Expecting left-paren for menu attributes.");
                    }
                }

                List <TokenKind> validExits = new List <TokenKind>();
                if (validExitKeywords != null)
                {
                    validExits.AddRange(validExitKeywords);
                }
                validExits.Add(TokenKind.MenuKeyword);

                HashSet <TokenKind> newEndKeywords = new HashSet <TokenKind>();
                if (endKeywords != null)
                {
                    newEndKeywords.AddRange(endKeywords);
                }
                newEndKeywords.Add(TokenKind.MenuKeyword);

                int beforeStart = -1, beforeDecEnd = -1, beforeEnd = -1;
                if (parser.PeekToken(TokenKind.BeforeKeyword))
                {
                    parser.NextToken();
                    beforeStart = parser.Token.Span.Start;
                    if (parser.PeekToken(TokenKind.MenuKeyword))
                    {
                        parser.NextToken();
                        beforeDecEnd = parser.Token.Span.End;
                        FglStatement        menuStmt;
                        List <FglStatement> stmts = new List <FglStatement>();
                        prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier);
                        while (MenuStatementFactory.TryGetStatement(parser, out menuStmt, containingModule, prepStatementBinders, returnStatementBinder,
                                                                    limitedScopeVariableAdder, validExits, contextStatementFactories, newEndKeywords))
                        {
                            stmts.Add(menuStmt);
                            beforeEnd = menuStmt.EndIndex;
                        }
                        prepStatementBinders.RemoveAt(0);

                        if (beforeEnd < 0)
                        {
                            beforeEnd = beforeDecEnd;
                        }
                        MenuOption beforeMenu = new MenuOption(beforeStart, beforeDecEnd, beforeEnd, stmts);
                        if (beforeMenu != null)
                        {
                            node.Children.Add(beforeMenu.StartIndex, beforeMenu);
                        }
                    }
                    else
                    {
                        parser.ReportSyntaxError("Expecting \"before\" keyword for menu block.");
                    }
                }

                prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier);
                while (!parser.PeekToken(TokenKind.EndOfFile) &&
                       !(parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.MenuKeyword, 2)))
                {
                    MenuOption menuOpt;
                    if (MenuOption.TryParseNode(parser, out menuOpt, containingModule, prepStatementBinders, returnStatementBinder,
                                                limitedScopeVariableAdder, validExits, contextStatementFactories, newEndKeywords) && menuOpt != null)
                    {
                        if (menuOpt.StartIndex < 0)
                        {
                            continue;
                        }
                        node.Children.Add(menuOpt.StartIndex, menuOpt);
                    }
                    else if (parser.PeekToken(TokenKind.EndKeyword) && endKeywords != null && endKeywords.Contains(parser.PeekToken(2).Kind))
                    {
                        break;
                    }
                    else
                    {
                        parser.NextToken();
                    }
                }
                prepStatementBinders.RemoveAt(0);

                if (!(parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.MenuKeyword, 2)))
                {
                    parser.ReportSyntaxError("A menu block must be terminated with \"end menu\".");
                }
                else
                {
                    parser.NextToken(); // advance to the 'end' token
                    parser.NextToken(); // advance to the 'menu' token
                    node.EndIndex = parser.Token.Span.End;
                }
            }

            return(result);
        }
Ejemplo n.º 25
0
        public static bool TryParseNode(Genero4glParser parser, out ConstructControlBlock node,
                                        IModuleResult containingModule,
                                        List <Func <PrepareStatement, bool> > prepStatementBinders,
                                        Func <ReturnStatement, ParserResult> returnStatementBinder   = null,
                                        Action <IAnalysisResult, int, int> limitedScopeVariableAdder = null,
                                        List <TokenKind> validExitKeywords = null,
                                        IEnumerable <ContextStatementFactory> contextStatementFactories = null,
                                        HashSet <TokenKind> endKeywords = null)
        {
            node = new ConstructControlBlock();
            bool result = true;

            node.StartIndex    = parser.Token.Span.Start;
            node.FieldSpecList = new List <FglNameExpression>();
            node.KeyNameList   = new List <VirtualKey>();

            switch (parser.PeekToken().Kind)
            {
            case TokenKind.Ampersand:
            {
                // handle include file
                PreprocessorNode preNode;
                PreprocessorNode.TryParseNode(parser, out preNode);
                node.StartIndex = -1;
                break;
            }

            case TokenKind.BeforeKeyword:
            case TokenKind.AfterKeyword:
            {
                parser.NextToken();
                if (parser.PeekToken(TokenKind.FieldKeyword))
                {
                    parser.NextToken();
                    node.Type = ConstructControlBlockType.Field;
                    // get the list of field specs
                    FglNameExpression fieldSpec;
                    while (FglNameExpression.TryParseNode(parser, out fieldSpec))
                    {
                        node.FieldSpecList.Add(fieldSpec);
                        if (!parser.PeekToken(TokenKind.Comma))
                        {
                            break;
                        }
                        parser.NextToken();
                    }
                }
                else if (parser.PeekToken(TokenKind.ConstructKeyword))
                {
                    parser.NextToken();
                    node.Type = ConstructControlBlockType.Construct;
                }
                else
                {
                    parser.ReportSyntaxError("Unexpected token found in construct control block.");
                    result = false;
                }
                break;
            }

            case TokenKind.OnKeyword:
            {
                parser.NextToken();
                switch (parser.PeekToken().Kind)
                {
                case TokenKind.IdleKeyword:
                    parser.NextToken();
                    node.Type = ConstructControlBlockType.Idle;
                    // get the idle seconds
                    ExpressionNode idleExpr;
                    if (FglExpressionNode.TryGetExpressionNode(parser, out idleExpr))
                    {
                        node.IdleSeconds = idleExpr;
                    }
                    else
                    {
                        parser.ReportSyntaxError("Invalid idle-seconds found in construct statement.");
                    }
                    break;

                case TokenKind.ActionKeyword:
                    parser.NextToken();
                    node.Type = ConstructControlBlockType.Action;
                    // get the action name
                    FglNameExpression actionName;
                    if (FglNameExpression.TryParseNode(parser, out actionName))
                    {
                        node.ActionName = actionName;
                    }
                    else
                    {
                        parser.ReportSyntaxError("Invalid action-name found in construct statement.");
                    }
                    if (parser.PeekToken(TokenKind.InfieldKeyword))
                    {
                        parser.NextToken();
                        // get the field-spec
                        if (FglNameExpression.TryParseNode(parser, out actionName))
                        {
                            node.ActionField = actionName;
                        }
                        else
                        {
                            parser.ReportSyntaxError("Invalid field-spec found in construct statement.");
                        }
                    }
                    break;

                case TokenKind.KeyKeyword:
                    parser.NextToken();
                    node.Type = ConstructControlBlockType.Key;
                    if (parser.PeekToken(TokenKind.LeftParenthesis))
                    {
                        parser.NextToken();
                        // get the list of key names
                        VirtualKey keyName;
                        while (VirtualKey.TryGetKey(parser, out keyName))
                        {
                            node.KeyNameList.Add(keyName);
                            if (!parser.PeekToken(TokenKind.Comma))
                            {
                                break;
                            }
                            parser.NextToken();
                        }
                        if (parser.PeekToken(TokenKind.RightParenthesis))
                        {
                            parser.NextToken();
                        }
                        else
                        {
                            parser.ReportSyntaxError("Expected right-paren in construct control block.");
                        }
                    }
                    else
                    {
                        parser.ReportSyntaxError("Expected left-paren in construct control block.");
                    }
                    break;

                default:
                    parser.ReportSyntaxError("Unexpected token found in input control block.");
                    //result = false;
                    break;
                }
                break;
            }

            default:
                result = false;
                break;
            }

            if (result && node.StartIndex >= 0)
            {
                // get the dialog statements
                FglStatement inputStmt;
                prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier);
                while (ConstructDialogStatementFactory.TryGetStatement(parser, out inputStmt, containingModule, prepStatementBinders, returnStatementBinder,
                                                                       limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, endKeywords) && inputStmt != null)
                {
                    node.Children.Add(inputStmt.StartIndex, inputStmt);
                }
                prepStatementBinders.RemoveAt(0);

                if (node.Type == ConstructControlBlockType.None && node.Children.Count == 0)
                {
                    result = false;
                }
            }

            return(result);
        }
Ejemplo n.º 26
0
        public static bool TryParseNode(Genero4glParser parser, out IfStatement node,
                                        IModuleResult containingModule,
                                        List <Func <PrepareStatement, bool> > prepStatementBinders,
                                        Func <ReturnStatement, ParserResult> returnStatementBinder   = null,
                                        Action <IAnalysisResult, int, int> limitedScopeVariableAdder = null,
                                        List <TokenKind> validExitKeywords = null,
                                        IEnumerable <ContextStatementFactory> contextStatementFactories = null,
                                        ExpressionParsingOptions expressionOptions = null,
                                        HashSet <TokenKind> endKeywords            = null)
        {
            node = null;
            bool result = false;

            if (parser.PeekToken(TokenKind.IfKeyword))
            {
                result = true;
                node   = new IfStatement();
                parser.NextToken();
                node.StartIndex = parser.Token.Span.Start;

                ExpressionNode conditionExpr;
                if (!FglExpressionNode.TryGetExpressionNode(parser, out conditionExpr, new List <TokenKind> {
                    TokenKind.ThenKeyword
                }, expressionOptions))
                {
                    parser.ReportSyntaxError("An if statement must have a condition expression.");
                }
                else
                {
                    node.ConditionExpression = conditionExpr;
                }

                if (parser.PeekToken(TokenKind.ThenKeyword))
                {
                    parser.NextToken();

                    node.DecoratorEnd = parser.Token.Span.End;

                    HashSet <TokenKind> newEndKeywords = new HashSet <TokenKind>();
                    if (endKeywords != null)
                    {
                        newEndKeywords.AddRange(endKeywords);
                    }
                    newEndKeywords.Add(TokenKind.IfKeyword);

                    IfBlockContentsNode ifBlock;
                    prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier);
                    if (IfBlockContentsNode.TryParseNode(parser, out ifBlock, containingModule, prepStatementBinders, returnStatementBinder,
                                                         limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, expressionOptions, newEndKeywords))
                    {
                        if (ifBlock != null)
                        {
                            node.Children.Add(ifBlock.StartIndex, ifBlock);
                        }
                    }

                    if (parser.PeekToken(TokenKind.ElseKeyword))
                    {
                        parser.NextToken();
                        ElseBlockContentsNode elseBlock;
                        if (ElseBlockContentsNode.TryParseNode(parser, out elseBlock, containingModule, prepStatementBinders, returnStatementBinder,
                                                               limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, expressionOptions, newEndKeywords))
                        {
                            if (elseBlock != null)
                            {
                                node.Children.Add(elseBlock.StartIndex, elseBlock);

                                // Add the span of "else" to the additional decorators
                                node.AdditionalDecoratorRanges.Add(elseBlock.StartIndex, elseBlock.StartIndex + 4);
                            }
                        }
                    }
                    prepStatementBinders.RemoveAt(0);

                    if (!(parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.IfKeyword, 2)))
                    {
                        parser.ReportSyntaxError("An if statement must be terminated with \"end if\".");
                    }
                    else
                    {
                        parser.NextToken(); // advance to the 'end' token
                        parser.NextToken(); // advance to the 'if' token
                        node.EndIndex = parser.Token.Span.End;
                    }
                }
                else
                {
                    parser.ReportSyntaxError("An if statement must have a \"then\" keyword prior to containing code.");
                }
            }

            return(result);
        }
Ejemplo n.º 27
0
        public bool TryParseNode(Genero4glParser parser,
                                 out FglStatement node,
                                 IModuleResult containingModule,
                                 List <Func <PrepareStatement, bool> > prepStatementBinders,
                                 Func <ReturnStatement, ParserResult> returnStatementBinder   = null,
                                 Action <IAnalysisResult, int, int> limitedScopeVariableAdder = null,
                                 bool returnStatementsOnly          = false,
                                 List <TokenKind> validExitKeywords = null,
                                 IEnumerable <ContextStatementFactory> contextStatementFactories = null,
                                 ExpressionParsingOptions expressionOptions = null,
                                 HashSet <TokenKind> endKeywords            = null)
        {
            node = null;
            bool result = false;

            if (returnStatementsOnly)
            {
                if (parser.PeekToken(TokenKind.ReturnKeyword))
                {
                    ReturnStatement retStmt;
                    if ((result = ReturnStatement.TryParseNode(parser, out retStmt)))
                    {
                        node = retStmt;
                    }
                }
                return(result);
            }

            if (contextStatementFactories != null)
            {
                foreach (var context in contextStatementFactories)
                {
                    node = context(parser);
                    if (node != null)
                    {
                        break;
                    }
                }
                if (node != null)
                {
                    return(true);
                }
            }

            switch (parser.PeekToken().Kind)
            {
            case TokenKind.LetKeyword:
            {
                LetStatement letStmt;
                if ((result = LetStatement.TryParseNode(parser, out letStmt, expressionOptions)))
                {
                    node = letStmt;
                }
                break;
            }

            case TokenKind.DeclareKeyword:
            {
                DeclareStatement declStmt;
                if ((result = DeclareStatement.TryParseNode(parser, out declStmt, containingModule)))
                {
                    node = declStmt;
                }
                break;
            }

            case TokenKind.DeferKeyword:
            {
                DeferStatementNode deferStmt;
                if ((result = DeferStatementNode.TryParseNode(parser, out deferStmt)))
                {
                    node = deferStmt;
                }
                break;
            }

            case TokenKind.PrepareKeyword:
            {
                PrepareStatement prepStmt;
                if ((result = PrepareStatement.TryParseNode(parser, out prepStmt, containingModule)))
                {
                    node = prepStmt;
                    foreach (var binder in prepStatementBinders)
                    {
                        if (binder(prepStmt))
                        {
                            break;
                        }
                    }
                }
                break;
            }

            case TokenKind.SqlKeyword:
            {
                SqlBlockNode sqlStmt;
                if ((result = SqlBlockNode.TryParseSqlNode(parser, out sqlStmt)))
                {
                    node = sqlStmt;
                }
                break;
            }

            case TokenKind.ReturnKeyword:
            {
                ReturnStatement retStmt;
                if ((result = ReturnStatement.TryParseNode(parser, out retStmt)))
                {
                    if (returnStatementBinder != null)
                    {
                        var parseResult = returnStatementBinder(retStmt);
                        if (!parseResult.Success && !string.IsNullOrWhiteSpace(parseResult.ErrorMessage))
                        {
                            parser.ReportSyntaxError(parseResult.ErrorMessage);
                        }
                    }
                    node = retStmt;
                }
                break;
            }

            case TokenKind.CallKeyword:
            {
                CallStatement callStmt;
                if ((result = CallStatement.TryParseNode(parser, out callStmt)))
                {
                    node = callStmt;
                }
                break;
            }

            case TokenKind.IfKeyword:
            {
                IfStatement ifStmt;
                if ((result = IfStatement.TryParseNode(parser, out ifStmt, containingModule, prepStatementBinders, returnStatementBinder,
                                                       limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, expressionOptions, endKeywords)))
                {
                    node = ifStmt;
                }
                break;
            }

            case TokenKind.WhileKeyword:
            {
                WhileStatement whileStmt;
                if ((result = WhileStatement.TryParseNode(parser, out whileStmt, containingModule, prepStatementBinders, returnStatementBinder,
                                                          limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, expressionOptions, endKeywords)))
                {
                    node = whileStmt;
                }
                break;
            }

            case TokenKind.ExitKeyword:
            {
                ExitStatement exitStatement;
                if ((result = ExitStatement.TryParseNode(parser, out exitStatement)))
                {
                    node = exitStatement;
                }
                break;
            }

            case TokenKind.ContinueKeyword:
            {
                ContinueStatement contStmt;
                if ((result = ContinueStatement.TryParseNode(parser, out contStmt)))
                {
                    node = contStmt;
                }
                break;
            }

            case TokenKind.WheneverKeyword:
            {
                WheneverStatement wheneverStmt;
                if ((result = WheneverStatement.TryParseNode(parser, out wheneverStmt)))
                {
                    node = wheneverStmt;
                }
                break;
            }

            case TokenKind.ForKeyword:
            {
                ForStatement forStmt;
                if ((result = ForStatement.TryParserNode(parser, out forStmt, containingModule, prepStatementBinders, returnStatementBinder,
                                                         limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, expressionOptions, endKeywords)))
                {
                    node = forStmt;
                }
                break;
            }

            case TokenKind.CaseKeyword:
            {
                CaseStatement caseStmt;
                if ((result = CaseStatement.TryParseNode(parser, out caseStmt, containingModule, prepStatementBinders, returnStatementBinder,
                                                         limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, expressionOptions, endKeywords)))
                {
                    node = caseStmt;
                }
                break;
            }

            case TokenKind.InitializeKeyword:
            {
                InitializeStatement initStmt;
                if ((result = InitializeStatement.TryParseNode(parser, out initStmt)))
                {
                    node = initStmt;
                }
                break;
            }

            case TokenKind.LocateKeyword:
            {
                LocateStatement locateStmt;
                if ((result = LocateStatement.TryParseNode(parser, out locateStmt)))
                {
                    node = locateStmt;
                }
                break;
            }

            case TokenKind.FreeKeyword:
            {
                FreeStatement freeStmt;
                if ((result = FreeStatement.TryParseNode(parser, out freeStmt)))
                {
                    node = freeStmt;
                }
                break;
            }

            case TokenKind.GotoKeyword:
            {
                GotoStatement gotoStmt;
                if ((result = GotoStatement.TryParseNode(parser, out gotoStmt)))
                {
                    node = gotoStmt;
                }
                break;
            }

            case TokenKind.LabelKeyword:
            {
                LabelStatement labelStmt;
                if ((result = LabelStatement.TryParseNode(parser, out labelStmt)))
                {
                    node = labelStmt;
                }
                break;
            }

            case TokenKind.SleepKeyword:
            {
                SleepStatement sleepStmt;
                if ((result = SleepStatement.TryParseNode(parser, out sleepStmt)))
                {
                    node = sleepStmt;
                }
                break;
            }

            case TokenKind.TryKeyword:
            {
                TryCatchStatement tryStmt;
                if ((result = TryCatchStatement.TryParseNode(parser, out tryStmt, containingModule, prepStatementBinders, returnStatementBinder,
                                                             limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, endKeywords)))
                {
                    node = tryStmt;
                }
                break;
            }

            case TokenKind.ValidateKeyword:
            {
                ValidateStatement validateStmt;
                if ((result = ValidateStatement.TryParseNode(parser, out validateStmt)))
                {
                    node = validateStmt;
                }
                break;
            }

            case TokenKind.OptionsKeyword:
            {
                OptionsStatement optionsStmt;
                if ((result = OptionsStatement.TryParseNode(parser, out optionsStmt)))
                {
                    node = optionsStmt;
                }
                break;
            }

            case TokenKind.ExecuteKeyword:
            {
                ExecuteStatement exeStmt;
                if ((result = ExecuteStatement.TryParseNode(parser, out exeStmt)))
                {
                    node = exeStmt;
                }
                break;
            }

            case TokenKind.OpenKeyword:
            {
                OpenStatement openStmt;
                if ((result = OpenStatement.TryParseNode(parser, out openStmt)))
                {
                    node = openStmt;
                }
                break;
            }

            case TokenKind.FetchKeyword:
            {
                FetchStatement fetchStmt;
                if ((result = FetchStatement.TryParseNode(parser, out fetchStmt)))
                {
                    node = fetchStmt;
                }
                break;
            }

            case TokenKind.CloseKeyword:
            {
                CloseStatement closeStmt;
                if ((result = CloseStatement.TryParseNode(parser, out closeStmt)))
                {
                    node = closeStmt;
                }
                break;
            }

            case TokenKind.ClearKeyword:
            {
                ClearStatement clearStmt;
                if ((result = ClearStatement.TryParseNode(parser, out clearStmt)))
                {
                    node = clearStmt;
                }
                break;
            }

            case TokenKind.ForeachKeyword:
            {
                ForeachStatement foreachStmt;
                if ((result = ForeachStatement.TryParseNode(parser, out foreachStmt, containingModule, prepStatementBinders, returnStatementBinder,
                                                            limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, endKeywords)))
                {
                    node = foreachStmt;
                }
                break;
            }

            case TokenKind.MessageKeyword:
            {
                MessageStatement msgStmt;
                if ((result = MessageStatement.TryParseNode(parser, out msgStmt)))
                {
                    node = msgStmt;
                }
                break;
            }

            case TokenKind.MenuKeyword:
            {
                MenuBlock menuStmt;
                if ((result = MenuBlock.TryParseNode(parser, out menuStmt, containingModule, prepStatementBinders, returnStatementBinder,
                                                     limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, endKeywords)))
                {
                    node = menuStmt;
                    if (limitedScopeVariableAdder != null)
                    {
                        limitedScopeVariableAdder(Genero4glAst.DialogVariable, node.StartIndex, node.EndIndex);
                    }
                }
                break;
            }

            case TokenKind.InputKeyword:
            {
                InputBlock inputStmt;
                if ((result = InputBlock.TryParseNode(parser, out inputStmt, containingModule, prepStatementBinders, returnStatementBinder,
                                                      limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, endKeywords)))
                {
                    node = inputStmt;
                    if (limitedScopeVariableAdder != null)
                    {
                        limitedScopeVariableAdder(Genero4glAst.DialogVariable, node.StartIndex, node.EndIndex);
                    }
                }
                break;
            }

            case TokenKind.ConstructKeyword:
            {
                ConstructBlock constructStmt;
                if ((result = ConstructBlock.TryParseNode(parser, out constructStmt, containingModule, prepStatementBinders, returnStatementBinder,
                                                          limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, endKeywords)))
                {
                    node = constructStmt;
                    if (limitedScopeVariableAdder != null)
                    {
                        limitedScopeVariableAdder(Genero4glAst.DialogVariable, node.StartIndex, node.EndIndex);
                    }
                }
                break;
            }

            case TokenKind.FlushKeyword:
            {
                FlushStatement flushStmt;
                if ((result = FlushStatement.TryParseNode(parser, out flushStmt)))
                {
                    node = flushStmt;
                }
                break;
            }

            case TokenKind.DisplayKeyword:
            {
                DisplayBlock dispStmt;
                if ((result = DisplayBlock.TryParseNode(parser, out dispStmt, containingModule, prepStatementBinders, returnStatementBinder,
                                                        limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, endKeywords)))
                {
                    node = dispStmt;
                    if (limitedScopeVariableAdder != null)
                    {
                        limitedScopeVariableAdder(Genero4glAst.DialogVariable, node.StartIndex, node.EndIndex);
                    }
                }
                break;
            }

            case TokenKind.PromptKeyword:
            {
                PromptStatement promptStmt;
                if ((result = PromptStatement.TryParseNode(parser, out promptStmt, containingModule, prepStatementBinders, returnStatementBinder,
                                                           limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, endKeywords)))
                {
                    node = promptStmt;
                    if (limitedScopeVariableAdder != null)
                    {
                        limitedScopeVariableAdder(Genero4glAst.DialogVariable, node.StartIndex, node.EndIndex);
                    }
                }
                break;
            }

            case TokenKind.DialogKeyword:
            {
                DialogBlock dialogBlock;
                if ((result = DialogBlock.TryParseNode(parser, out dialogBlock, containingModule, prepStatementBinders, returnStatementBinder,
                                                       limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, endKeywords)))
                {
                    node = dialogBlock;
                    if (limitedScopeVariableAdder != null)
                    {
                        limitedScopeVariableAdder(Genero4glAst.DialogVariable, node.StartIndex, node.EndIndex);
                    }
                }
                break;
            }

            case TokenKind.AcceptKeyword:
            {
                AcceptStatement acceptStmt;
                if ((result = AcceptStatement.TryParseNode(parser, out acceptStmt)))
                {
                    node = acceptStmt;
                }
                break;
            }

            case TokenKind.LoadKeyword:
            {
                LoadStatement loadStmt;
                if ((result = LoadStatement.TryParseNode(parser, out loadStmt)))
                {
                    node = loadStmt;
                }
                break;
            }

            case TokenKind.CreateKeyword:
            {
                CreateStatement createStmt;
                if ((result = CreateStatement.TryParseNode(parser, out createStmt, containingModule)))
                {
                    node = createStmt;
                }
                break;
            }

            case TokenKind.BreakpointKeyword:
            {
                BreakpointStatement brkStmt;
                if ((result = BreakpointStatement.TryParseNode(parser, out brkStmt)))
                {
                    node = brkStmt;
                }
                break;
            }

            case TokenKind.OutputKeyword:
            {
                OutputToReportStatement outRpt;
                if ((result = OutputToReportStatement.TryParseNode(parser, out outRpt)))
                {
                    node = outRpt;
                }
                break;
            }

            case TokenKind.StartKeyword:
            {
                StartReportStatement startRpt;
                if ((result = StartReportStatement.TryParseNode(parser, out startRpt)))
                {
                    node = startRpt;
                }
                break;
            }

            case TokenKind.FinishKeyword:
            {
                FinishReportStatement finRpt;
                if ((result = FinishReportStatement.TryParseNode(parser, out finRpt)))
                {
                    node = finRpt;
                }
                break;
            }

            case TokenKind.TerminateKeyword:
            {
                TerminateReportStatement termRpt;
                if ((result = TerminateReportStatement.TryParseNode(parser, out termRpt)))
                {
                    node = termRpt;
                }
                break;
            }

            default:
            {
                if (SqlStatementFactory.IsValidStatementStart(parser.PeekToken().Kind))
                {
                    bool dummy;
                    result = SqlStatementFactory.TryParseSqlStatement(parser, out node, out dummy);
                }
                break;
            }
            }

            if (result)
            {
                // check for semicolon
                if (parser.PeekToken(TokenKind.Semicolon))
                {
                    parser.NextToken();
                }
            }

            return(result);
        }
Ejemplo n.º 28
0
        public static bool TryParseNode(Genero4glParser parser, out CreateStatement node, IModuleResult containingModule)
        {
            node = null;
            bool result = true;

            if (parser.PeekToken(TokenKind.CreateKeyword))
            {
                parser.NextToken();
                switch (parser.PeekToken().Kind)
                {
                case TokenKind.SequenceKeyword:
                    CreateSequenceStatement sequenceNode;
                    result = CreateSequenceStatement.TryParseNode(parser, out sequenceNode);
                    node   = sequenceNode;
                    break;

                case TokenKind.TableKeyword:
                case TokenKind.TempKeyword:
                    CreateTableStatement tableNode;
                    result = CreateTableStatement.TryParseNode(parser, out tableNode, containingModule);
                    node   = tableNode;
                    break;

                default:
                    result = false;
                    break;
                }
            }

            return(result);
        }
Ejemplo n.º 29
0
        public static bool TryParseNode(Genero4glParser parser, out DisplayControlBlock node, IModuleResult containingModule, bool allowNonControlBlocks,
                                        bool isArray,
                                        List <Func <PrepareStatement, bool> > prepStatementBinders,
                                        Func <ReturnStatement, ParserResult> returnStatementBinder   = null,
                                        Action <IAnalysisResult, int, int> limitedScopeVariableAdder = null,
                                        List <TokenKind> validExitKeywords = null,
                                        IEnumerable <ContextStatementFactory> contextStatementFactories = null,
                                        HashSet <TokenKind> endKeywords = null)
        {
            node = new DisplayControlBlock();
            bool result = true;

            node.KeyNameList = new List <VirtualKey>();

            bool isDragAndDrop = false;

            switch (parser.PeekToken().Kind)
            {
            case TokenKind.Ampersand:
            {
                // handle include file
                PreprocessorNode preNode;
                PreprocessorNode.TryParseNode(parser, out preNode);
                node.StartIndex = -1;
                break;
            }

            case TokenKind.BeforeKeyword:
            case TokenKind.AfterKeyword:
            {
                parser.NextToken();
                node.StartIndex = parser.Token.Span.Start;
                if (parser.PeekToken(TokenKind.DisplayKeyword))
                {
                    parser.NextToken();
                    node.Type = DisplayControlBlockType.Display;
                }
                else if (parser.PeekToken(TokenKind.RowKeyword))
                {
                    parser.NextToken();
                    node.Type = DisplayControlBlockType.Row;
                }
                else
                {
                    parser.ReportSyntaxError("Unexpected keyword found in display control block.");
                    result = false;
                }
                break;
            }

            case TokenKind.OnKeyword:
            {
                parser.NextToken();
                node.StartIndex = parser.Token.Span.Start;
                switch (parser.PeekToken().Kind)
                {
                case TokenKind.IdleKeyword:
                    parser.NextToken();
                    node.Type = DisplayControlBlockType.Idle;
                    // get the idle seconds
                    ExpressionNode idleExpr;
                    if (FglExpressionNode.TryGetExpressionNode(parser, out idleExpr))
                    {
                        node.IdleSeconds = idleExpr;
                    }
                    else
                    {
                        parser.ReportSyntaxError("Invalid idle-seconds found in display array statement.");
                    }
                    break;

                case TokenKind.TimerKeyword:
                    parser.NextToken();
                    node.Type = DisplayControlBlockType.Timer;
                    // get the timer seconds
                    ExpressionNode timerExpr;
                    if (FglExpressionNode.TryGetExpressionNode(parser, out timerExpr))
                    {
                        node.TimerSeconds = timerExpr;
                    }
                    else
                    {
                        parser.ReportSyntaxError("Invalid timer-seconds found in display array statement.");
                    }
                    break;

                case TokenKind.ActionKeyword:
                    parser.NextToken();
                    node.Type = DisplayControlBlockType.Action;
                    // get the action name
                    FglNameExpression actionName;
                    if (FglNameExpression.TryParseNode(parser, out actionName))
                    {
                        node.ActionName = actionName;
                    }
                    else
                    {
                        parser.ReportSyntaxError("Invalid action-name found in display array statement.");
                    }
                    GetActionAttributesDisplayArray(parser);
                    break;

                case TokenKind.KeyKeyword:
                    parser.NextToken();
                    node.Type = DisplayControlBlockType.Key;
                    if (parser.PeekToken(TokenKind.LeftParenthesis))
                    {
                        parser.NextToken();
                        // get the list of key names
                        VirtualKey keyName;
                        while (VirtualKey.TryGetKey(parser, out keyName))
                        {
                            node.KeyNameList.Add(keyName);
                            if (!parser.PeekToken(TokenKind.Comma))
                            {
                                break;
                            }
                            parser.NextToken();
                        }
                        if (parser.PeekToken(TokenKind.RightParenthesis))
                        {
                            parser.NextToken();
                        }
                        else
                        {
                            parser.ReportSyntaxError("Expected right-paren in display array block.");
                        }
                    }
                    else
                    {
                        parser.ReportSyntaxError("Expected left-paren in display array block.");
                    }
                    break;

                case TokenKind.AppendKeyword:
                    node.Type = DisplayControlBlockType.Append;
                    parser.NextToken();
                    GetActionAttributesListmodTriggers(parser);
                    break;

                case TokenKind.InsertKeyword:
                    node.Type = DisplayControlBlockType.Insert;
                    parser.NextToken();
                    GetActionAttributesListmodTriggers(parser);
                    break;

                case TokenKind.UpdateKeyword:
                    node.Type = DisplayControlBlockType.Update;
                    parser.NextToken();
                    GetActionAttributesListmodTriggers(parser);
                    break;

                case TokenKind.DeleteKeyword:
                    node.Type = DisplayControlBlockType.Delete;
                    parser.NextToken();
                    GetActionAttributesListmodTriggers(parser);
                    break;

                case TokenKind.ExpandKeyword:
                    node.Type = DisplayControlBlockType.Expand;
                    parser.NextToken();
                    if (parser.PeekToken(TokenKind.LeftParenthesis))
                    {
                        parser.NextToken();
                        FglNameExpression rowInd;
                        if (FglNameExpression.TryParseNode(parser, out rowInd))
                        {
                            node.RowIndex = rowInd;
                        }
                        else
                        {
                            parser.ReportSyntaxError("Invalid row-index found in display array statement.");
                        }

                        if (parser.PeekToken(TokenKind.RightParenthesis))
                        {
                            parser.NextToken();
                        }
                        else
                        {
                            parser.ReportSyntaxError("Expected right-paren in display array statement.");
                        }
                    }
                    else
                    {
                        parser.ReportSyntaxError("Expected left-paren in display array statement.");
                    }
                    break;

                case TokenKind.CollapseKeyword:
                    node.Type = DisplayControlBlockType.Collapse;
                    parser.NextToken();
                    if (parser.PeekToken(TokenKind.LeftParenthesis))
                    {
                        parser.NextToken();
                        FglNameExpression rowInd1;
                        if (FglNameExpression.TryParseNode(parser, out rowInd1))
                        {
                            node.RowIndex = rowInd1;
                        }
                        else
                        {
                            parser.ReportSyntaxError("Invalid row-index found in display array statement.");
                        }
                        if (parser.PeekToken(TokenKind.RightParenthesis))
                        {
                            parser.NextToken();
                        }
                        else
                        {
                            parser.ReportSyntaxError("Expected right-paren in display array statement.");
                        }
                    }
                    else
                    {
                        parser.ReportSyntaxError("Expected left-paren in display array statement.");
                    }
                    break;

                case TokenKind.Drag_EnterKeyword:
                    node.Type = DisplayControlBlockType.DragEnter;
                    parser.NextToken();
                    isDragAndDrop = true;
                    break;

                case TokenKind.Drag_FinishKeyword:
                case TokenKind.Drag_FinishedKeyword:
                    node.Type = DisplayControlBlockType.DragFinish;
                    parser.NextToken();
                    isDragAndDrop = true;
                    break;

                case TokenKind.Drag_OverKeyword:
                    node.Type = DisplayControlBlockType.DragOver;
                    parser.NextToken();
                    isDragAndDrop = true;
                    break;

                case TokenKind.Drag_StartKeyword:
                    node.Type = DisplayControlBlockType.DragStart;
                    parser.NextToken();
                    isDragAndDrop = true;
                    break;

                case TokenKind.DropKeyword:
                    node.Type = DisplayControlBlockType.Drop;
                    parser.NextToken();
                    isDragAndDrop = true;
                    break;

                default:
                    parser.ReportSyntaxError("Unexpected token found in input control block.");
                    result = false;
                    break;
                }
                break;
            }

            default:
                if (!allowNonControlBlocks)
                {
                    result = false;
                }
                else
                {
                    node.StartIndex = parser.Token.Span.Start;
                }
                break;
            }

            if (result && node.StartIndex >= 0)
            {
                node.DecoratorEnd = parser.Token.Span.End;
                if (isDragAndDrop)
                {
                    if (parser.PeekToken(TokenKind.LeftParenthesis))
                    {
                        parser.NextToken();
                        FglNameExpression keyName;
                        if (FglNameExpression.TryParseNode(parser, out keyName))
                        {
                            node.DragAndDropObject = keyName;
                        }
                        else
                        {
                            parser.ReportSyntaxError("Invalid drag-and-drop object name found in display array statement.");
                        }

                        if (parser.PeekToken(TokenKind.RightParenthesis))
                        {
                            parser.NextToken();
                        }
                        else
                        {
                            parser.ReportSyntaxError("Expected right-paren in input control block.");
                        }
                    }
                    else
                    {
                        parser.ReportSyntaxError("Expected left-paren in input control block.");
                    }
                }

                // get the dialog statements
                FglStatement dispStmt;
                prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier);
                while (DisplayStatementFactory.TryGetStatement(parser, out dispStmt, isArray, containingModule, prepStatementBinders, returnStatementBinder,
                                                               limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, endKeywords) && dispStmt != null)
                {
                    node.Children.Add(dispStmt.StartIndex, dispStmt);
                    node.EndIndex = dispStmt.EndIndex;
                }
                prepStatementBinders.RemoveAt(0);

                if (node.Type == DisplayControlBlockType.None && node.Children.Count == 0)
                {
                    result = false;
                }
            }

            return(result);
        }
Ejemplo n.º 30
0
        public static bool TryParseNode(Genero4glParser parser, out TryCatchStatement defNode,
                                        IModuleResult containingModule,
                                        List <Func <PrepareStatement, bool> > prepStatementBinders,
                                        Func <ReturnStatement, ParserResult> returnStatementBinder   = null,
                                        Action <IAnalysisResult, int, int> limitedScopeVariableAdder = null,
                                        List <TokenKind> validExitKeywords = null,
                                        IEnumerable <ContextStatementFactory> contextStatementFactories = null,
                                        HashSet <TokenKind> endKeywords = null)
        {
            defNode = null;
            bool result = false;

            if (parser.PeekToken(TokenKind.TryKeyword))
            {
                result  = true;
                defNode = new TryCatchStatement();
                parser.NextToken();
                defNode.StartIndex   = parser.Token.Span.Start;
                defNode.DecoratorEnd = parser.Token.Span.End;

                HashSet <TokenKind> newEndKeywords = new HashSet <TokenKind>();
                if (endKeywords != null)
                {
                    newEndKeywords.AddRange(endKeywords);
                }
                newEndKeywords.Add(TokenKind.TryKeyword);

                prepStatementBinders.Insert(0, defNode.BindPrepareCursorFromIdentifier);

                TryBlock tryBlock;
                if (TryBlock.TryParseNode(parser, out tryBlock, containingModule, prepStatementBinders, returnStatementBinder,
                                          limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, newEndKeywords) && tryBlock != null)
                {
                    defNode.Children.Add(tryBlock.StartIndex, tryBlock);
                }

                if (parser.PeekToken(TokenKind.CatchKeyword))
                {
                    parser.NextToken();
                    CatchBlock catchBlock;
                    if (CatchBlock.TryParseNode(parser, out catchBlock, containingModule, prepStatementBinders, returnStatementBinder,
                                                limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, newEndKeywords) && catchBlock != null)
                    {
                        defNode.Children.Add(catchBlock.StartIndex, catchBlock);

                        // add the catch block to the additional decorators
                        defNode.AdditionalDecoratorRanges.Add(catchBlock.StartIndex, catchBlock.StartIndex + 5);
                    }
                }

                prepStatementBinders.RemoveAt(0);

                if (parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.TryKeyword, 2))
                {
                    parser.NextToken();
                    parser.NextToken();
                }
                else
                {
                    parser.ReportSyntaxError("Invalid end of try-catch block found.");
                }
                defNode.EndIndex = parser.Token.Span.End;
            }

            return(result);
        }