2009年5月25日月曜日

Javaソースコードの特定位置がコードがコメントか文字列か判定する方法

まだ検証していないけどとりあえずできたので上げてみる。

まじめに構文解析しないで簡易に知る方法ないかなと思って実装してみた。言語は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: