Skip to content

Commit

Permalink
WI #2584 Implement SORT table statement from Cobol v6.3 (#2586)
Browse files Browse the repository at this point in the history
  • Loading branch information
fm-117 committed Oct 30, 2023
1 parent 33b130f commit 0de79ed
Show file tree
Hide file tree
Showing 22 changed files with 415 additions and 157 deletions.
1 change: 1 addition & 0 deletions TypeCobol.Test/Misc/LanguageLevel/tcQualifiedNames.Mix.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Line 45[20,24] <27, Error, Syntax> - Syntax error : extraneous input 's1::b' exp
PERFORM s1::b
*KO qualifiedDataName1
Line 47[42,67] <27, Error, Syntax> - Syntax error : mismatched input 'WORK-STUDENT::STUDENT-ID-W' expecting user defined word
Line 47[12,15] <27, Error, Syntax> - Syntax error : SORT file statement requires at least one sorting KEY.
SORT FILE-03 ON ASCENDING KEY WORK-STUDENT::STUDENT-ID-W
USING FILE-01 GIVING FILE-02
*KO qualifiedConditionName
Expand Down
95 changes: 32 additions & 63 deletions TypeCobol.Test/Parser/CodeElements/SORT_ko.CodeElements.txt

Large diffs are not rendered by default.

10 changes: 2 additions & 8 deletions TypeCobol.Test/Parser/CodeElements/SORT_ko.cbl
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
* neither USING not GIVING
SORT x ASCENDING d.
SORT x ON DESCENDING KEY d.
SORT x ASCENDING d1 d2 d3.
SORT x DESCENDING d1 d2 d3.
SORT x ASCENDING d1 d2 ASCENDING d3 DESCENDING d4 ASCENDING d5 d6 DESCENDING d7 d8 d9.
* missing USING
* missing USING: invalid but not checked by ANTLR grammar
SORT x DESCENDING d GIVING filename1 filename2 filename3.
SORT x ASCENDING d1 d2 d3 GIVING filename.
* missing GIVING
* missing GIVING: invalid but not checked by ANTLR grammar
SORT x DESCENDING d USING filename1 filename2 filename3.
SORT x ASCENDING d1 d2 d3 USING filename.
* either USING or INPUT PROCEDURE
Expand Down
70 changes: 70 additions & 0 deletions TypeCobol.Test/Parser/CodeElements/SORT_ok.CodeElements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,73 @@

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

[[SortStatement]] [1,4:SORT]<SORT> --> [6,6:x]<UserDefinedWord>

[[SortStatement]] [1,4:SORT]<SORT> --> [26,26:d]<UserDefinedWord>

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

[[SortStatement]] [1,4:SORT]<SORT> --> [26,26:d]<UserDefinedWord>

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

[[SortStatement]] [1,4:SORT]<SORT> --> [32,33:d3]<UserDefinedWord>

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

[[SortStatement]] [1,4:SORT]<SORT> --> [32,33:d3]<UserDefinedWord>

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

[[SortStatement]] [1,4:SORT]<SORT> --> [84,85:d9]<UserDefinedWord>

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

[[SortStatement]] [1,4:SORT]<SORT> --> [27,31:ORDER]<ORDER>

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

[[SortStatement]] [1,4:SORT]<SORT> --> [27,31:ORDER]<ORDER>

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

[[SortStatement]] [1,4:SORT]<SORT> --> [27,31:ORDER]<ORDER>

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

[[SortStatement]] [1,4:SORT]<SORT> --> [24,25:IN]<IN>

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

[[SortStatement]] [1,4:SORT]<SORT> --> [27,31:ORDER]<ORDER>

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

[[SortStatement]] [1,4:SORT]<SORT> --> [13,22:DUPLICATES]<DUPLICATES>

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

[[SortStatement]] [1,4:SORT]<SORT> --> [24,25:IN]<IN>

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

[[SortStatement]] [1,4:SORT]<SORT> --> [13,22:DUPLICATES]<DUPLICATES>

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

[[SortStatement]] [1,4:SORT]<SORT> --> [30,41:alphabetname]<UserDefinedWord>

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

[[SortStatement]] [1,4:SORT]<SORT> --> [30,41:alphabetname]<UserDefinedWord>

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

[[SortStatement]] [1,4:SORT]<SORT> --> [30,41:alphabetname]<UserDefinedWord>

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

[[SortStatement]] [1,4:SORT]<SORT> --> [30,41:alphabetname]<UserDefinedWord>

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

