示例#1
0
 private void CheckNoGlobalOrExternal(DataDivision node)
 {
     if (node == null)
     {
         return;                              // no DATA DIVISION
     }
     foreach (var section in node.Children()) // "storage" sections
     {
         foreach (var child in section.Children)
         {
             var data = child.CodeElement as DataDescriptionEntry;
             if (data == null)
             {
                 continue;
             }
             if (data.IsGlobal)             // TCRFUN_DECLARATION_NO_GLOBAL
             {
                 DiagnosticUtils.AddError(data, "Illegal GLOBAL clause in function data item.");
             }
             if (data.IsExternal)             // TCRFUN_DECLARATION_NO_EXTERNAL
             {
                 DiagnosticUtils.AddError(data, "Illegal EXTERNAL clause in function data item.");
             }
         }
     }
 }
        public void OnNode([NotNull] Node node, ParserRuleContext context, CodeModel.Program program)
        {
            var functionDeclaration = node as FunctionDeclaration;

            if (functionDeclaration == null)
            {
                return;                              //not my job
            }
            var header = node.CodeElement as FunctionDeclarationHeader;

            if (header == null)
            {
                return;                 //not my job
            }
            var filesection = node.Get <FileSection>("file");

            if (filesection != null)     // TCRFUN_DECLARATION_NO_FILE_SECTION
            {
                DiagnosticUtils.AddError(filesection,
                                         "Illegal FILE SECTION in function \"" + header.Name + "\" declaration",
                                         context);
            }

            CheckNoGlobalOrExternal(node.Get <DataDivision>("data-division"));
            CheckNoLinkageItemIsAParameter(node.Get <LinkageSection>("linkage"), header.Profile);
        }
示例#3
0
        public static void OnNode(FunctionDeclaration functionDeclaration)
        {
            var header = functionDeclaration?.CodeElement as FunctionDeclarationHeader;

            if (header == null)
            {
                return;                 //not my job
            }
            var filesection = functionDeclaration.Get <FileSection>("file");

            if (filesection != null) // TCRFUN_DECLARATION_NO_FILE_SECTION
            {
                DiagnosticUtils.AddError(filesection,
                                         "Illegal FILE SECTION in function \"" + header.Name + "\" declaration");
            }

            CheckNoGlobalOrExternal(functionDeclaration.Get <DataDivision>("data-division"));
            CheckNoLinkageItemIsAParameter(functionDeclaration.Get <LinkageSection>("linkage"), header.Profile);

            CheckParameters(header.Profile, functionDeclaration);
            CheckNoPerform(functionDeclaration.SymbolTable.EnclosingScope, functionDeclaration);

            var headerNameURI = new URI(header.Name);
            var functions     = functionDeclaration.SymbolTable.GetFunction(headerNameURI, functionDeclaration.Profile);

            if (functions.Count > 1)
            {
                DiagnosticUtils.AddError(functionDeclaration,
                                         "A function \"" + headerNameURI.Head + "\" with the same profile already exists in namespace \"" +
                                         headerNameURI.Tail + "\".");
            }
        }
示例#4
0
        public void OnCodeElement(CodeElement e, ParserRuleContext ctxt)
        {
            var statement = e as CancelStatement;

            if (statement == null)
            {
                return; //not our job
            }
            var context = ctxt as CodeElementsParser.CancelStatementContext;

            foreach (var item in statement.Programs)
            {
                if (item == null)
                {
                    continue;                              //TODO#249
                }
                if (item.SymbolReference == null)
                {
                    continue;                                              // DO nothing
                }
                if (string.IsNullOrWhiteSpace(item.SymbolReference.Name) || item.SymbolReference.Name.IsNumeric())
                {
                    // we should link this error to the specific context.identifierOrLiteral[i] context
                    // corresponding to statement.Items[i], but since refactor in #157 it's not trivial anymore
                    DiagnosticUtils.AddError(statement, "CANCEL: <program name> must be alphanumeric", context);
                }
            }
        }
示例#5
0
        public void OnCodeElement(CodeElement e, ParserRuleContext c)
        {
            var data = e as DataRenamesEntry;

            if (data == null)
            {
                return; //not our job
            }
            var context = c as CodeElementsParser.DataConditionEntryContext;

            if (data.LevelNumber.Value != 66)
            {
                //(source page 379 of ISO Cobol 2014)
                DiagnosticUtils.AddError(data, "RENAMES must be level 66", context.levelNumber);
            }
            if (data.DataName == null)
            {
                //(source page 379 of ISO Cobol 2014)
                DiagnosticUtils.AddError(data, "Data name must be specified for level-66 items", context.levelNumber);
            }
            if (data.RenamesFromDataName.Equals(data.RenamesToDataName))
            {
                //(source page 379 of ISO Cobol 2014)
                DiagnosticUtils.AddError(data, "Renamed items can't be the same " + data.RenamesFromDataName + " and " + data.RenamesToDataName, context);
            }
        }
示例#6
0
        public void OnCodeElement(CodeElement e, ParserRuleContext c)
        {
            var statement = e as InspectConvertingStatement;

            if (statement == null)
            {
                return; //not our job
            }
            var context = c as CodeElementsParser.InspectStatementContext;
            var seen    = new Dictionary <InspectStatement.StartCharacterPosition, bool>();

            foreach (var value in Enum.GetValues(typeof(InspectTallyingStatement.StartCharacterPosition)))
            {
                seen[(InspectTallyingStatement.StartCharacterPosition)value] = false;
            }
            for (int i = 0; i < statement.ReplacingConditions.Length; i++)
            {
                var position = statement.ReplacingConditions[i].StartCharacterPosition;
                if (seen[position.Value])
                {
                    string error = "INSPECT: Maximum one " + position.Token.SourceText + " phrase for any one ALL, LEADING, CHARACTERS, FIRST or CONVERTING phrase";
                    DiagnosticUtils.AddError(statement, error, context.convertingPhrase().countingOrReplacingCondition()[i]);
                }
                seen[position.Value] = true;
            }
        }
示例#7
0
        public void OnNode([NotNull] Node node, ParserRuleContext context, CodeModel.Program program)
        {
            var header = node.CodeElement as FunctionDeclarationHeader;

            if (header == null)
            {
                return;                 //not my job
            }
            var filesection = node.Get <FileSection>("file");

            if (filesection != null)     // TCRFUN_DECLARATION_NO_FILE_SECTION
            {
                DiagnosticUtils.AddError(filesection.CodeElement, "Illegal FILE SECTION in function \"" + header.Name + "\" declaration", context);
            }

            CheckNoGlobalOrExternal(node.Get <DataDivision>("data-division"));

            CheckParameters(header.Profile, header, context, node);
            CheckNoLinkageItemIsAParameter(node.Get <LinkageSection>("linkage"), header.Profile);

            CheckNoPerform(node.SymbolTable.EnclosingScope, node);

            var headerNameURI = new URI(header.Name);
            var functions     = node.SymbolTable.GetFunction(headerNameURI, header.Profile);

            if (functions.Count > 1)
            {
                DiagnosticUtils.AddError(header, "A function \"" + headerNameURI.Head + "\" with the same profile already exists in namespace \"" + headerNameURI.Tail + "\".", context);
            }
//		foreach(var function in functions) {
//			if (!function.IsProcedure && !function.IsFunction)
//				DiagnosticUtils.AddError(header, "\""+header.Name.Head+"\" is neither procedure nor function.", context);
//		}
        }
