999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

COBOL到Java源代碼翻譯中的數據類型轉換

2008-01-01 00:00:00蘇靈燕武成崗唐生林
計算機應用研究 2008年3期

摘要:提出了一種功能等價的類型封裝和嵌套方法,可以有效地將COBOL數據描述映射到Java類型系統。該方法已在所開發的COBOL2Java翻譯系統中進行應用,通過了近400萬行的真實銀行商用系統的測試。實驗結果表明,此方法正確有效,并且提高了生成代碼的執行效率和可讀性。

關鍵詞:遺產代碼;COBOL;Java;翻譯;類型封裝和嵌套方式

中圖分類號:TP311文獻標志碼:A

文章編號:1001-3695(2008)03-0771-04

0引言

作為面向商業應用的程序設計語言COBOL[1]已經存在了五十多年,是一種典型的傳統語言。以這種語言編寫的軟件廣泛應用于銀行、證券和保險業。根據Arie van Deursen[2]在1999年的統計結果顯示,COBOL代碼量幾乎占到世界所有軟件代碼總量的30%。據不完全統計,大約1 000億行代碼是用COBOL語言編寫的[3]?,F代語言以其優越性替代了傳統語言,很少有軟件從業人員去學習和使用傳統語言,因此用這些語言編寫的程序就成為了遺產代碼。由此導致了一系列問題的出現:a)遺產代碼的維護[4]。目前僅有極少數了解傳統語言的程序員去維護大量的遺產代碼,傳統語言維護人員的短缺意味著維護費用的提高。文獻[5]提出維護遺產代碼的一個好方法是將遺產代碼翻譯成現代語言;b)遺產代碼的存在影響了新業務的開發。企業希望通過不斷地開發新業務,如電子商務、電子政務等,在保護原有投資的同時可以繼續擴展原來的服務。但是原有系統通常運行在基于大型機的專有系統上,很難滿足新業務所需要的分布式、平臺無關性和擴展性方面的要求;同時,這些系統也很難與支持新業務的平臺整合,重新開發新系統取而代之將是耗時和昂貴的;c)不利于代碼的跨平臺遷移。計算機網絡的出現使計算機不再是一臺獨立的機器,而是整個信息網絡的組成部分。一套軟件能否跨平臺工作決定了其是否具有更強的生命力。為了使代碼順利遷移,一種可能的辦法就是將這些用傳統語言編寫的軟件遷移到新的語言環境或平臺,如Java[6]。Java環境通過對Java語言與核心庫、字節碼以及Java虛擬機[7]三方面規范的制定,保證了Java代碼的網絡移動性,使得采用Java語言編碼的軟件可以獨立于特定的軟/硬件環境。因此,尋求一種將遺產代碼轉換成現代語言的技術是實現代碼遷移,使舊代碼煥發新活力,保護用戶投資的一項很有意義的工作。

由于COBOL語言誕生時代的局限性以及面向商業應用的特定性,它不支持如整型、浮點型等基本數據類型,而是詳細地描述每一個數據的取值范圍、用法以及內部表示,它幾乎完全不同于Java或C的數據類型語法和語義。如何將COBOL數據遷移到新平臺并且保持原COBOL代碼的功能等價,成為遺產代碼遷移必須解決的基本問題之一。本文利用類型封裝方法將COBOL基本數據映射到Java類型系統,利用類型封裝和嵌套方式將COBOL群組數據映射到Java嵌套類,從而實現了將COBOL數據功能等價地遷移到Java平臺,并且盡量保持了原COBOL代碼的風格,具有較好的可讀性。采用此方法通過了基于COBOL-85標準的測試集NIST [8],同時也成功地將數百萬行的真實銀行商用系統自動地、功能等價地遷移到Java平臺。

1相關工作

目前許多商業公司和研究機構都進行了這方面的研究,如LegacyJ Compiler公司的工具PerCOBOL[9]可以將COBOL源程序直接編譯成Java字節碼運行,較好地避開了數據類型遷移的問題。但是由于它不生成Java源代碼,不利于代碼維護,同時也不能滿足在原軟件基礎上的二次開發等進一步的軟件維護需求。

在源代碼轉換級別對數據類型進行遷移的方法主要可分為兩類:

