我正在設計一個轉換爲Java源代碼的DSL。它們是通常用於指定編譯器的語義/翻譯的符號嗎?通過編譯器進行代碼翻譯的正式表示法
實施例:
DSL:
a = b = c = 4
轉化爲:
Integer temp0 = 4;
Integer a = temp0;
Integer b = temp0;
Integer c = temp0;
由於提前,
的Jeroen
我正在設計一個轉換爲Java源代碼的DSL。它們是通常用於指定編譯器的語義/翻譯的符號嗎?通過編譯器進行代碼翻譯的正式表示法
實施例:
DSL:
a = b = c = 4
轉化爲:
Integer temp0 = 4;
Integer a = temp0;
Integer b = temp0;
Integer c = temp0;
由於提前,
的Jeroen
模式匹配LANGUAG es可以用來形式化小樹變換。有關這種DSL的示例,請參閱Nanopass framework。更通用的方法是將樹變換看作術語重寫的形式。
這樣的轉換足夠正式,例如它們可以被認證,如CompCert。
有一些正式的語言來定義語義;您幾乎可以在有關編程語言的會議記錄的任何技術文章中看到這些語言和定義。有關該主題的文本可用:https://mitpress.mit.edu/.../semantics-programming-languages您需要有一些願意閱讀簡潔的數學符號。
實際上,這些語義並不用於驅動翻譯/編譯器;這仍然是一個研究課題。請參閱http://Fwww.andrew.cmu.edu%2Fuser%2Fasubrama%2Fdissertation.pdf要閱讀這些內容,您通常需要花些時間閱讀上述介紹性文字。
在定義譯文;最實用的是program transformation systems。 利用這些工具,一個可以寫,使用的源語言符號(例如,你的DSL),和目標語言的符號(例如,Java或彙編語言或其他),轉換規則形式的 :
replace source_language_fragment by target_language_fragment if condition
這些工具由源語言和目標語言的語法驅動,並將轉換規則從其可讀格式解釋爲AST到AST重寫。要將複雜的DSL完全轉換爲另一種語言,通常需要數百條規則,但關鍵之處在於它們比手寫翻譯器的典型程序代碼更容易閱讀。
試圖按照OP的例子,假設一個人作的OP的「看MyDSL」和「Java」的語法爲目標,並使用變換規則我們的DMS軟件Reengineeering Toolkit的風格:
source domain dsl;
target domain Java;
rule translate_single_assignment(t: dsl_IDENTIFIER, e: dsl_expression):
" \t = \e " -- MyDSL syntax
-> -- read as "rewrites to"
" int \JavaIdentifier\(\t\)=\e;
".
rule translate_multi_assignment(t1: dsl_IDENTIFIER, t2: dsl_IDENTIFIER, e: dsl_expression):
" \t1 = \t2 = \e " -- MyDSL syntax
-> -- read as "rewrites to"
" \>\dsl \t2 = \e \statement
int \t1;
\t1=\t2;
".
您需要兩個規則:一個用於簡單賦值t = e的基本情況;和一個處理多重任務的情況。多重賦值的情況剝離了最外層的賦值, 併爲其生成代碼,並將多重賦值的其餘部分以原始DSL形式重新插入,以便通過兩條規則之一進行再處理。
用於重構的另一個例子(SOURCE_LANGUAGE == TARGET_LANGUAGE)我不知道是否有定義語義的形式語言,但如果你想的是如何,這是常見的例子完成後,看看例如[C標準](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf)或[Java JLS](http://docs.oracle.com)的第6章的.com/JavaSE的/功能/ JLS/SE7/HTML/index.html中)。 –