示例#8
0
        public void OnCodeElement(CodeElement e, ParserRuleContext c)
        {
            var data = e as DataDescriptionEntry;

            if (data == null)
            {
                return;         //not our job
            }
            var context  = c as CodeElementsParser.DataDescriptionEntryContext;
            var external = GetContext(data, context.externalClause());
            var global   = GetContext(data, context.globalClause());

            if (data.DataName == null)
            {
                if (!data.IsFiller)
                {
                    DiagnosticUtils.AddError(data, "Data name or FILLER expected", context.dataNameDefinition());
                }
                if (data.IsExternal)
                {
                    DiagnosticUtils.AddError(data, "Data name must be specified for any entry containing the EXTERNAL clause", external);
                }
                if (data.IsGlobal)
                {
                    DiagnosticUtils.AddError(data, "Data name must be specified for any entry containing the GLOBAL clause", global);
                }
            }
            else
            {
                if (data.IsExternal && data.LevelNumber.Value != 01)
                {
                    DiagnosticUtils.AddError(data, "External is only allowed for level 01", external);
                }
            }
        }
示例#9
0
        public void OnCodeElement(CodeElement e, ParserRuleContext c)
        {
            var statement = e as MoveSimpleStatement;

            if (statement == null)
            {
                return; //not our job
            }
            var moveStatementContext = c as CodeElementsParser.MoveStatementContext;

            if (moveStatementContext != null)
            {
                var moveSimpleContext = moveStatementContext.moveSimple();
                if (moveSimpleContext != null)
                {
                    if (statement.StorageAreaWrites != null)
                    {
                        for (int i = 0; i < statement.StorageAreaWrites.Count; i++)
                        {
                            var receiver = statement.StorageAreaWrites[i].StorageArea;
                            if (receiver is FunctionCallResult)
                            {
                                DiagnosticUtils.AddError(statement, "MOVE: illegal <function call> after TO",
                                                         moveSimpleContext.storageArea1()[i]);
                            }
                        }
                    }
                }
            }
        }
示例#10
0
        private static void CheckParameter([NotNull] ParameterDescriptionEntry parameter, Node node)
        {
            // TCRFUN_LEVEL_88_PARAMETERS
            if (parameter.LevelNumber?.Value != 1)
            {
                DiagnosticUtils.AddError(node,
                                         "Condition parameter \"" + parameter.Name + "\" must be subordinate to another parameter.");
            }
            if (parameter.DataConditions != null)
            {
                foreach (var condition in parameter.DataConditions)
                {
                    if (condition.LevelNumber?.Value != 88)
                    {
                        DiagnosticUtils.AddError(node,
                                                 "Condition parameter \"" + condition.Name + "\" must be level 88.");
                    }
                    if (condition.LevelNumber?.Value == 88 && parameter.DataType == DataType.Boolean)
                    {
                        DiagnosticUtils.AddError(node,
                                                 "The Level 88 symbol '" + parameter.Name + "' cannot be declared under a BOOL typed symbol");
                    }
                }
            }

            if (parameter.Picture != null)
            {
                CrossCompleteChecker.CheckPicture(node, parameter);
            }

            var            type = parameter.DataType;
            TypeDefinition foundedType;

            TypeDefinitionHelper.Check(node, type, out foundedType); //Check if the type exists and is not ambiguous
        }
示例#11
0
        private void CheckVariable(Node node, StorageArea storageArea)
        {
            if (!storageArea.NeedDeclaration)
            {
                return;
            }
            var area = storageArea.GetStorageAreaThatNeedDeclaration;

            if (area.SymbolReference == null)
            {
                return;
            }
            //Do not handle TCFunctionName, it'll be done by TypeCobolChecker
            if (area.SymbolReference.IsOrCanBeOfType(SymbolType.TCFunctionName))
            {
                return;
            }

            var found = node.SymbolTable.GetVariable(area);

            if (found.Count < 1)
            {
                if (node.SymbolTable.GetFunction(area).Count < 1)
                {
                    DiagnosticUtils.AddError(node.CodeElement, "Symbol " + area + " is not referenced");
                }
            }
            if (found.Count > 1)
            {
                DiagnosticUtils.AddError(node.CodeElement, "Ambiguous reference to symbol " + area);
            }
        }
