一些 Polyglot 招式
C/C++:
// comment
/* multi-line
comment */
#if 0
Same effect as comments
#endif
#ifndef __cplusplus
Ignored by C++
#endif
#ifdef __cplusplus
Ignored by C
#endif
Python:
# comment
'''
multi-line string
that sometimes could be used as comments
'''
"""
double quoted multi-line string
"""
'string'; "string"
Shell:
# comment
Vim:
" comment
Shell script 不只參數,指令也可以可以加引號。用這個特性可以排除 Python:
'echo' 'shell'
exit
在 Python 裡是 function,在 shell script 裡則是指令。這個差異可以用來排除 shell:
exit
print('python')
執行到 exit
以後,shell 的部份就會結束,後面的 code 就算有語法錯誤也不會有影響
這兩個技巧可能只適用在以 shell 開頭,而且行數不多的情況。在到達 exit
之前,所有的 shell 指令和參數都需要包成字串,以相容 Python
若 shell 的部份行數較多,或是有比較複雜的邏輯,可以用另一個方式處理:
- Python 和 shell 的字串都可以直接相鄰,例如
'a''b'
'''
對 Python 而言是多行字串的符號true
指令會忽略所有參數
利用這幾個特性,可以隔出一段 shell 專用的空間:
'true' ''' '
echo 'shell'
'true' ' '''
注意上面的範例開頭是 '''
在前,結尾則是 '''
在後。順序交換的話,再接回 Python 的區塊時容易出問題
若需要互相嵌入程式碼的話 (例如 shell → Python → shell) (為什麼會需要?), 接續前面的例子,利用 shell 字串本身就可以延續多行的特性,可以隔出 Python 專用的空間:
'true' '''shell start'
echo 'shell'
dummy="python start
'true' 'shell end'''
print('python')
'true' '''shell start'
python end"
echo 'shell'
'true' 'shell end'''
#if 0
/ #endif
包含的 code 可以排除 C++:
#if 0
print('python')
#endif
#if 0
/ #endif
裡面放入 Python 的多行字串 '''
,可以再用來排除 Python
#if 0
'''
#endif
std::cout << "C++" << std::endl;
#if 0
'''
#endif
利用 /*
/ */
搭配 #
,也可以分別隔出 C/C++ 和 Python 專用的空間:
#include <stdio.h> /*
print("Hello, Python!")
# */ int main() { puts("Hello, C!"); }
Macro 可以讓 C/C++ 稍微配合 Python 的語法,讓一些 code 同時相容 C/C++ 和 Python:
#if 0
LANG = 'Python'
#endif
#define LANG "C/C++"
#define print(str) printf(str "\n");
print(LANG)
另一個方式是利用行尾的反斜線 \\
:
#define NOTHING 0 // \
more code
在這個例子裡,C/C++ 會將 more code
視為前一行的延續,所以會被註解掉
Python 則是會將它當成獨立的一行,產生 IndentationError: unexpected indent
Vim 的雙引號 "
是註解,後面再接一個雙引號的話,在 Python 裡會形成字串
放一個分號 ;
做結束以後,後面可以開始接 Python code
""; print('python')
Python code 裡再放 '''
的話,可以再反過來排除 Python:
""; text = '''
echom 'vim'
""'''.rstrip('"').rstip('\n')
如上所示,進入到 Python 多行字串的區域以後,根據寫法,在離開前有機會不用再加分號
;
,並且可以把內容接到變數裡使用
和 shell 類似,Vim 的 exit
也是指令,可以用來排除 vim:
exit
print('python')
搭配前面的註解方式,Vim 的 function!
可以用來隔出一段 Python 專用的空間:
""; '''
function! __NOVIM__ ()
""'''
print('python')
""; '''
endfunction
""'''