Регулярное выражение для CS
От: Аноним  
Дата: 20.11.09 17:33
Оценка: :))) :))) :))) :))) :))) :))) :))) :)
Никто не находил хороший регэксп для парсинга C#?

Конкретно интересует разбор кода одного-единственного класса на методы, но со всеми потрохами, в т.ч. вложенными классами. Написал свой, но не уверен в качестве, лучше всего бы какой-нибудь активно используемый.

21.11.09 17:29: Перенесено из '.NET'
23.11.09 02:02: Перенесено модератором из 'Коллеги, улыбнитесь' — Кодт
Re: Регулярное выражение для CS
От: Аноним  
Дата: 20.11.09 19:05
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Никто не находил хороший регэксп для парсинга C#?


А>Конкретно интересует разбор кода одного-единственного класса на методы, но со всеми потрохами, в т.ч. вложенными классами. Написал свой, но не уверен в качестве, лучше всего бы какой-нибудь активно используемый.


Не ожидал, что такой невинный вопрос вызовет такую бурю смеха.

Ну, вот такой регэксп успешно ищет все атрибуты:

\[\s*({0}|{0}Attribute)\s*\(\s*"[^"]*"\s*\)\s*\]


Тип атрибута (короткое имя) подставляется вместо {0}. Аналогичным образом, я написал регэксп посложнее, в который передаю все типы (они известны заранее), и который вычленяет методы из кода класса. Но он работает на более-менее простом коде, а все заморочки C#, боюсь, не учитывает. Вот я и подумал, что вместо шлифовки его на тоннах тестов лучше поискать отлаженный.
Re[2]: Регулярное выражение для CS
От: samius Япония http://sams-tricks.blogspot.com
Дата: 20.11.09 19:13
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Ну, вот такой регэксп успешно ищет все атрибуты:


А>

А>\[\s*({0}|{0}Attribute)\s*\(\s*"[^"]*"\s*\)\s*\]

* не все, а только одиночные с обязательным одиноким строковым параметром, причем в строке не встречаются кавычки
* ищет в том числе закомментированные атрибуты

успешным такой поиск назвать можно лишь условно
Re[3]: Регулярное выражение для CS
От: Аноним  
Дата: 20.11.09 19:24
Оценка:
Здравствуйте, samius, Вы писали:

А>>

А>>\[\s*({0}|{0}Attribute)\s*\(\s*"[^"]*"\s*\)\s*\]

S>* не все, а только одиночные с обязательным одиноким строковым параметром, причем в строке не встречаются кавычки

Это by design. Чисто для примера.

S>* ищет в том числе закомментированные атрибуты


Вот об этом и речь. Я как-то не подумал про комментарии. А сколько еще всего, про что я не подумал. Может быть, в опенсорсе есть код, который обтачивался как следует? Мне нужно определить границы методов класса, но чем регэксп универсальнее, тем лучше.

S>успешным такой поиск назвать можно лишь условно
Re[4]: Регулярное выражение для CS
От: Пельмешко Россия blog
Дата: 20.11.09 19:33
Оценка:
Здравствуйте, Аноним, Вы писали:

S>>успешным такой поиск назвать можно лишь условно


http://irony.codeplex.com/SourceControl/changeset/view/39566#157181
|> IronySamples/CSharp/CSharpGrammar.cs

Вперёд!
Re[5]: Регулярное выражение для CS
От: samius Япония http://sams-tricks.blogspot.com
Дата: 20.11.09 19:38
Оценка:
Здравствуйте, Пельмешко, Вы писали:

П>Здравствуйте, Аноним, Вы писали:


S>>>успешным такой поиск назвать можно лишь условно


П>http://irony.codeplex.com/SourceControl/changeset/view/39566#157181

П>|> IronySamples/CSharp/CSharpGrammar.cs

П>Вперёд!

Прикольно, но
this.GrammarComments = "NOTE: This grammar is just a demo, and it is a broken demo.\r\n" + 
                       "Demonstrates token preview technique to help parser resolve conflicts.\r\n";
Re: Регулярное выражение для CS
От: Петрухин Эдуард Россия  
Дата: 20.11.09 19:54
Оценка: 1 (1) +1
Здравствуйте, <Аноним>, Вы писали:

А>Никто не находил хороший регэксп для парсинга C#?


С помощью регулярных выражений распарсить код на C# (и, насколько я знаю, на любых других «полноценных» языках программирования) невозможно.
Дело в том, что регулярные выражения задают язык, синтаксис которого описывается автоматной грамматикой, а синтаксис C# описывается контексто-свободной грамматикой. Автоматная грамматика является частным случаем контекстно-свободной, так что регулярные выражения тебе не помогут.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Re[2]: Регулярное выражение для CS
От: Аноним  
Дата: 20.11.09 20:03
Оценка:
Здравствуйте, Петрухин Эдуард, Вы писали:

А>>Никто не находил хороший регэксп для парсинга C#?


ПЭ>С помощью регулярных выражений распарсить код на C# (и, насколько я знаю, на любых других «полноценных» языках программирования) невозможно.

ПЭ>Дело в том, что регулярные выражения задают язык, синтаксис которого описывается автоматной грамматикой, а синтаксис C# описывается контексто-свободной грамматикой. Автоматная грамматика является частным случаем контекстно-свободной, так что регулярные выражения тебе не помогут.

Никто не просит квадратуру круга. Используемые типы (и что еще входит в свободный контекст?) я могу подставить в регэксп, и предполагаю его как раз с такими "местами для вставок".
Re: Регулярное выражение для CS
От: Аноним  
Дата: 20.11.09 20:10
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Никто не находил хороший регэксп для парсинга C#?


А>Конкретно интересует разбор кода одного-единственного класса на методы, но со всеми потрохами, в т.ч. вложенными классами. Написал свой, но не уверен в качестве, лучше всего бы какой-нибудь активно используемый.

попробуйте поискать парсер C#
например вот тут есть:
ccisamples.codeplex.com, в ревизии 5590 был удален по запросу C# team
Re[3]: Регулярное выражение для CS
От: Петрухин Эдуард Россия  
Дата: 20.11.09 20:51
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>... Используемые типы (и что еще входит в свободный контекст?) я могу подставить в регэксп ...

Ты не правильно понимаешь термин «контексто-свободная грамматика». Рекомендую поискать по словосочетанию «Иерархия грамматик Хомского».

А>..., и предполагаю его как раз с такими "местами для вставок".

Я тебя уверяю — регулярные выражения тебе не помогут, только зря потратишь время. Для примера: ты в исходном посте упомянул о вложенных классах. Это называется «самовложением». Самовложение — характерный признак контекстно-свободных грамматик (если бы отсутствовали самовложения, грамматика была бы автоматной). Никаким регулярным выражением самовложения тебе не одолеть.
С помощью регулярного выражения можно описать, например, язык идентификаторов или язык чисел, но вот язык арифметических выражений уже не удастся.

Лучше поищи готовый парсер языка или напиши свой (это не очень сложно, хотя и не совсем просто ).
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Re: Регулярное выражение для CS
От: Аноним  
Дата: 20.11.09 21:16
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Никто не находил хороший регэксп для парсинга C#?


А>Конкретно интересует разбор кода одного-единственного класса на методы, но со всеми потрохами, в т.ч. вложенными классами. Написал свой, но не уверен в качестве, лучше всего бы какой-нибудь активно используемый.


Мое любимое регулярное выражение на этот случай — такое. Код компилируется, результурующая сборка поднимается через reflection и исследуется.
Re[2]: Регулярное выражение для CS
От: Lloyd Россия  
Дата: 20.11.09 23:06
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Ну, вот такой регэксп успешно ищет все атрибуты:


А>

А>\[\s*({0}|{0}Attribute)\s*\(\s*"[^"]*"\s*\)\s*\]


Не ищет он атрибуты. Наличие Attribute — опционально.
Re[3]: Регулярное выражение для CS
От: Пельмешко Россия blog
Дата: 21.11.09 11:49
Оценка: +1
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, Аноним, Вы писали:


А>>Ну, вот такой регэксп успешно ищет все атрибуты:


А>>

А>>\[\s*({0}|{0}Attribute)\s*\(\s*"[^"]*"\s*\)\s*\]


L>Не ищет он атрибуты. Наличие Attribute — опционально.


Там у него alternation: {0}|{0}Attribute, так что опциональность учёл.

Не учёл comma-separated атрибуты в одних квадратных скобках, не учёл verbatim strings, не учёл не строковые аргументы, named-параметры, вообще без параметров атрибуты... Можно вечно продолжать
Re[4]: Регулярное выражение для CS
От: koandrew Канада http://thingselectronic.blogspot.ca/
Дата: 21.11.09 12:15
Оценка:
Здравствуйте, Петрухин Эдуард, Вы писали:

ПЭ>Лучше поищи готовый парсер языка или напиши свой (это не очень сложно, хотя и не совсем просто ).


Да вроде ничего сложного нет, ибо имеются генераторы парсеров по формальному определению (по грамматике). Грамматика C# описана тут. Дерзай!
[КУ] оккупировала армия.
Re: Регулярное выражение для CS
От: Mr.Cat  
Дата: 21.11.09 15:05
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Конкретно интересует разбор кода одного-единственного класса на методы, но со всеми потрохами, в т.ч. вложенными классами. Написал свой, но не уверен в качестве, лучше всего бы какой-нибудь активно используемый.
Если надо анализировать только структуру классов (без кода методов и т.п.) — то проще скомпилировать в сборки и изучать ее через reflection.
Если такой способ не подходит — ищи готовые парсеры сишарпа (например, гугли по "csharp parser"). Например, парсер шарпа должен быть как минимум в mono — вот только неизвестно, в каком он там виде и применим ли в твоем случае.
Re[2]: Регулярное выражение для CS
От: _DAle_ Беларусь  
Дата: 21.11.09 15:38
Оценка: +1
Здравствуйте, Петрухин Эдуард, Вы писали:

ПЭ>Здравствуйте, <Аноним>, Вы писали:


А>>Никто не находил хороший регэксп для парсинга C#?


ПЭ>С помощью регулярных выражений распарсить код на C# (и, насколько я знаю, на любых других «полноценных» языках программирования) невозможно.

ПЭ>Дело в том, что регулярные выражения задают язык, синтаксис которого описывается автоматной грамматикой, а синтаксис C# описывается контексто-свободной грамматикой. Автоматная грамматика является частным случаем контекстно-свободной, так что регулярные выражения тебе не помогут.

Строго говоря, "регулярные выражения" в том виде, в котором они реализованы в большинстве языков/библиотек, выходят за рамки автоматных грамматик, но эта тема не для "Коллеги, улыбнитесь"
Re[2]: Регулярное выражение для CS
От: Niemand Австралия  
Дата: 21.11.09 16:48
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Мое любимое регулярное выражение на этот случай — такое. Код компилируется, результурующая сборка поднимается через reflection и исследуется.


подобную фичу сделал пару недель назад на своем проекте, могу вот поделиться (чуть подредактировал):

        public static SomeDataClass[] CompileContext(string filename)
        {
            try
            {
                // устанавливаем в режим c# 3.0, BCL 3.5, чтобы кушало лябмды и другое
                CSharpCodeProvider codeProvider = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion",
"v3.5" } });

                var result = codeProvider.CompileAssemblyFromFile(new CompilerParameters(new[] { 
                // какие либы здесь надо, а какие не надо - это индивидуйно, меняйте под себя
                "System.dll",
                "System.Data.dll",
                "System.Core.dll",
                "System.Web.Services.dll"}, Guid.NewGuid() + ".dll"), // конечно тут надо написать Path.GetTempFile()+".dll", но в моей задаче сойдет и так
                    filename);

                var assembly = result.CompiledAssembly; // получаем сборку (или исключение)

                var contextType = assembly.GetTypes().FirstOrDefault(t => t.BaseType == typeof(SomeMyBaseType)); 
                // если класс всего один можно заменить на 
                // var contextType = assembly.GetTypes().FirstOrDefault(); 

                // дальше вытягиваем список методов (у меня там идет другая логика, потому скопипастил с http://www.csharp-examples.net/get-method-names/ )
                MethodInfo[] methodInfos = typeof(MyClass).GetMethods(); // и добавляем .Select(m=>m.Name).ToList() или как-то так если надо только имена методов

                // ... ну и так дальше
If the message above is in English — means I'm wasting my work time and work computer to post here. No hard feelings
Re[2]: Регулярное выражение для CS
От: regexp  
Дата: 22.11.09 22:22
Оценка:
Здравствуйте, Mr.Cat, Вы писали:

MC>Если надо анализировать только структуру классов (без кода методов и т.п.) — то проще скомпилировать в сборки и изучать ее через reflection.

А>>Конкретно интересует разбор кода одного-единственного класса на методы, но со всеми потрохами, в т.ч. вложенными классами. Написал свой, но не уверен в качестве, лучше всего бы какой-нибудь активно используемый.

MC>Если такой способ не подходит — ищи готовые парсеры сишарпа (например, гугли по "csharp parser"). Например, парсер шарпа должен быть как минимум в mono — вот только неизвестно, в каком он там виде и применим ли в твоем случае.


Парсер-шмарсер... Хотелось бы взять одно готовое выражение, отформатировать его (string.Format()) согласно прилагающейся инструкции и получить искомое.
Re[5]: Регулярное выражение для CS
От: regexp  
Дата: 22.11.09 22:23
Оценка:
Здравствуйте, Пельмешко, Вы писали:

П>Здравствуйте, Аноним, Вы писали:


S>>>успешным такой поиск назвать можно лишь условно


П>http://irony.codeplex.com/SourceControl/changeset/view/39566#157181

П>|> IronySamples/CSharp/CSharpGrammar.cs

П>Вперёд!


Посмотрю, хотя мне уже не нравится.
Re[4]: Регулярное выражение для CS
От: regexp  
Дата: 22.11.09 22:32
Оценка:
Здравствуйте, Пельмешко, Вы писали:

П>Там у него alternation: {0}|{0}Attribute, так что опциональность учёл.


Именно.

П>Не учёл comma-separated атрибуты в одних квадратных скобках


Да.

>не учёл verbatim strings


Да.

>не учёл не строковые аргументы, named-параметры, вообще без параметров атрибуты...


Нет. Я не сразу уточнил, что это для более узкого поиска атрибутов, паттерн которых известен (один обязательный строковый параметр).

>Можно вечно продолжать


Да я не знаю даже. Ну вот, пока три замечания поступило: фальшсрабатывания на комментариях, @"" и comma-separated. Чем зарываться в дебри парсеростроения, может мне стоит отладиться на таких замечаниях? Можете еще что-нибудь найти в этом выражении?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.