示例#12
0
        private void CheckParameter([NotNull] ParameterDescriptionEntry parameter, CodeElement ce, ParserRuleContext context, Node node)
        {
            // TCRFUN_LEVEL_88_PARAMETERS
            if (parameter.LevelNumber.Value != 1)
            {
                DiagnosticUtils.AddError(ce, "Condition parameter \"" + parameter.Name + "\" must be subordinate to another parameter.", context);
            }
            if (parameter.DataConditions != null)
            {
                foreach (var condition in parameter.DataConditions)
                {
                    if (condition.LevelNumber.Value != 88)
                    {
                        DiagnosticUtils.AddError(ce, "Condition parameter \"" + condition.Name + "\" must be level 88.");
                    }
                }
            }

            if (parameter.Picture != null)
            {
                Cobol85CompleteASTChecker.CheckPicture(parameter);
            }

            var type = parameter.DataType;

            TypeDefinitionHelper.Check(node, type); //Check if the type exists and is not ambiguous
        }
示例#13
0
        public static void OnNode(Node node)
        {
            var functionDeclaration = node as FunctionDeclaration;

            if (functionDeclaration == null)
            {
                return;                              //not my job
            }
            var header = node.CodeElement as FunctionDeclarationHeader;

            if (header == null)
            {
                return;                 //not my job
            }
            CheckParameters(header.Profile, node);
            CheckNoPerform(node.SymbolTable.EnclosingScope, node);

            var headerNameURI = new URI(header.Name);
            var functions     = node.SymbolTable.GetFunction(headerNameURI, functionDeclaration.Profile);

            if (functions.Count > 1)
            {
                DiagnosticUtils.AddError(node,
                                         "A function \"" + headerNameURI.Head + "\" with the same profile already exists in namespace \"" +
                                         headerNameURI.Tail + "\".");
            }
        }
示例#14
0
        private void CheckTypedef(DataTypeDescriptionEntry typedef,
                                  CodeElementsParser.DataDescriptionEntryContext context)
        {
            if (typedef == null)
            {
                return;
            }

            if (typedef.LevelNumber?.Value != 1)
            {
                string message = "TYPEDEF clause can only be specified for level 01 entries";
                DiagnosticUtils.AddError(typedef, message, context.cobol2002TypedefClause());
            }

            if (typedef.IsExternal)
            {
                string message = "EXTERNAL clause cannot be specified with TYPEDEF clause";
                foreach (var external in context.externalClause())
                {
                    DiagnosticUtils.AddError(typedef, message, external);
                }
            }

#if EUROINFO_LEGACY_TYPEDEF
            if (typedef.RestrictionLevel != RestrictionLevel.STRICT)
            {
                string message = "Custom EI rule : Only TYPEDEF STRICT is allowed.";
                DiagnosticUtils.AddError(typedef, message, context.cobol2002TypedefClause());
                return;
            }
#endif

            if (typedef.RestrictionLevel == RestrictionLevel.STRICT) //Manage as a STRICT TYPEDEF
            {
                if (typedef.IsSynchronized != null && typedef.IsSynchronized.Value == true)
                {
                    DiagnosticUtils.AddError(typedef, "SYNC clause cannot be used with a STRICT type definition", context.cobol2002TypedefClause());
                }
            }

            if (typedef.RestrictionLevel == RestrictionLevel.STRONG) //Manage as a STRONG TYPEDEF
            {
                if (typedef.InitialValue != null)
                {
                    string message = "STRONG TYPEDEF cannot contain VALUE clause:";
                    foreach (var valeuClause in context.valueClause())
                    {
                        DiagnosticUtils.AddError(typedef, message, valeuClause);
                    }
                }

                if (typedef.Picture != null)
                {
                    string message   = "Elementary TYPEDEF cannot be STRONG";
                    string rulestack = RuleStackBuilder.GetRuleStack(context.cobol2002TypedefClause());
                    DiagnosticUtils.AddError(typedef, message,
                                             ParseTreeUtils.GetFirstToken(context.cobol2002TypedefClause().STRONG()), rulestack);
                }
            }
        }
示例#15
0
        private static void Check(SymbolReference renames, Node node)
        {
            var founds = node.SymbolTable.GetVariables(renames);

            if (founds.Count() > 1)
            {
                string message = "Illegal RENAMES: Ambiguous reference to symbol \'" + renames + "\'";
                DiagnosticUtils.AddError(node, message, MessageCode.SemanticTCErrorInParser);
                return;
            }
            if (!founds.Any())
            {
                string message = "Illegal RENAMES: Symbol \'" + renames + "\' is not referenced";
                DiagnosticUtils.AddError(node, message, MessageCode.SemanticTCErrorInParser);
                return;
            }

            var found            = founds.First();
            var foundCodeElement = found.CodeElement as DataDefinitionEntry;

            if (found.IsStronglyTyped || found.IsStrictlyTyped)
            {
                string message = string.Format("Illegal RENAMES: '{0}' is {1}", renames,
                                               found.IsStronglyTyped ? "strongly-typed" : "strictly-typed");
                DiagnosticUtils.AddError(node, message, MessageCode.SemanticTCErrorInParser);
            }

            if (foundCodeElement?.LevelNumber != null && foundCodeElement.LevelNumber.Value == 01)
            {
                string message = string.Format("Illegal RENAMES: '{0}' is level 01", renames);
                DiagnosticUtils.AddError(node, message, MessageCode.SemanticTCErrorInParser);
            }
        }
示例#16
0
        public static void OnNode(Node node)
        {
            var redefinesNode = node as DataRedefines;

            if (redefinesNode == null)
            {
                return; //not my job
            }
            var redefinesSymbolReference = redefinesNode.CodeElement().RedefinesDataName;
            var redefinedVariable        = node.SymbolTable.GetRedefinedVariable(redefinesNode, redefinesSymbolReference);

            if (redefinedVariable == null)
            {
                string message = "Illegal REDEFINES: Symbol \'" + redefinesSymbolReference + "\' is not referenced";
                DiagnosticUtils.AddError(node, message, MessageCode.SemanticTCErrorInParser);
                return;
            }

            if (redefinedVariable.IsStronglyTyped || redefinedVariable.IsStrictlyTyped)
            {
                string message = string.Format("Illegal REDEFINES: '{0}' is {1}", redefinesSymbolReference,
                                               redefinedVariable.IsStronglyTyped ? "strongly-typed" : "strictly-typed");
                DiagnosticUtils.AddError(node, message, MessageCode.SemanticTCErrorInParser);
            }
        }
示例#17
0
        private static void CheckParameters([NotNull] ParametersProfile profile, Node node)
        {
            var parameters = profile.Parameters;

            foreach (var parameter in profile.InputParameters)
            {
                CheckParameter(parameter, node);
            }
            foreach (var parameter in profile.InoutParameters)
            {
                CheckParameter(parameter, node);
            }
            foreach (var parameter in profile.OutputParameters)
            {
                CheckParameter(parameter, node);
            }
            if (profile.ReturningParameter != null)
            {
                CheckParameter(profile.ReturningParameter, node);
                parameters.Add(profile.ReturningParameter);
            }

            foreach (
                var duplicatedParameter in
                parameters.GroupBy(p => p.Name).Where(g => g.Skip(1).Any()).SelectMany(g => g))
            //Group on parameter.Name //where group contains more than one item //reexpand to get all duplicated parameters
            {
                DiagnosticUtils.AddError(node,
                                         string.Format("Parameter with name '{0}' declared multiple times", duplicatedParameter.Name), duplicatedParameter);
            }
        }
示例#18
0
 protected static void Check <T>(T node, [NotNull] IList <T> found) where T : Node
 {
     if (found.Count > 1)
     {
         DiagnosticUtils.AddError(node.CodeElement, "Symbol \'" + node.Name + "\' already declared");
     }
 }
示例#19
0
        public override bool Visit(DataDefinition dataDefinition)
        {
            if (dataDefinition.CodeElement is CommonDataDescriptionAndDataRedefines)
            {
                CheckPicture(dataDefinition);
            }

            //Check if DataDefinition is level 88 and declared under BOOL variable
            if (!(dataDefinition.CodeElement is DataDefinitionEntry))
            {
                return(true);
            }

            var levelNumber          = ((DataDefinitionEntry)dataDefinition.CodeElement).LevelNumber;
            var dataDefinitionParent = (dataDefinition.Parent as DataDefinition);

            if (levelNumber != null && dataDefinitionParent != null &&
                dataDefinitionParent.DataType == DataType.Boolean && levelNumber.Value == 88)
            {
                DiagnosticUtils.AddError(dataDefinition.CodeElement,
                                         "The Level 88 symbol '" + dataDefinition.Name + "' cannot be declared under a BOOL typed symbol");
            }
            if (levelNumber != null && !(levelNumber.Value == 01 || levelNumber.Value == 77) &&
                dataDefinitionParent == null)
            {
                DiagnosticUtils.AddError(dataDefinition.CodeElement,
                                         "The variable '" + dataDefinition.Name + "' can only be of level 01 or 77");
            }

            return(true);
        }
示例#20
0
 public virtual void StartFunctionProcedureDivision(ProcedureDivisionHeader header)
 {
     if (header.UsingParameters != null && header.UsingParameters.Count > 0)
     {
         DiagnosticUtils.AddError(header, "TCRFUN_DECLARATION_NO_USING");//TODO#249
     }
     Enter(new ProcedureDivision(header), header);
 }
示例#21
0
 public static void CheckRedefines(DataRedefinesEntry redefines, CodeElementsParser.DataDescriptionEntryContext context)
 {
     if (context.cobol2002TypedefClause() != null)
     {
         string message = "REDEFINES clause cannot be specified with TYPEDEF clause";
         DiagnosticUtils.AddError(redefines, message, context.redefinesClause());
     }
 }
示例#22
0
 public static void OnCodeElement(SetStatementForIndexes set, CodeElementsParser.SetStatementForIndexesContext context)
 {
     if (set.SendingVariable == null)
     {
         DiagnosticUtils.AddError(set, "Set xxx up/down by xxx: Sending field missing or type unknown",
                                  context?.variableOrExpression2());
     }
 }
示例#23
0
        private static void Check(CodeElement e, SymbolTable table, [NotNull] FunctionCall call,
                                  [NotNull] FunctionDeclaration definition)
        {
            var parameters    = definition.Profile.Parameters;
            var callArgsCount = call.Arguments != null ? call.Arguments.Length : 0;

            if (callArgsCount > parameters.Count)
            {
                var m = string.Format("Function '{0}' only takes {1} parameter(s)", call.FunctionName, parameters.Count);
                DiagnosticUtils.AddError(e, m);
            }
            for (int c = 0; c < parameters.Count; c++)
            {
                var expected = parameters[c];
                if (c < callArgsCount)
                {
                    var actual = call.Arguments[c].StorageAreaOrValue;
                    if (actual.IsLiteral)
                    {
                        continue;
                    }
                    var callArgName = actual.MainSymbolReference != null ? actual.MainSymbolReference.Name : null;
                    var found       = table.GetVariable(actual);
                    if (found.Count < 1)
                    {
                        DiagnosticUtils.AddError(e, "Parameter " + callArgName + " is not referenced");
                    }
                    if (found.Count > 1)
                    {
                        DiagnosticUtils.AddError(e, "Ambiguous reference to parameter " + callArgName);
                    }
                    if (found.Count != 1)
                    {
                        continue;
                    }
                    var type = found[0];
                    // type check. please note:
                    // 1- if only one of [actual|expected] types is null, overriden DataType.!= operator will detect it
                    // 2- if both are null, we WANT it to break: in TypeCobol EVERYTHING should be typed,
                    // and things we cannot know their type as typed as DataType.Unknown (which is a non-null valid type).
                    if (type != null && (type.DataType != expected.DataType || type.Length > expected.Length))
                    {
                        var m =
                            string.Format(
                                "Function '{0}' expected parameter '{1}' of type {2} and length {3} and received '{4}' of type {5} and length {6}",
                                call.FunctionName, expected.Name, expected.DataType, expected.Length,
                                callArgName ?? string.Format("position {0}", c + 1), type.DataType, type.Length);
                        DiagnosticUtils.AddError(e, m);
                    }
                }
                else
                {
                    var m = string.Format("Function '{0}' is missing parameter '{1}' of type {2} and length {3}",
                                          call.FunctionName, expected.Name, expected.DataType, expected.Length);
                    DiagnosticUtils.AddError(e, m);
                }
            }
        }
