PowerShell:从 Cobol Copybook 中提取数据长度和精度的代码

问题描述 投票:0回答:1

===问题陈述=== 考虑到 PIC 格式的所有不同数据类型,从 Cobol Copybook 中提取数据长度(而不是字节)和精度的代码

这段代码足以处理 PIC 数据的所有情况吗?请问还有其他格式吗?

===代码正在处理的情况列表===

PIC X(n):从格式“PIC X(n)”中提取长度,其中 n 是字符数。 PIC 9(n):从格式“PIC 9(n)”中提取长度和整数长度,其中 n 是位数。 PIC 9(n)V9(m):从格式“PIC 9(n)V9(m)”中提取长度、整数长度和精度,其中 n 是整数位数,m 是小数位数。 PIC -9(n).99:从格式“PIC -9(n).99”中提取长度、整数长度和精度,其中 n 是整数位数。 PIC 9(n).99:从格式“PIC 9(n).99”中提取长度、整数长度和精度,其中 n 是整数位数。 PIC -9(n).9(m):从格式“PIC -9(n).9(m)”中提取长度、整数长度和精度,其中 n 是整数位数,m 是整数位数小数位。 PIC 9(n).9(m):从格式“PIC 9(n).9(m)”中提取长度、整数长度和精度,其中 n 是整数位数,m 是小数位数。 PIC 9(n) OCCURS m TIMES:从格式“PIC 9(n) OCCURS m TIMES”中提取长度和整数长度,其中 n 是位数,m 是字段出现的次数。 简单数据类型:PIC A、PIC 9:将简单数据类型的长度设置为 1。

=== PowerShell 代码===

$copybookDataType = "PIC 9(09)V99."
$totalLength = ""
$integerLength = "N/A"
$precision = "N/A"

# 1. Handling format: PIC X(n).
if ($copybookDataType -match "^PIC\s+X\((\d+)\).$") {
    $totalLength = $Matches[1]
}
# 2. Handling format: PIC 9(n).
elseif ($copybookDataType -match "^PIC\s+(\d+)\((\d+)\).$") {
    $totalLength = $Matches[2]
    $integerLength = $Matches[1]
}
# 3. Handling format: PIC 9(09)V99.
elseif ($copybookDataType -match "^PIC\s+9\((\d+)\)V(\d+)\.$") {
    $integerLength = $Matches[1]
    $precision = ($Matches[2] -split "9").Count
    $totalLength = $integerLength + $precision + 1
}
# 4. Handling format: PIC -9(n).
elseif ($copybookDataType -match "^PIC\s+-9\((\d+)\).$") {
    $integerLength = $Matches[1]
    $totalLength = $integerLength + 1
}
# 5. Handling format: PIC 9(n)V9(m).
elseif ($copybookDataType -match "^PIC\s+(\d+)\(\d+V(\d+)\).$") {
    $integerLength = $Matches[1]
    $precision = $Matches[2]
    $totalLength = $integerLength + $precision + 1
}
# 6. Handling format: PIC -9(n).99.
elseif ($copybookDataType -match "^PIC\s+-9\((\d+)\)\.(\d+).$") {
    $integerLength = $Matches[1]
    $precision = ($Matches[2] -split "9").Count
    if ($copybookDataType -match "\.$") {
        $precision -= 1
    }
    $totalLength = $integerLength + $precision + 3
}
# 7. Handling format: PIC 9(n).99.
elseif ($copybookDataType -match "^PIC\s+9\((\d+)\)\.(\d+).$") {
    $integerLength = $Matches[1]
    $precision = ($Matches[2] -split "9").Count
    if ($copybookDataType -match "\.$") {
        $precision -= 1
    }
    $totalLength = $integerLength + $precision + 2
}
# 8. Handling format: PIC -9(n).9(m).
elseif ($copybookDataType -match "^PIC\s+-9\((\d+)\)\.9\((\d+)\).$") {
    $integerLength = $Matches[1]
    $precision = $Matches[2]
    if ($copybookDataType -match "\.$") {
        $precision -= 1
    }
    $totalLength = $integerLength + $precision + 4
}
# 9. Handling format: PIC 9(n).9(m).
elseif ($copybookDataType -match "^PIC\s+9\((\d+)\)\.9\((\d+)\).$") {
    $integerLength = $Matches[1]
    $precision = $Matches[2]
    if ($copybookDataType -match "\.$") {
        $precision -= 1
    }
    $totalLength = $integerLength + $precision + 3
}
# 10. Handling format: PIC 9(n) OCCURS m TIMES.
elseif ($copybookDataType -match "^PIC\s+(\d+)\(\d+\)\s+OCCURS\s+(\d+)\s+TIMES.$") {
    $dataTypeLength = $Matches[1]
    $occursTimes = $Matches[2]
    $totalLength = $dataTypeLength * $occursTimes
    $integerLength = $dataTypeLength
}
# 11. Handling simple data types: PIC A, PIC 9.
elseif ($copybookDataType -match "^PIC\s+(\w+).$") {
    $totalLength = 1
}
# 12. Handling format: PIC .9(n).
elseif ($copybookDataType -match "^PIC\s+\.9\((\d+)\).$") {
    $precision = $Matches[1]
    $totalLength = $precision + 1
}
# 13. Handling format: PIC -.9(n).
elseif ($copybookDataType -match "^PIC\s+-\.9\((\d+)\).$") {
    $precision = $Matches[1]
    $totalLength = $precision + 2
}

Write-Host "Total Length: $totalLength"
Write-Host "Integer Length: $integerLength"
Write-Host "Precision: $precision"
powershell cobol copybook
1个回答
1
投票

问题:这段代码足以处理 PIC 数据的所有情况吗? 答案:不,由于某些原因(主要是关于格式)请参阅评论。

主要问题是根据COBOL规则无法正确匹配,因为你至少需要添加记录并考虑任何地方的换行符和注释;理论上,还有单词延续(很少使用)、条件编译(更常用)、

COPY REPLACING
/
REPLACE
以及使用可能在抄本之外定义的常量,甚至使用指定的编译选项。 另外:对于某些
USAGE
,不同的编译器将使用不同的大小(并且
SYNCHRONIZED
也可能由于填充而改变记录的大小,每个编译器/环境/选项也不同)。

结论:虽然您可以在 powershell 中解析某些内容 - 但它很可能不应该是 COBOL 抄写本。 要么变得更加复杂,因为您需要“解析 COBOL”(整个编译单元,而不仅仅是单个副本)并且特定于编译器/环境,或者仅可用于“简单”输入。

最合理的做法是将编译单元放入生成符号列表的 COBOL 编译器中(大多数编译器都有一个选项,也只能进行语法检查),然后解析该符号列表(其中包括使用的实际长度) )使用 powershell(也可以使用管道完成,不需要临时文件)。

举个例子:对于 GnuCOBOL,它会类似于

cobc $yourflags_like_dialect_and_copybook_directories -fsyntax-only -frelax-syntax -w -t sym.lst --tlines=0 -fno-tsource -ftsymbols source.cob

(如果您希望结果出现在标准输出上,请使用 
-
 作为输出名称,而不是 
sym.lst
)。

© www.soinside.com 2019 - 2024. All rights reserved.