Уведомления

Группа в Telegram: @pythonsu

#1 Сен. 20, 2012 20:59:40

Relrin
Зарегистрирован: 2012-09-12
Сообщения: 13
Репутация: +  0  -
Профиль   Отправить e-mail  

Анализ строк

Пишу парсер 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)

Как можно осуществить поиск по =begin … =end, в котором бы я учитывал строки? и вернуть значение потом как “свойство”? Ведь нужно еще учесть строки, которые могут попасть в блок =begin … =end

Офлайн

#2 Сен. 20, 2012 21:32:43

odnochlen
Зарегистрирован: 2012-06-28
Сообщения: 794
Репутация: +  14  -
Профиль   Отправить e-mail  

Анализ строк

Relrin
Пишу парсер Ruby
Good luck

Традиционно парсеры пишутся с использованием конечных автоматов.

Офлайн

#3 Сен. 21, 2012 04:23:23

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10015
Репутация: +  857  -
Профиль   Отправить e-mail  

Анализ строк

Relrin
Класс: Поиск в коде однострочных комментариев вида ‘#’ и многострочных вида ‘=begin … =end’
найди в интернете классическую задачу про удаление комментариев C из исходного файла



Офлайн

#4 Сен. 22, 2012 02:48:44

EBFE
Зарегистрирован: 2012-07-03
Сообщения: 99
Репутация: +  20  -
Профиль   Отправить e-mail  

Анализ строк

odnochlen
Традиционно парсеры пишутся с использованием конечных автоматов.
Настоящие программисты записывают байты на хард намагниченной иголкой
http://xkcd.com/378/
А вообще для этого существуют парсер-генераторы, ибо составлять вручную таблицы для bottom-up парсера извращение еще то

Хотя если в этом случае, если нужны только комментарии, можно использовать pygments:
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')]
или позаимствовать оттуда regexы
import re
regex = r'(#.*?$)|(=begin\s.*?\n=end.*?$)'
re.findall(regex, code, flags=re.M | re.S)

Отредактировано EBFE (Сен. 22, 2012 04:21:12)

Офлайн

#5 Сен. 22, 2012 20:04:22

odnochlen
Зарегистрирован: 2012-06-28
Сообщения: 794
Репутация: +  14  -
Профиль   Отправить e-mail  

Анализ строк

EBFE
или позаимствовать оттуда regexы
А как будет с # в строковом литерале?

EBFE
составлять вручную таблицы для bottom-up парсера извращение еще то
Чисто для комментов гимора гораздо меньше.

Отредактировано odnochlen (Сен. 22, 2012 20:05:22)

Офлайн

#6 Сен. 22, 2012 21:58:34

EBFE
Зарегистрирован: 2012-07-03
Сообщения: 99
Репутация: +  20  -
Профиль   Отправить e-mail  

Анализ строк

odnochlen
А как будет с # в строковом литерале?
Нормально, просто “заимствовать” придется “правильно”
http://pygments.org/demo/55113/
http://pygments.org/demo/55115/

Отредактировано EBFE (Сен. 22, 2012 22:04:43)

Офлайн

#7 Сен. 23, 2012 00:21:53

odnochlen
Зарегистрирован: 2012-06-28
Сообщения: 794
Репутация: +  14  -
Профиль   Отправить e-mail  

Анализ строк

Что-то я по ссылкам ничего интересного не увидел.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version