Created
December 27, 2013 03:40
-
-
Save LeslieZhu/8142288 to your computer and use it in GitHub Desktop.
将C语言源程序文件中的C89的32个关键字转换为大写,但不包括在注释里面的。 可以批处理文件,也可以通过管道输入,或者进入交互模式。 这是《编译原理及实践》的2.21习题的一个实践。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
#-*- coding:utf-8 -*- | |
""" | |
upper-keyword.py ------- Change C source keyword which not in comment to UPPER. | |
Author: Leslie Zhu | |
Email: [email protected] | |
Version: 1.0 | |
upper_keyword: read source and output with upper keyword(not in comment) | |
file_stream: check and read a file line by line | |
parse_line: parse each line based on status | |
status: a list with each flag | |
""" | |
Usage=""" | |
Usage: python upper_keyword.py infile.c | |
e.g: | |
$ python upper_keyword.py [?|-?|-h|--help] | |
$ python upper_keyword.py FILE1.c FILE2.c FILE3.c [..] | |
$ cat FILE1.c FILE2.c [..] | python upper_keyword.py | |
$ python upper_keyword.py | |
/* test: int a=3;*/ | |
// test: float b=3.0;*/ | |
int | |
main() | |
{ | |
int c=1; | |
return c; | |
} | |
^D | |
/* test: int a=3;*/ | |
// test: float b=3.0;*/ | |
INT | |
main() | |
{ | |
INT c=1; | |
RETURN c; | |
} | |
""" | |
import os,sys | |
# init status list | |
# '/' : status_0 = False | |
# '*' : status_1 = False | |
# '//': status_2 = False | |
# '/*': status_3 = False | |
# '*/': status_4 = False | |
# not in comment: status_5 = True | |
status=[False,False,False,False,False,True] | |
# C89 32 keywords | |
keywords=['auto','enum','unsigned','break','extern', | |
'return','void','case','float','short', | |
'volatile','char','for','signed','while', | |
'const','goto','sizeof','continue','if', | |
'static','default','struct','do','int', | |
'switch','double','long','typedef', | |
'else','register','union'] | |
# a keyword endswith token | |
tokens = [" ",";",",","(",")","{","}","\t",'\n'] | |
def parse_line(line=""): | |
"parse line and determine its status in C source comments,then upper the comments." | |
outline = "" | |
global status,keywords,tokens | |
if status[2]: status[5] = True | |
status[2] = False | |
word_flag = False # a flag for mark word in source file | |
prev_word = "" # init prev word split by blackspace | |
line = line | |
length = len(line) - 1 | |
for i,c in enumerate(line): | |
# update status | |
if status[5]: | |
if c == '/': | |
status=[True,False,False,False,False,False] | |
elif status[0]: | |
if c == '*' and not status[2]: status=[False,False,False,True,False,False] | |
if c == '/' and not status[3]: status=[False,False,True,False,False,False] | |
elif status[3]: | |
if status[1] and c != '/': status[2] = False | |
if c == '*': status=[False,True,False,True,False,False] | |
if c == '/' and status[1]: status=[False,False,False,False,False,True] | |
# depends on status | |
if status[2] or status[3]: | |
outline += str(c) | |
elif c in ['/','*']: | |
outline += str(c) | |
else: | |
if c != " " and not word_flag: | |
word_flag = True | |
if (c not in tokens and i != length) and word_flag: | |
prev_word += str(c) | |
if (c in tokens or i == length) and word_flag: | |
word_flag = False | |
if prev_word in keywords: | |
prev_word = prev_word.upper() | |
outline += prev_word | |
prev_word = "" | |
if (c in tokens or i == length) and not word_flag: | |
outline += str(c) | |
return outline | |
def file_stream(filename=None): | |
if not os.path.exists(filename): | |
print "File %s not exists!" % filename | |
sys.exit(1) | |
else: | |
return open(filename).readlines() | |
def upper_keyword(data=sys.stdin): | |
"read infile line by line and parse it." | |
for line in data: | |
print parse_line(line), | |
if __name__ == "__main__": | |
if len(sys.argv) == 2 and sys.argv[1] in ["?","-?","-h","--help"]: | |
print Usage | |
sys.exit(0) | |
if len(sys.argv) >= 2: | |
for i in range(1,len(sys.argv)): | |
upper_keyword(file_stream(sys.argv[i])) | |
else: | |
try: | |
upper_keyword(sys.stdin.readlines()) | |
except (KeyboardInterrupt,EOFError,IOError): | |
print Usage |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment