Форум сайта python.su
0
Пишу парсер Ruby, который будет считать сколько строк закомментировано. Есть следующий класс:
#!/usr/bin/env python # -*- coding: utf-8 -*- """ Класс: Поиск в коде однострочных комментариев вида '#' и многострочных вида '=begin ... =end' """ import re class RubyComments: def __init__(self,code): self._code = code + '\n' self._lines = set() @property def comment_lines_count(self): """ Возвращает количество строк с '#' в self._code """ match_to_set = lambda m: set(range(*m.span())) re_iter = lambda expr: re.finditer(expr, self._code) code = list(enumerate(match_to_set(m) for m in re_iter('.*\n'))) for m in re_iter('#(.*\\\s*\n)+.*\n|#.*\n|/\*(\n|.)*?\*/'): self._lines |= set(s[0] for s in code if match_to_set(m) & s[1]) return len(self._lines)
Офлайн
14
RelrinGood luck
Пишу парсер Ruby
Офлайн
857
Relrinнайди в интернете классическую задачу про удаление комментариев C из исходного файла
Класс: Поиск в коде однострочных комментариев вида ‘#’ и многострочных вида ‘=begin … =end’
Офлайн
20
odnochlenНастоящие программисты записывают байты на хард намагниченной иголкой
Традиционно парсеры пишутся с использованием конечных автоматов.


import pygments from pygments.token import Comment ruby_lex = pygments.lexers.get_lexer_by_name('ruby') code=""" #!/usr/bin/env ruby puts "hello" =begin some ruby =begin nested =end comment =end puts "world" """ comments = [(tok,line) for tok,line in ruby_lex.get_tokens(code) if tok in Comment] >>> comments [(Token.Comment.Single, u'#!/usr/bin/env ruby'), (Token.Comment.Multiline, u'=be gin \nsome ruby =begin nested =end \ncomment\n=end')] >>> [t for t in ruby_lex.get_tokens(code)] >>> [(Token.Comment.Single, u'#!/usr/bin/env ruby'), (Token.Text, u'\n\n'), (Token.N ame.Builtin, u'puts'), (Token.Text, u' '), (Token.Literal.String.Double, u'"'), (Token.Literal.String.Double, u'hello'), (Token.Literal.String.Double, u'"'), (T oken.Text, u'\n'), (Token.Comment.Multiline, u'=begin\nsome ruby =begin nested = end\ncomment\n=end'), (Token.Text, u'\n\n'), (Token.Name.Builtin, u'puts'), (Tok en.Text, u' '), (Token.Literal.String.Double, u'"'), (Token.Literal.String.Doubl e, u'world'), (Token.Literal.String.Double, u'"'), (Token.Text, u'\n')]
import re regex = r'(#.*?$)|(=begin\s.*?\n=end.*?$)' re.findall(regex, code, flags=re.M | re.S)
Отредактировано EBFE (Сен. 22, 2012 04:21:12)
Офлайн
14
EBFEА как будет с # в строковом литерале?
или позаимствовать оттуда regexы
EBFEЧисто для комментов гимора гораздо меньше.
составлять вручную таблицы для bottom-up парсера извращение еще то
Отредактировано odnochlen (Сен. 22, 2012 20:05:22)
Офлайн
20
odnochlenНормально, просто “заимствовать” придется “правильно”
А как будет с # в строковом литерале?

Отредактировано EBFE (Сен. 22, 2012 22:04:43)
Офлайн
14
Что-то я по ссылкам ничего интересного не увидел.
Офлайн