23 changes: 22 additions & 1 deletion TypeCobol.Test/Parser/CodeElements/SORT_ok.cbl
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,25 @@ SORT x ASCENDING d1 d2 d3 INPUT PROCEDURE IS procedurename1 THRU procedurename2
SORT x ASCENDING d1 d2 d3 INPUT PROCEDURE procedurename1 THRU procedurename2 OUTPUT PROCEDURE IS procedurename3 THRU procedurename4.
* everything
SORT x DESCENDING d DUPLICATES SEQUENCE alphabetname INPUT PROCEDURE procedurename1 OUTPUT PROCEDURE procedurename2 THRU procedurename3.
SORT x ASCENDING d1 d2 d3 WITH DUPLICATES IN ORDER COLLATING SEQUENCE IS alphabetname INPUT PROCEDURE IS procedurename1 THRU procedurename2 OUTPUT PROCEDURE IS procedurename3 THRU procedurename4.
SORT x ASCENDING d1 d2 d3 WITH DUPLICATES IN ORDER COLLATING SEQUENCE IS alphabetname INPUT PROCEDURE IS procedurename1 THRU procedurename2 OUTPUT PROCEDURE IS procedurename3 THRU procedurename4.
* Table SORT format
SORT x
SORT x ASCENDING d.
SORT x ON DESCENDING KEY d.
SORT x ASCENDING d1 d2 d3.
SORT x DESCENDING d1 d2 d3.
SORT x ASCENDING d1 d2 ASCENDING d3 DESCENDING d4 ASCENDING d5 d6 DESCENDING d7 d8 d9.
* WITH DUPLICATES clause
SORT x WITH DUPLICATES IN ORDER.
SORT x DUPLICATES IN ORDER.
SORT x WITH DUPLICATES ORDER.
SORT x WITH DUPLICATES IN .
SORT x DUPLICATES ORDER.
SORT x WITH DUPLICATES .
SORT x DUPLICATES IN .
SORT x DUPLICATES .
* COLLATING SEQUENCE clause
SORT x COLLATING SEQUENCE IS alphabetname.
SORT x SEQUENCE IS alphabetname.
SORT x COLLATING SEQUENCE alphabetname.
SORT x SEQUENCE alphabetname.
63 changes: 63 additions & 0 deletions TypeCobol.Test/Parser/Programs/Cobol85/SortStatement.Mix.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
 IDENTIFICATION DIVISION.
PROGRAM-ID. TCOMFL06.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
Select Out001 Assign To SOR001.
Select AmbiguousName Assign To SOR001.
DATA DIVISION.
FILE SECTION.
SD Out001.
01 Out001Data PIC X(200).
SD AmbiguousName.
01 AmbiguousNameData PIC X(200).
WORKING-STORAGE SECTION.
01 tab1.
05 a OCCURS 20.
10 item-a PIC X.
01 AmbiguousName PIC X.
PROCEDURE DIVISION.
*KO unable to resolve SORT target
Line 21[17,37] <27, Error, Syntax> - Syntax error : Unable to resolve reference to SORT target 'something-not-defined'.
SORT something-not-defined
*KO ambiguous reference
Line 23[17,29] <27, Error, Syntax> - Syntax error : Ambiguous reference to SORT target 'AmbiguousName'.
SORT AmbiguousName
*KO SORT file without KEY
Line 25[12,15] <27, Error, Syntax> - Syntax error : SORT file statement requires at least one sorting KEY.
SORT Out001 INPUT PROCEDURE inputProc
OUTPUT PROCEDURE outputProc
*KO SORT file without input
Line 28[12,15] <27, Error, Syntax> - Syntax error : Missing input definition in SORT file statement: either add INPUT PROCEDURE phrase or USING file phrase to define required input.
SORT Out001 ASCENDING Out001Data
OUTPUT PROCEDURE outputProc
*KO SORT file without output
Line 31[12,15] <27, Error, Syntax> - Syntax error : Missing output definition in SORT file statement: either add OUTPUT PROCEDURE phrase or GIVING file phrase to define required output.
SORT Out001 ASCENDING Out001Data
INPUT PROCEDURE inputProc
*KO SORT table with input
Line 34[12,15] <27, Error, Syntax> - Syntax error : SORT table statement does not allow input definition.
SORT a ASCENDING item-a
INPUT PROCEDURE inputProc
*KO SORT table with output
Line 37[12,15] <27, Error, Syntax> - Syntax error : SORT table statement does not allow output definition.
SORT a ASCENDING item-a
OUTPUT PROCEDURE outputProc
*KO SORT table without KEY
Line 40[12,15] <27, Error, Syntax> - Syntax error : SORT table statement has no sorting KEY and the sorted table 'a' does not define any KEY clause.
SORT a
*Ok, this is a valid SORT file
SORT Out001 ASCENDING Out001Data
INPUT PROCEDURE inputProc
OUTPUT PROCEDURE outputProc
*Ok, this is a valid SORT table
SORT a ASCENDING item-a
GOBACK
.
inputProc.
DISPLAY "input proc"
.
outputProc.
DISPLAY "output proc"
.
END PROGRAM TCOMFL06.
55 changes: 55 additions & 0 deletions TypeCobol.Test/Parser/Programs/Cobol85/SortStatement.rdz.cbl
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
IDENTIFICATION DIVISION.
PROGRAM-ID. TCOMFL06.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
Select Out001 Assign To SOR001.
Select AmbiguousName Assign To SOR001.
DATA DIVISION.
FILE SECTION.
SD Out001.
01 Out001Data PIC X(200).
SD AmbiguousName.
01 AmbiguousNameData PIC X(200).
WORKING-STORAGE SECTION.
01 tab1.
05 a OCCURS 20.
10 item-a PIC X.
01 AmbiguousName PIC X.
PROCEDURE DIVISION.
*KO unable to resolve SORT target
SORT something-not-defined
*KO ambiguous reference
SORT AmbiguousName
*KO SORT file without KEY
SORT Out001 INPUT PROCEDURE inputProc
OUTPUT PROCEDURE outputProc
*KO SORT file without input
SORT Out001 ASCENDING Out001Data
OUTPUT PROCEDURE outputProc
*KO SORT file without output
SORT Out001 ASCENDING Out001Data
INPUT PROCEDURE inputProc
*KO SORT table with input
SORT a ASCENDING item-a
INPUT PROCEDURE inputProc
*KO SORT table with output
SORT a ASCENDING item-a
OUTPUT PROCEDURE outputProc
*KO SORT table without KEY
SORT a
*Ok, this is a valid SORT file
SORT Out001 ASCENDING Out001Data
INPUT PROCEDURE inputProc
OUTPUT PROCEDURE outputProc
*Ok, this is a valid SORT table
SORT a ASCENDING item-a
GOBACK
.
inputProc.
DISPLAY "input proc"
.
outputProc.
DISPLAY "output proc"
.
END PROGRAM TCOMFL06.
18 changes: 15 additions & 3 deletions TypeCobol/AntlrGrammar/CobolCodeElements.g4
Original file line number Diff line number Diff line change
Expand Up @@ -6684,12 +6684,24 @@ setStatementForConditions:
// segment or wholly contained within the same independent segment as that SORT
// statement.

// Table SORT statements can appear anywhere in the PROCEDURE DIVISION. This format of the SORT
// statement can be used with programs that are compiled with the THREAD option.
// data-name-2
// Specifies a table data-name that is subject to the following rules:
// - data-name-2 must have an OCCURS clause in the data description entry.
// - data-name-2 can be qualified.
// - data-name-2 can be subscripted. The rightmost or only subscript of the table must be omitted or
// replaced with the word ALL.
// The number of occurrences of table elements that are referenced by data-name-2 is determined
// by the rules in the OCCURS clause. The sorted table elements are placed in the same table that is
// referenced by data-name-2.

sortStatement:
SORT fileNameReference onAscendingDescendingKey+
SORT dataItemReferenceOrFileName onAscendingDescendingKey*
(WITH? DUPLICATES IN? ORDER?)?
collatingSequence?
(usingFilenames | inputProcedure)
(givingFilenames | outputProcedure);
(usingFilenames | inputProcedure)?
(givingFilenames | outputProcedure)?;

// Rules shared with mergeStatement

Expand Down
4 changes: 4 additions & 0 deletions TypeCobol/AntlrGrammar/CobolExpressions.g4
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ dataItemReferenceOrConditionReferenceOrIndexName:
// [Type ambiguity] : fileName cannot be distinguished from identifier at this parsing stage
dataItemReferenceOrConditionReferenceOrFileName:
qualifiedDataNameOrQualifiedConditionNameOrFileName (LeftParenthesisSeparator subscript+ RightParenthesisSeparator)?;

// [Type ambiguity] : fileName cannot be distinguished from identifier at this parsing stage
dataItemReferenceOrFileName:
qualifiedDataNameOrFileName (LeftParenthesisSeparator subscript+ RightParenthesisSeparator)?;

// [Type ambiguity] : className cannot be distinguished from identifier at this parsing stage
dataItemReferenceOrConditionReferenceOrClassName:
Expand Down
4 changes: 4 additions & 0 deletions TypeCobol/AntlrGrammar/CobolWords.g4
Original file line number Diff line number Diff line change
Expand Up @@ -1715,6 +1715,10 @@ qualifiedDataNameOrQualifiedConditionNameOrIndexName:
qualifiedDataNameOrQualifiedConditionNameOrFileName:
dataNameReferenceOrConditionNameReferenceOrConditionForUPSISwitchNameReferenceOrFileNameReference | qualifiedDataNameOrQualifiedConditionName1;

// [Type ambiguity] at this parsing stage
qualifiedDataNameOrFileName:
dataNameReferenceOrFileNameReference | qualifiedDataName1;

