Найти - Пользователи
Полная версия: Анализ строк
Начало » Python для новичков » Анализ строк
1
Relrin
Пишу парсер 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
odnochlen
Relrin
Пишу парсер Ruby
Good luck

Традиционно парсеры пишутся с использованием конечных автоматов.
py.user.next
Relrin
Класс: Поиск в коде однострочных комментариев вида ‘#’ и многострочных вида ‘=begin … =end’
найди в интернете классическую задачу про удаление комментариев C из исходного файла
EBFE
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)
odnochlen
EBFE
или позаимствовать оттуда regexы
А как будет с # в строковом литерале?

EBFE
составлять вручную таблицы для bottom-up парсера извращение еще то
Чисто для комментов гимора гораздо меньше.
EBFE
odnochlen
А как будет с # в строковом литерале?
Нормально, просто “заимствовать” придется “правильно”
http://pygments.org/demo/55113/
http://pygments.org/demo/55115/
odnochlen
Что-то я по ссылкам ничего интересного не увидел.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB