まだ検証していないけどとりあえずできたので上げてみる。
まじめに構文解析しないで簡易に知る方法ないかなと思って実装してみた。言語はPython。文字列リテラルとコメント(と一応文字リテラル)の開始をサーチして、それに対応する終わりを探す。という処理を再帰で繰り返して、閉じてればNoneを、閉じてなければ対応する文字列を返却する。コメントは単純だけど文字列とかはエスケープもあるので、ちょっと不安。
import re
beginning_regex = re.compile(r'(\'|"|(?:/\*)|(?://))', re.MULTILINE)
doublequote_regex = re.compile(r'(?:[^\\]|\A)(?:\\\\)*"', re.MULTILINE)
singlequote_regex = re.compile(r"(?:[^\\])(?:\\\\)*'", re.MULTILINE)
cpp_comment_regex = re.compile(r'\n', re.MULTILINE)
c_comment_regex = re.compile(r'\*/', re.MULTILINE)
regex_map = {'"': doublequote_regex,
"'": singlequote_regex,
'//':cpp_comment_regex,
'/*': c_comment_regex}
return_map = {'"': 'string',
"'": 'char',
'//': 'cppcomment',
'/*': 'comment'}
def is_open(code_content,pos):
'''
code_content : string of whole source code
pos : position for checking
returns None when the string doesn't contain open comment/string literal
otherwise, returns a string "ccomment", "cppcomment", "string" or "char"
'''
idx = 0
cnt = 0
print pos
while True:
match = beginning_regex.search(code_content, idx)
if (match == None) or (pos < match.start()):
return None
match_head = match.group()
end_regex = regex_map[match_head]
idx = match.end()
if (match_head == '"') or (match_head == "'"):
idx = idx - 1
end_match = end_regex.search(code_content, idx)
if (end_match == None) or (pos < end_match.start()):
return return_map[match_head]
idx = end_match.end()
#main routine
f = open(filepath)
position = 100
result = is_open(f.read(), position)
if result:
print result + '内です'
else:
print 'コードです'
0 Comments:
Post a Comment