// [Type ambiguity] at this parsing stage
qualifiedDataNameOrQualifiedConditionNameOrClassName:
dataNameReferenceOrConditionNameReferenceOrConditionForUPSISwitchNameReferenceOrClassNameReference | qualifiedDataNameOrQualifiedConditionName1;
Expand Down
4 changes: 2 additions & 2 deletions TypeCobol/Compiler/CodeElements/CobolLanguageLevelVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ bool IsStopVisitingChildren
bool Visit([NotNull] DataSection dataSection);
bool Visit([NotNull] DataDivision dataDivision);
bool Visit([NotNull] FileSection fileSection);
bool Visit([NotNull] FileDescriptionEntryNode fileDescriptionEntryNode);
bool Visit([NotNull] FileDescription fileDescription);
bool Visit([NotNull] GlobalStorageSection globalStorageSection);
bool Visit([NotNull] WorkingStorageSection workingStorageSection);
bool Visit([NotNull] LocalStorageSection localStorageSection);
Expand Down Expand Up @@ -1355,7 +1355,7 @@ public virtual bool Visit(JsonParse jsonParse)
return true;
}

public virtual bool Visit(FileDescriptionEntryNode fileDescriptionEntryNode) {
public virtual bool Visit(FileDescription fileDescription) {
return true;
}

Expand Down
29 changes: 17 additions & 12 deletions TypeCobol/Compiler/CodeElements/Statement/SortStatement.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System.Collections.Generic;

namespace TypeCobol.Compiler.CodeElements
namespace TypeCobol.Compiler.CodeElements
{
/// <summary>
/// p422:
Expand All @@ -21,17 +19,24 @@ public SortStatement() : base(CodeElementType.SortStatement, StatementType.SortS
{ }

/// <summary>
/// p422:
/// file-name-1
/// The name given in the SD entry that describes the records to be sorted.
///
/// p423:
/// No pair of file-names in a SORT statement can be specified in the same SAME
/// SORT AREA clause or the SAME SORT-MERGE AREA clause. File-names
/// associated with the GIVING clause (file-name-3, ...) cannot be specified in the SAME
/// AREA clause; however, they can be associated with the SAME RECORD AREA clause.
/// No pair of file-names in a SORT statement can be specified in the same SAME SORT AREA clause or the
/// SAME SORT-MERGE AREA clause. File-names associated with the GIVING clause (file-name-3, ...) cannot
/// be specified in the SAME AREA clause; however, they can be associated with the SAME RECORD AREA
/// clause.
///
/// data-name-2
/// Specifies a table data-name that is subject to the following rules:
/// - data-name-2 must have an OCCURS clause in the data description entry.
/// - data-name-2 can be qualified.
/// - data-name-2 can be subscripted. The rightmost or only subscript of the table must be omitted or
/// replaced with the word ALL.
/// The number of occurrences of table elements that are referenced by data-name-2 is determined
/// by the rules in the OCCURS clause. The sorted table elements are placed in the same table that is
/// referenced by data-name-2.
/// </summary>
public SymbolReference FileName { get; set; }
public DataOrConditionStorageArea FileNameOrTableName { get; set; }

/// <summary>
/// p423:
Expand Down Expand Up @@ -255,7 +260,7 @@ public SortStatement() : base(CodeElementType.SortStatement, StatementType.SortS
public override bool VisitCodeElement(IASTVisitor astVisitor)
{
return base.VisitCodeElement(astVisitor) && astVisitor.Visit(this)
&& this.ContinueVisitToChildren(astVisitor, FileName, WithDuplicates, CollatingSequence,
&& this.ContinueVisitToChildren(astVisitor, FileNameOrTableName, WithDuplicates, CollatingSequence,
InputProcedure, ThroughInputProcedure, OutputProcedure, ThroughOutputProcedure)
&& this.ContinueVisitToChildren(astVisitor, SortingKeys, InputFiles, OutputFiles);
}
Expand Down
24 changes: 0 additions & 24 deletions TypeCobol/Compiler/CodeModel/FileDescription.cs

This file was deleted.

2 changes: 1 addition & 1 deletion TypeCobol/Compiler/CodeModel/Method.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public class Method
/// More than one record description entry can be specified; each is an alternative description of the same record storage area.
/// Data areas described in the FILE SECTION are not available for processing unless the file that contains the data area is open.
/// </summary>
public IDictionary<SymbolDefinition, FileDescription> FileDescriptions { get; set; }
public IDictionary<SymbolDefinition, FileDescriptionEntry> FileDescriptions { get; set; }

/// <summary>
/// A single copy of the WORKING-STORAGE for a method is statically allocated on the first invocation of the method and persists in a last-used state for the duration of the run unit.
Expand Down

0 comments on commit 0de79ed

Please sign in to comment.