Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
--- Diagnostics ---
Line 10[25,30] <27, Error, Syntax> - Syntax error : The max value ('0') is not valid in an OCCURS. RuleStack=codeElement>dataDescriptionEntry>occursClause, OffendingSymbol=[25,30:OCCURS]<OCCURS>
Line 11[25,30] <27, Error, Syntax> - Syntax error : The max value ('-2') is not valid in an OCCURS. RuleStack=codeElement>dataDescriptionEntry>occursClause, OffendingSymbol=[25,30:OCCURS]<OCCURS>
Line 15[22,27] <27, Error, Syntax> - Syntax error : The min value ('-2') is not valid in an OCCURS. RuleStack=codeElement>dataDescriptionEntry>occursClause, OffendingSymbol=[22,27:OCCURS]<OCCURS>
Line 17[29,34] <27, Error, Syntax> - Syntax error : The min value ('2') must not exceed the max value ('1') in an OCCURS. RuleStack=codeElement>dataDescriptionEntry>occursClause, OffendingSymbol=[29,34:OCCURS]<OCCURS>
--- Code Elements ---
[[ProgramIdentification]] [8,21:IDENTIFICATION]<IDENTIFICATION> --> [28,28+:.]<PeriodSeparator>
- ProgramName = TCOCCLVL
- IsInitial = False
- IsRecursive = False
- IsCommon = False

[[DataDivisionHeader]] [8,11:DATA]<DATA> --> [21,21+:.]<PeriodSeparator>

[[WorkingStorageSectionHeader]] [8,22:WORKING-STORAGE]<WORKING_STORAGE> --> [31,31+:.]<PeriodSeparator>

[[DataDescriptionEntry]] [8,9:01]<LevelNumber>{1} --> [19,19+:.]<PeriodSeparator>

[[DataDescriptionEntry]] [11,12:05]<LevelNumber>{5} --> [34,34+:.]<PeriodSeparator>

[[DataDescriptionEntry]] [8,9:05]<LevelNumber>{5} --> [32,33:. ]<PeriodSeparator>

[[DataDescriptionEntry]] [11,12:05]<LevelNumber>{5} --> [44,44+:.]<PeriodSeparator>

[[DataDescriptionEntry]] [11,12:05]<LevelNumber>{5} --> [44,44+:.]<PeriodSeparator>

[[DataDescriptionEntry]] [11,12:05]<LevelNumber>{5} --> [59,59+:.]<PeriodSeparator>

[[DataDescriptionEntry]] [11,12:05]<LevelNumber>{5} --> [59,59+:.]<PeriodSeparator>

[[DataDescriptionEntry]] [11,12:05]<LevelNumber>{5} --> [65,65+:.]<PeriodSeparator>

[[ProcedureDivisionHeader]] [8,16:PROCEDURE]<PROCEDURE> --> [26,26+:.]<PeriodSeparator>

[[GobackStatement]] [12,17:GOBACK]<GOBACK> --> [12,17:GOBACK]<GOBACK>

[[SentenceEnd]] [12,12+:.]<PeriodSeparator> --> [12,12+:.]<PeriodSeparator>

[[ProgramEnd]] [8,10:END]<END> --> [28,28+:.]<PeriodSeparator>
- ProgramName = TCOCCLVL

22 changes: 22 additions & 0 deletions TypeCobol.Test/Parser/Programs/Cobol85/OccursWrongValues.rdz.cbl
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
 IDENTIFICATION DIVISION.
PROGRAM-ID. TCOCCLVL.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 ROOT-GRP.
05 CNT PIC S9(2) BINARY.
* OK
05 MAX-OK OCCURS 5 PIC X.
* KO: Max value cannot be zero or negative
05 MAX-ZERO OCCURS 0 PIC X.
05 MAX-NEG OCCURS -2 PIC X.
* OK: Min value can be zero
05 MIN-ZERO OCCURS 0 TO 5 DEPENDING ON CNT PIC X.
* KO: Min value cannot be negative
05 MIN-NEG OCCURS -2 TO 1 DEPENDING ON CNT PIC X.
* KO: Min value cannot exceed Max value
05 MIN-EXCEED-MAX OCCURS 2 TO 1 DEPENDING ON CNT PIC X.

PROCEDURE DIVISION.
GOBACK
.
END PROGRAM TCOCCLVL.
18 changes: 18 additions & 0 deletions TypeCobol/Compiler/Diagnostics/CodeElementCheckers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,24 @@ public static void CheckOccurs([NotNull] CommonDataDescriptionAndDataRedefines c
DiagnosticUtils.AddError(codeElement, $"OCCURS cannot be specified on level {levelNumberValue}.", context);
}

// Check Max value cannot be zero or negative
var maxOcc = codeElement.MaxOccurencesCount?.Value;
if (maxOcc <= 0 ) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unwanted space between 0 and )

DiagnosticUtils.AddError(codeElement, $"The max value ('{maxOcc}') is not valid in an OCCURS.", context);
}
// Check Min value cannot be negative
var minOcc = codeElement.MinOccurencesCount?.Value;
if (minOcc < 0)
{
DiagnosticUtils.AddError(codeElement, $"The min value ('{minOcc}') is not valid in an OCCURS.", context);
}

// Check Min value cannot exceed Max value
if (minOcc > maxOcc)
{
DiagnosticUtils.AddError(codeElement, $"The min value ('{minOcc}') must not exceed the max value ('{maxOcc}') in an OCCURS.", context);
}

// Create diagnostic for duplicate keys found by builder
foreach (var duplicateSortingKeyReference in duplicateSortingKeysReferences)
{
Expand Down
17 changes: 15 additions & 2 deletions TypeCobol/Compiler/Nodes/Data.cs
Original file line number Diff line number Diff line change
Expand Up @@ -720,8 +720,21 @@ public DataUsage? GroupUsage
}
}

public long MinOccurencesCount { get { if (_CommonDataDesc != null && _CommonDataDesc.MinOccurencesCount != null) return _CommonDataDesc.MinOccurencesCount.Value; else return 1; } }
public long MaxOccurencesCount { get { return _CommonDataDesc != null && _CommonDataDesc.MaxOccurencesCount != null ? _CommonDataDesc.MaxOccurencesCount.Value : 1; } }
public long MinOccurencesCount {
get
{
long? minOccurences = _CommonDataDesc?.MinOccurencesCount?.Value;
return minOccurences >= 0 ? minOccurences.Value : 1;
}
}

public long MaxOccurencesCount {
get
{
long? maxOccurences = _CommonDataDesc?.MaxOccurencesCount?.Value;
return maxOccurences > 0 ? maxOccurences.Value : 1;
}
}


public NumericVariable OccursDependingOn { get { return _CommonDataDesc != null ? _CommonDataDesc.OccursDependingOn : null; } }
Expand Down
Loading