a)簡單映射和類型嵌套[10]。根據數據的取值范圍和用法描述,將COBOL基本數據映射到Java基本數據類型,將COBOL群組數據映射到Java類。該方法實現簡單快捷,數據類型的對應關系一目了然。但是該方法不是一個功能等價的變換,需要用戶的人工干預,在確保沒有溢出發生的情況下才能保證系統的正確可靠。

b)類型封裝方法,如文獻[11,12]中提出的方法。當目標語言沒有精確等價于源語言的數據類型時,可以采用類型封裝方法仿真源語言的數據類型。文獻[11]對COBOL的所有數據對象進行了封裝。群組數據被封裝成對等的Java類,在該類中提供了一系列的set/get方法對群組項的子項進行存取,但是它僅提供了兩種基本類型數據接口,即int和string類型。一方面COBOL群組數據的子項即基本數據不能完全對應于int和string,需要額外的類型包裝才能保證數據映射的功能等價;另一方面數字數據可以當做其他類型使用,如字符串類型。為了保證功能等價,必須為每一個數據對象的每一種可能解釋提供相應的set/get方法。如果實際的應用程序并未用到所有這些方式,那么這種情況將造成不必要的代碼膨脹。文獻[12]同樣對COBOL的所有數據對象進行了封裝。群組數據被封裝成record類型,它包含兩部分信息:描述群組數據各個域之間的從屬關系(父子關系)的結構化信息;描述群組數據的物理內存的信息。群組數據的層次關系信息組成一個樹狀的數據結構,保存在record對象中。訪問群組數據子項時,首先根據要訪問的子項名在結構二叉樹中找到對應的節點,然后根據節點中存儲的類型信息返回對應數據類型對象。類型封裝是一個功能等價的變換,不足之處在于文獻[11,12]中實現的群組數據轉換可讀性不是很好,并且訪問效率還可以進一步提高。另外,在文獻[13,14]中提出了一種形式化的推導方法,根據COBOL數據的使用方法建立等價類,進一步推導數據類型及其子類之間的關系。

2COBOL數據分析和數據轉換

2.1COBOL數據對象分析

COBOL是一種商業數據處理語言,由于COBOL誕生時代的局限性和當時程序設計語言的發展水平及其設計目標,COBOL沒有數據類型的概念。它使用描述性語句來定義程序中使用的每一個數據對象,該描述決定了數據在內存中的編碼方式、定浮點特性、數據寬度、數據范圍和精度等。一個典型的COBOL數據對象定義如下所示:

01 R.

03 namePICX(10).

03 date PICX(6)value \"ABCDEF\".

03 AREDEFINESdate.

05 yearPIC99.

05 monthPIC99.

05 dayPIC99.

03 salaryPIC9(4)V99.

其中:PIC子句定義了數據的外在表現形式,同時也確定了數據對象的存儲空間大小及其支持的數據操作;這一點類似于Java中的基本數據類型,如string、char、int、double等;而VALUE子句則描述了COBOL數據對象的初始值。每一個帶有PIC子句描述的COBOL數據對象,在COBOL中都有對應的語句對其進行類型安全的訪問,如數據對象salary的PIC為9(4)V99,在COBOL中有add、subtract、multiply和divide等算術操作語句對其進行運算;但是對于PIC為X(10)這樣的字符串型數據不能實施算術操作。同時每一個數據對象可以是一個群組項(記錄)的一部分。組成一個記錄的所有子數據對象要求在存儲上是相鄰的,因為COBOL中的片斷操作可以跨越數據類型的限制直接訪問數據對象的存儲空間,并且由REDEFINES子句表示的兩個數據對象在存儲空間上是重疊的。以上定義可以看出,記錄R有四個直接子數據對象,即由層號03表示的四個數據對象。其中數據對象A是一個子記錄,它有自己的三個子對象,即year、month和day。由于數據對象A重新定義了數據對象date,也就是說A是date的別名,與date數據對象的存儲空間重疊,類似于C語言中的union結構。另外,在COBOL中可以實施片斷訪問,如R[10:2]表示對R的存儲空間從偏移量10開始的2個連續字節的訪問,同時也是對數據對象year的隱含操作。

2.2COBOL基本數據的轉換

現代程序語言的設計者大都提供基本數據類型,如int、float等用以映射現實世界中的簡單數據;同時也提供class允許用戶自定義所需的數據類型用以映射現實世界中較為復雜的數據。如文獻[10]中所描述的,將COBOL基本數據根據其表示的數據范圍對應到Java中的short、int等基本數據類型是粗糙的、非功能等價的,不能滿足COBOL數據運算的精度要求,反映到現實的COBOL程序應用環境中,很有可能造成經濟上的損失。因此,采用現代程序語言所提供的面向對象機制,將COBOL數據映射到用戶自定義類型,是惟一功能等價的數據遷移方法。

COBOL基本數據根據PIC子句中的格式字符串分為字母、字母數字、字母數字編輯、數字、數字編輯五種類別。所有數據類別缺省作為字符串存放在內存中,惟一可以用不同方式存儲的是數字類別。對于數字類別,可以指定其他屬性(如二進制)以不同方式存儲,提高計算效率。根據操作語句的不同,將COBOL基本數據分為字母數字數據和數字數據項兩類。字母數字數據通過數據語句進行操作,如initalize、inspect、string[1]等;數字數據項通過算術語句進行操作,如add、subtract、multiply[1]等。字母、字母數字、字母數字編輯、數字編輯是字母數字數據,數字類別是數字數據項。

在Java中用類BasicType作為一個基類,用于記錄各類數據的一些基本信息,具體結構如下所示:

public abstract class BasicType extends MemArea{

string picture;//如9(4)V99

int flags;//對應COBOL語法中各種子句

string initValue;//對應VALUE子句

Protected abstract void moveFrom(…); //對本數據對象賦值的方法

}

其中:picture和flags用于記錄COBOL中PIC子句的信息,initValue用于記錄VALUE的內容。

進一步,對于COBOL中的每種數據類別都定義一個Java類。字母數字數據用BasicString類表示,它繼承自BasicType, 封裝了字母數字數據可以支持的inspect、string[1]等操作。根據PIC描述的不同,字母數字數據可細分為字母數字型(Alpha)、字母數字編輯型(AlphaDigitEdited)、數字編輯型(NumericEdited)。對于數字數據項用Numeric類表示,它也繼承自BasicType,封裝了數字數據可以支持的加減乘除操作。根據其存儲格式的不同可細分為若干個子類,如NumericDisplay、NumericBCD等。數據層次如下所示:

MemArea:

BasicType:

BasicString:

Alpha

AlphaDigitEdited

NumericEdited

Numeric:

NumericDisplay

NumericBIN

其中:MemArea 類封裝了COBOL數據對象的存儲空間,它沒有任何類型信息,也不對存儲的內容作任何解釋,僅支持兩個基本的get/set接口對存儲內容進行讀操作/寫操作。該類用以支持COBOL中的數據片斷訪問方式。

2.3COBOL群組數據——記錄的轉換

可以將基本數據組成層次結構,稱為群組數據或組,組可以分成子組,最終分成基本數據不能再劃分。群組數據反映了COBOL對真實世界中結構化數據的抽象能力,它可以分為記錄和表格兩種類型,其中記錄類似于C語言中的嵌套struct定義。將前面定義的COBOL中的記錄通過類型封裝和嵌套方式映射成對等的Java類,用Java語言描述為

public static class R{

private static byte[] r=new byte[22];

public static Alpha R_slf=new Alpha(r, 0, 22, \"X(22)\");

public static Alpha name=new Alpha(r, 0, 10, \"X(10)\");

public static Alpha date=new Alpha(r, 10, 6, \"X(6)\", new Literal(\"ABCDEF\", Constant.STR_LIT));

public static class A {

public static Alpha A_slf=new Alpha(r, 10, 6, \"X(6)\");

public static NumericDisplay year=new NumericDisplay(r, 10, 2, \"99\");

public static NumericDisplay month=new NumericDisplay(r, 12, 2, \"99\");

public static NumericDisplay day=new NumericDisplay(r, 14, 2, \"99\");

}

public static NumericDisplay salary=new NumericDisplay(r, 16, 6, \"9(4)V99\");

}

Java虛擬機沒有對數據對象內存布局的嚴格規定,所以必須為整個記錄分配一個連續的空間,如上述代碼中的字節型數組r。只有這樣,才能保證數據對象name、date、子記錄A、salary占據連續的存儲空間,從而保持與COBOL一樣的語義,支持片斷操作。

從以上代碼片斷可以看出,構成記錄的子項對應于2.2節中的封裝類型。該類型的第一個參數是分配給整個記錄的存儲空間,緊接著的兩個參數是當前數據在這個記錄中的位置和長度,如數據對象name占據從0開始的10 Byte,date占據從10開始的6 Byte,同時A也占據從10開始的6 Byte,這表明date和A占據同一塊存儲空間,從而實現了REDEFINES的語義。后面的參數表示數據項的PIC字符串以及初始值。

對記錄域的訪問,通過類名限定方式進行,如對數據項day的訪問會被翻譯成R.A.day??梢源_定本次訪問的是一個PIC為“99”的數字數據,存儲空間為整個記錄從14開始的2 Byte。對數據項date的訪問會被翻譯成R.date,可以發現這次訪問的是一個PIC為“X(6)”的字母數字數據,存儲空間為整個記錄從10開始的6 Byte。這里兩次訪問對應的數據項由于有REDEFINES關系,其存儲空間有重疊關系,也就是說數字數據在字母數字數據的內部。因為這里的兩個數據對象共享存儲空間r,以任何一個數據對象訪問方式對存儲空間的修改都會自動反映到其他相關的數據對象中,不需要同步操作通知另一個數據對象。對于A[4:2]這樣的數據片斷訪問,則可以翻譯為R.A_slf..getMemArea(3,2)。這里的getMemArea方法返回的是A數據對象的最后兩個字節的存儲空間,也就是R.A.day所占據的存儲空間。其中COBOL偏移從1開始計數,Java從0開始。雖然在兩次訪問之間,數據對象對應的存儲內容可能發生了變化,但是數據對象均是以引用的方式指向對應存儲空間,數據對象訪問的內容總是最新的,因此并不需要同步操作。

2.4COBOL群組數據——表格的轉換

表格是一個由若干同類型元素組成的集合,類似于現代語言中的數組。組成表格的元素可以是COBOL中的基本數據,也可以是記錄。典型的表格例子如下所示:

01R.

03 SLIC OCCURS4 TIMES.

05 SLIFPIC XX VALUE \"aa\".

05 SLILPIC 99 VALUE 11.

以上定義了一個COBOL表格SLIC,組成表格的元素是記錄,長度為4個字符,每個記錄由兩個05層基本數據組成。引用表格中的元素時需要下標,如SLIF(3)表示對表格SLIC的第三個元素中的基本數據SLIF的訪問。

在類型封裝和嵌套方法中,利用Java中的array類提供的靜態方法set來創建Java數組。每一個表格包含兩部分信息:a)描述表格元素的信息,該信息映射成Java對應類,類的實例是組成Java數組的元素;b)描述表格所在的物理內存信息,映射成Java中的封裝類table,即Java數組。整個表格分配一段連續的空間,表格元素的成員封裝成COBOL中的基本數據,它記錄了表格元素成員在整個連續空間中占據的位置、長度以及相關的PIC字符串、初始值信息等。用Java語言描述為

public static class SLICELEMENT extends MemArea{

public Alpha SLIF;

public NumericDisplay SLIL;

public void setMem(byte[] value,int off, int len) {

super.setMem(value, off,len);

SLIF=new Alpha(value, off, 2, \"XX\", 0x13, new Literal(true,Constant.STR_LIT,\"a\"));

SLIL=new NumericDisplay(value, off+2, 2, \"99\", 0x12, new Literal(true,Constant.STR_LIT,\"1\"));

}

}

public table SLIC=new table(r, 0, 4*4, 1 ,4, SLICELEMENT.class)

創建Java數組時,通過setMem方法對表格元素的位置進行了調整,用來指向正確的存儲空間。訪問表格中的元素時,利用array類的靜態方法get即可,如SLIF(3),可以翻譯成array.get(R.SLIC.array,3).SLIF。

2.5轉換過程

對于基本數據和表格,轉換過程相對簡單,只要在前端分析語法樹上記錄相關信息,生成Java代碼時將相關信息以封裝類型輸出即可。記錄的處理有些復雜,在前端分析的語法樹上,對于每一個記錄的定義都形成一個語法節點。該節點本身已經形成了一個語法樹結構,從而反映記錄本身層次化的語法結構,這棵樹的每個子節點對應記錄定義中的某個子數據項,在其類型信息中,記錄了該數據項的PIC、flags等信息。生成Java代碼時,需要遍歷這個語法節點,將各子數據項的信息封裝成相應類型,以嵌套類的方式輸出。

3實驗驗證和結果

根據第2章所描述的COBOL數據對象的類型封裝和嵌套方法,實現了一個COBOL2Java翻譯系統,并將該翻譯系統應用于一個近400萬行COBOL源代碼的真實商用程序,成功地將其功能等價地翻譯到Java代碼,說明本文所述方法是正確有效的。同時,在生成代碼的適用性、執行效率和可讀性方面,對本文所述方法和文獻中的方法進行了對比試驗。

在適用性的對比實驗中,選取了真實商用程序的一個子模塊(該模塊由179個文件組成)進行了翻譯,實驗結果如表1所示。

因為NIST的例子很大,并且包含各種操作,如字符串的合并、拆分,文件的讀、寫等,所以在執行效率的對比實驗中,僅選取了對數據項和數組元素進行訪問操作的代碼片段,涵蓋了COBOL中對數據項的一般操作。因為只有文獻[12]中的方法完全支持REDEFINES和片斷訪問,并且能夠保證數據精度不丟失,所以在該實驗中僅對文獻[12]中的方法和本文方法進行了對比。文獻[12]中的方法記為M3,本文的方法記為M4,實驗結果如圖1所示。

圖1中橫坐標表示數據訪問的次數,縱坐標表示數據訪問需要的時間,單位為ms。從圖1中可以看出,方法M3所用的時間是方法M4的四倍以上,即方法M4比方法M3的執行效率要高很多,隨著數據訪問次數的變大該對比更加明顯。COBOL中有大量的數據訪問操作,因此本文的方法可以很大程度上提高生成代碼的執行效率。分析差異時發現,方法M3首先根據要訪問的子項名字在結構二叉樹中找到對應節點,然后根據節點中存儲的類型信息構造對應數據類型的對象并返回;方法M4按類名限定方式對數據項進行訪問,省去了每次訪問時的查找時間,主要時間花在了類的裝載上,并且訪問次數越多優勢越明顯。同時方法M3在構造對應數據類型的對象時需要額外分配空間,不可避免地會增加轉換后代碼的內存需求。

另外對數據項的訪問,方法M3采用對封裝類型record的查找方式,本文采用類名限定方式;在可讀性方面,本文方法更好,同時也可提高目標系統的可維護性。

4結束語

數據類型轉換是遺產代碼遷移必須要解決的基本問題之一,轉換過程中需要注意隱含在數據類型中的豐富語義,不能進行簡單內部數據類型的映射,需要進行數據仿真以保證轉換后程序的功能等價。本文提出類型封裝和嵌套方法,對COBOL數據對象進行仿真,實現了語義正確的數據類型轉換,成功地將一個近400萬行的真實商用程序功能等價地遷移到Java平臺。同時采用本文方法生成的Java代碼執行效率高、可讀性好,有利于代碼的維護。

參考文獻:

[1]BAROUDI C,et al.Programming language COBOL X3.23[S]. New York:ANSI, 1985.

[2]DEURSEN A van,KLINT P,VERHOEF C.Research issues in the renovation of legacy systems[C]//Proc of the 2nd International Conference on Fundamental Approaches to Software Engineering.London:SpringerVerlag,1999:1-21.

[3]FRANK P C.Legacy integration changing perspective[J].IEEE Software,2000,17(2):37-41.

[4]KONTOGIANNIS K, MARTIN J, WONG K,et al.Code migration through transformations:an experience report[C]//Proc of Conference of the Centre for Advanced Studies on Collaboractive Research CON’98.[S.l.]:IBM Press,1998:13.

[5]HARSU M.Reengineering legacy software through language conversion[R].Tampere University of Tampere,2000.

[6]Sun Microsystems Inc.The Java language environment[S].[S.l.]:Sun Microsystems Inc,1995.

[7]LINDHOLM T,YELLIN F.The JavaTM virtrual machine specification[S]. [S.l.]:Sun Microsystems Inc. [8]COBOL test suits[EB/OL].http://www.itl.nist.gov/div897/ctg/cobol_form.htm.

[9]LegacyJ’s PerCOBOLCOBOL to Java compiler[EB/OL].http://www.legacyj.com/lgcyj_percl.html.

[10]ANDREY A,TEREKHOV,CHRIS VERHOEF.The realities of language conversions[J].IEEE Software,2000,17(6):111124.

[11]MOSSIENKO M.Automated COBOL to Java recycling[C]//Proc of the 7th European Conference on Software Maintenance and Reengineering.Washington DC:IEEE Computer Society,2003.

[12]石學林,張兆慶,武成崗.COBOL到Java翻譯中的數據類型轉換方法[J].計算機研究與發展,2006,43(2):336-342.

[13]DEURSEN A van,MOONEN L.Type inference for COBOL systems[C]//Proc of the 5th Working Conference on Reverse Engingeering.Washington DC:IEEE Computer Society,1998:220-230.

[14]DEURSEN A Van,MOONEN L.Understanding COBOL systems using inferred types[C]//Proc of the 7th International Workshop on Program Comprehension.Washington DC:IEEE Computer Press,1999:74.

“本文中所涉及到的圖表、注解、公式等內容請以PDF格式閱讀原文”

主站蜘蛛池模板: 2020亚洲精品无码| 日韩 欧美 国产 精品 综合| 亚洲欧洲日产无码AV| 久久综合伊人77777| 国产真实自在自线免费精品| 午夜老司机永久免费看片| 免费在线色| 亚洲第一极品精品无码| 久久久波多野结衣av一区二区| 制服无码网站| 2024av在线无码中文最新| 国产欧美日韩精品综合在线| 97在线公开视频| 国产精品视频猛进猛出| 97在线公开视频| 日韩无码视频网站| 国产99视频精品免费观看9e| 国产伦精品一区二区三区视频优播 | 亚洲婷婷六月| 青青草a国产免费观看| 免费国产不卡午夜福在线观看| 亚洲日产2021三区在线| 国产精品午夜福利麻豆| 二级特黄绝大片免费视频大片| 婷婷午夜天| 人妻精品久久无码区| 国产精品视频a| 99精品影院| 欧美色伊人| 高清欧美性猛交XXXX黑人猛交| 日韩国产亚洲一区二区在线观看| 福利视频一区| 亚洲AV无码乱码在线观看裸奔| 国产精品yjizz视频网一二区| 综合人妻久久一区二区精品 | 国产精品青青| 伊人久久久久久久| 波多野结衣国产精品| 日本a级免费| 一级毛片免费播放视频| 亚洲欧美一区二区三区蜜芽| 亚洲天堂视频在线免费观看| 一区二区在线视频免费观看| 成人中文字幕在线| 素人激情视频福利| 国产99热| 亚洲欧美不卡视频| 在线看免费无码av天堂的| 国产欧美在线| 欧美日韩v| 专干老肥熟女视频网站| 亚洲欧洲日韩国产综合在线二区| 欧美中出一区二区| 国内毛片视频| 国产在线麻豆波多野结衣| 国产成人永久免费视频| 亚洲 欧美 偷自乱 图片| 97影院午夜在线观看视频| 一级片免费网站| 欧美在线网| 久久精品国产电影| 亚洲中文字幕97久久精品少妇| www.youjizz.com久久| 97在线碰| 99视频只有精品| 美女无遮挡被啪啪到高潮免费| 亚洲欧美国产视频| 91成人免费观看在线观看| 999精品视频在线| 高清视频一区| 欧美日韩国产综合视频在线观看 | 亚洲第一中文字幕| 在线看片中文字幕| 91精品伊人久久大香线蕉| 日本在线视频免费| 日韩毛片免费| 欧美综合区自拍亚洲综合天堂| 国产精品成人一区二区不卡| 孕妇高潮太爽了在线观看免费| 欧美一级高清免费a| 日本在线免费网站| 中文字幕在线一区二区在线|