Расширение тетради COBOL на основе предложения OCCURS с использованием Java
Я пишу Java-программу, в которой мне нужно расширить тетрадь COBOL, если она содержит предложение OCCURS.
Число рядом с ключевым словом OCCURS определяет повторение дочерних строк в предложении OCCURS. Первый номер строки определяет уровень. Для одного OCCURS может быть более одного дочернего элемента. Предположим, входная тетрадь выглядит следующим образом:
01 TEST-REC.
05 VAR1 PIC X(02).
05 VAR2 OCCURS 2.
10 VAR3 PIC X(3).
05 VAR6 PIC X(02).
тогда вывод должен быть (игнорировать первую строку из ввода):
05 VAR1 PIC X(02).
10 VAR3 PIC X(3).
10 VAR3 PIC X(3).
05 VAR6 PIC X(02).
Я написал следующий код для обработки этого, и он отлично работает.
public class Test{
private static String copyBookExpansaion = "";
private static BufferedReader br1 = null;
public static void parseLine() throws IOException{
String line;
while((line = br1.readLine()) != null){
if(line.indexOf(" OCCURS ") == -1){
copyBookExpansaion = copyBookExpansaion + line.trim() + "\n";
}
else{
String s[] = line.trim().replaceAll(" +"," ").split(" ");
int size = Integer.parseInt(s[3].replaceAll("[^0-9]", ""));
line = br1.readLine();
for(int i = 0; i < size;i++){
copyBookExpansaion = copyBookExpansaion + line.trim() + "\n";
}
}
}
return;
}
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
FileInputStream copyBook= new FileInputStream("C:\\Users\\DadMadhR\\Desktop\\temp\\copybook\\test_Copybook.cpy");
br1 = new BufferedReader(new InputStreamReader(copyBook));
br1.readLine();
parseLine();
System.out.println(copyBookExpansaion);
}
}
Я не могу обработать вложенное предложение OCCURS. Предположим, мой вклад выглядит следующим образом:
01 TEST-REC.
05 VAR1 PIC X(02).
05 VAR2 OCCURS 2.
10 VAR3 PIC X(3).
10 VAR4 OCCURS 2.
15 VAR5 PIC X(2).
05 VAR6 PIC X(02).
тогда вывод должен выглядеть так:
05 VAR1 PIC X(02).
10 VAR3 PIC X(3).
15 VAR5 PIC X(2).
15 VAR5 PIC X(2).
10 VAR3 PIC X(3).
15 VAR5 PIC X(2).
15 VAR5 PIC X(2).
05 VAR6 PIC X(02).
Нет ограничений на количество вложенных OCCURS. Я не получаю подход для обработки вложенных OCCURS.
Кто-нибудь может предложить способ справиться с этим делом?
1 ответ
Попробуй это
Шаг 1. Создайте древовидную структуру. У каждой строки есть родитель. Уровень родителя (01, 05, ...) меньше уровня линии. Итак, структура
01 TEST-REC.
|
+--05 VAR1 PIC X(02).
|
+--05 VAR2 OCCURS 2.
| |
| +--10 VAR3 PIC X(3).
| |
| +--10 VAR4 OCCURS 2.
| |
| +--15 VAR5 PIC X(2).
|
+--05 VAR6 PIC X(02).
Шаг 2. Запишите структуру в поток. (а) Если строка содержит PIC
затем напишите собственную линию. (б) Пишите рекурсивно каждому ребенку. (Если строка содержит OCCURS N
затем повторите N раз.)
public class Test {
static class Node {
final int level;
final String line;
final List<Node> children = new ArrayList<>();
Node(int level, String line) {
this.level = level;
this.line = line;
}
void write(PrintStream out) {
int n = 1;
if (line.contains("OCCURS"))
n = Integer.parseInt(line.replaceAll("^.* |[^\\d]*$", ""));
if (line.contains("PIC"))
out.println(line);
for (int i = 0; i < n; ++i)
for (Node child : children)
child.write(out);
}
}
static Node parse(String inputFile) throws IOException {
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream(inputFile)))) {
List<Node> lines = new ArrayList<>();
String line;
int no = 0;
while ((line = reader.readLine()) != null) {
++no;
line = line.trim();
int level = Integer.parseInt(line.replaceFirst("\\s.*", ""));
Node child = new Node(level, line);
if (lines.size() > 0) {
boolean found = false;
for (int i = lines.size() - 1; i >= 0; --i) {
Node parent = lines.get(i);
if (parent.level < level) {
parent.children.add(child);
found = true;
break;
}
}
if (!found)
throw new RuntimeException(
"parent not found for line " + no + " : " + line);
}
lines.add(child);
}
return lines.get(0);
}
}
public static void main(String[] args) throws IOException {
// Step 1
Node top = parse("C:\\Users\\DadMadhR\\Desktop\\temp\\copybook\\test_Copybook.cpy");
// Step 2
top.write(System.out);
}
}