示例#24
0
 public override bool Visit(If ifNode)
 {
     if (ifNode?.Children != null && !(ifNode.Children.Last() is End))
     {
         DiagnosticUtils.AddError(ifNode.CodeElement,
                                  "\"end-if\" is missing", MessageCode.Warning);
     }
     return(true);
 }
示例#25
0
 public override bool Visit(Evaluate evaluate)
 {
     if (evaluate.GetChildren <WhenOther>().Count == 0)
     {
         DiagnosticUtils.AddError(evaluate.CodeElement,
                                  "\"when other\" is missing", MessageCode.Warning);
     }
     return(true);
 }
示例#26
0
        public static void CheckLibrary([NotNull] ProcedureDivision procedureDivision)
        {
            //A procedure or a function cannot contains another procedure or function declaration
            //So we only need to check ProcedureDivision of Program
            if (!(procedureDivision.Parent is Program))
            {
                return;
            }


            //If the procedure division contains a PUBLIC procedure or function then it's considered as a "Library"
            bool isLibrary = procedureDivision.Children.Any(c =>
            {
                var f = c.CodeElement as FunctionDeclarationHeader;
                return(f != null && f.Visibility == AccessModifier.Public);
            });

            if (isLibrary)
            {
                bool firstParagraphChecked = false;
                foreach (var child in procedureDivision.Children)
                {
                    //TCRFUN_ONLY_PARAGRAPH_AND_PUBLIC_FUNC_IN_LIBRARY
                    if (child is Paragraph)
                    {
                        if (!firstParagraphChecked &&
                            !child.Name.Equals("INIT-LIBRARY", StringComparison.InvariantCultureIgnoreCase))
                        {
                            DiagnosticUtils.AddError(child.CodeElement == null ? procedureDivision : child,
                                                     "First paragraph of a program which contains public procedure must be INIT-LIBRARY. Move paragraph " + child.Name + " lower in the source.");
                        }
                        firstParagraphChecked = true;

                        continue; //A paragraph is always accepted as a child of ProcedureDivision
                    }
                    //TCRFUN_ONLY_PARAGRAPH_AND_PUBLIC_FUNC_IN_LIBRARY
                    if (!(child is FunctionDeclaration || child is Declaratives))
                    {
                        DiagnosticUtils.AddError(child.CodeElement == null ?
                                                 (child is Sentence
                            ? (child.Children.FirstOrDefault(c => c.CodeElement != null) ?? procedureDivision)
                            : procedureDivision) : child,
                                                 "Inside a library only function declaration or declaratives are allowed " + child.Name + " / " + child.ID);
                    }
                }

                var pdiv = procedureDivision.CodeElement as ProcedureDivisionHeader;

                //TCRFUN_LIBRARY_PROCEDURE_NO_USING
                if (pdiv?.UsingParameters != null && pdiv.UsingParameters.Count > 0)
                {
                    DiagnosticUtils.AddError(procedureDivision,
                                             "Illegal " + pdiv.UsingParameters.Count + " USING in library PROCEDURE DIVISION.");
                }
            }
        }
示例#27
0
        public static void CheckStatement(Node node)
        {
            var statement = node.CodeElement as SetStatementForIndexes;

            if (statement != null)
            {
                // Check receivers (incremented)
                var  receivers        = node.StorageAreaWritesDataDefinition.Values.Select(tuple => tuple.Item2);
                bool containsPointers = false;
                bool allArePointers   = true;
                foreach (var receiver in receivers)
                {
                    if (receiver.Usage == DataUsage.Pointer)
                    {
                        containsPointers = true;
                        var levelNumber = ((DataDefinitionEntry)receiver.CodeElement).LevelNumber;
                        if (levelNumber != null && levelNumber.Value > 49)
                        {
                            DiagnosticUtils.AddError(node, "Only pointer declared in level 01 to 49 can be use in instructions SET UP BY and SET DOWN BY.");
                            break;
                        }
                        receiver.SetFlag(Node.Flag.NodeisIncrementedPointer, true);
                    }
                    else
                    {
                        allArePointers = false;
                    }
                    // Do note break here because it can be all indexes wich is correct or a pointer as last receiver wich is not
                }

                if (allArePointers)
                {
                    node.SetFlag(Node.Flag.NodeContainsPointer, true);
                }
                // If the receivers contains at least one Pointer, they must all be pointer
                else if (containsPointers)
                {
                    DiagnosticUtils.AddError(node, "[Set [pointer1, pointer2 ...] UP|DOWN BY n] only support pointers.");
                }

                // Check sender (increment)
                int outputResult; // not used
                if (!int.TryParse(statement.SendingVariable.ToString(), out outputResult))
                {                 // Not an integer
                    var variable = node.GetDataDefinitionForQualifiedName(new URI(statement.SendingVariable.ToString()));
                    if (variable == null || variable.DataType.Name != "Numeric")
                    {// Not an Variable or a notNumeric variable
                        if (statement.SendingVariable.ArithmeticExpression == null)
                        {
                            // Not an arithmetic expressions
                            DiagnosticUtils.AddError(node, "Increment only support integer values, numeric variables and arithmetic expressions");
                        }
                    }
                }
            }
        }
示例#28
0
        private void TypeReferencer(DataDescription dataEntry, SymbolTable symbolTable)
        {
            if (symbolTable == null)
            {
                return;
            }
            var types = symbolTable.GetType(dataEntry.DataType);

            if (types.Count != 1)
            {
                return;
            }
            var type = types.First();


            var circularRefInsideChildren = type.Children.Any(c =>
            {
                var dataChild = c as DataDescription;
                if (dataChild == null)
                {
                    return(false);
                }
                var childrenType = symbolTable.GetType(dataChild.DataType).FirstOrDefault();
                if (childrenType == null)
                {
                    return(false);
                }
                return(dataEntry.GetParentTypeDefinition == childrenType); //Circular reference detected will return true
            });

            if (type == dataEntry.GetParentTypeDefinition || circularRefInsideChildren)
            {
                DiagnosticUtils.AddError(dataEntry, "Type circular reference detected", MessageCode.SemanticTCErrorInParser);
                return; //Do not continue to prevent further work/crash with circular references
            }

            if (symbolTable.TypesReferences.ContainsKey(type)) //If datatype already exists, add ref to the list
            {
                if (!symbolTable.TypesReferences[type].Contains(dataEntry))
                {
                    symbolTable.TypesReferences[type].Add(dataEntry);
                }
            }
            else
            {
                symbolTable.TypesReferences.Add(type, new List <DataDefinition> {
                    dataEntry
                });
            }

            //Also add all the typedChildren to reference list
            foreach (var dataDescTypeChild in type.Children.Where(c => c is DataDescription))
            {
                TypeReferencer(dataDescTypeChild as DataDescription, symbolTable);
            }
        }
示例#29
0
        public static void OnNode(Program node)
        {
            node.SetFlag(Node.Flag.MissingEndProgram, !(node.Children.LastOrDefault() is End));

            if (node.IsFlagSet(Node.Flag.MissingEndProgram))
            {
                DiagnosticUtils.AddError(node,
                                         "\"END PROGRAM\" is missing.", MessageCode.Warning);
            }
        }
示例#30
0
 public static void OnCodeElement(DataConditionEntry data, CodeElementsParser.DataConditionEntryContext context)
 {
     if (data.LevelNumber?.Value != 88)
     {
         DiagnosticUtils.AddError(data, "Data conditions must be level 88", context?.levelNumber);
     }
     if (data.DataName == null)
     {
         DiagnosticUtils.AddError(data, "Data name must be specified for level-88 items", context?.levelNumber);
     }
 }