Регулярное выражение для 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. Чем зарываться в дебри парсеростроения, может мне стоит отладиться на таких замечаниях? Можете еще что-нибудь найти в этом выражении?
Re[4]: Регулярное выражение для CS
От: regexp  
Дата: 22.11.09 22:40
Оценка:
Здравствуйте, Петрухин Эдуард, Вы писали:

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


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

Для "математика" это может звучать дико, как любой случай коверканья задачи под инструмент, но я оценил количество работы с парсером и сразу решил, что сделаю как можно более работоспособный регэксп, но не больше.
Re[2]: Регулярное выражение для CS
От: regexp  
Дата: 22.11.09 22:45
Оценка:
Здравствуйте, Аноним, Вы писали:

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


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


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


Ну и много вы наисследуете, если получите пачку ошибок от компайлера? Где можно, я использую отражение, но это не панацея.

Ладно, не в этом дело. Задача (выделенная болдом) через отражение не решается.
Re[3]: Регулярное выражение для CS
От: regexp  
Дата: 22.11.09 22:52
Оценка:
Здравствуйте, Niemand, Вы писали:

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


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

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

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

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

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

N>                // ... ну и так дальше
N>


Извините, это поделка. Я выше приводил пример регэкспа — вот он как раз был написан по аналогичному случаю: для поиска в исходном коде референсов (заданных через атрибуты). Собственно, в плюсах есть аналог — прагма lib (ЕМНИП).

Однако, не в этом дело. Дело в том, что мне нужно

>Конкретно интересует разбор кода одного-единственного класса на методы


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

_DA>Строго говоря, "регулярные выражения" в том виде, в котором они реализованы в большинстве языков/библиотек, выходят за рамки автоматных грамматик, но эта тема не для "Коллеги, улыбнитесь"


Спьяну ее сюда засунули, что ли? Весельчаки
Re[3]: Регулярное выражение для CS
От: Mr.Cat  
Дата: 22.11.09 23:03
Оценка:
Здравствуйте, regexp, Вы писали:
R>Парсер-шмарсер... Хотелось бы взять одно готовое выражение, отформатировать его (string.Format()) согласно прилагающейся инструкции и получить искомое.
Ты задачу штоле поподробнее опиши.
Но скорее всего регулярные выражения не самый удачный вариант — быстро накатаешь половину рабочей программы — потом напорешься на несколько хитрых частных случаев и будешь их до посинения отлаживать.
Re[4]: Регулярное выражение для CS
От: Кодт Россия  
Дата: 22.11.09 23:03
Оценка:
Здравствуйте, regexp, Вы писали:

_DA>>Строго говоря, "регулярные выражения" в том виде, в котором они реализованы в большинстве языков/библиотек, выходят за рамки автоматных грамматик, но эта тема не для "Коллеги, улыбнитесь"


R>Спьяну ее сюда засунули, что ли? Весельчаки


Исключительно от радости за невинность коллеги.
Однако, исправляю.
Перекуём баги на фичи!
Re[2]: Регулярное выражение для CS
От: Кодт Россия  
Дата: 22.11.09 23:06
Оценка:
Здравствуйте, Аноним, Вы писали:

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

А также всё, что похоже на атрибуты, но закомментировано. А также — всё, что находится внутри методов и является не атрибутами, а вызовами оператора []... и так далее, и тому подобное.
Перекуём баги на фичи!
Re[3]: Регулярное выражение для CS
От: Кодт Россия  
Дата: 22.11.09 23:13
Оценка:
Здравствуйте, _DAle_, Вы писали:

_DA>Строго говоря, "регулярные выражения" в том виде, в котором они реализованы в большинстве языков/библиотек, выходят за рамки автоматных грамматик, но эта тема не для "Коллеги, улыбнитесь"


Вот, кстати, давно хотел выяснить: регекспы с расширениями (perl-compatible) дотягивают до КС-грамматики, или образуют какой-то промежуточный класс грамматик между КС и регулярными (автоматными)?
И если дотягивают — как можно построить регексп из, например, БНФ?
У меня есть подозрение, что в любом случае размер регекспа очень нелинейно (вплоть до экспоненты) зависит от размера БНФ.
Поэтому, даже если автор и родит регексп, он либо не влезет в память, либо наглухо загрузит интерпретатор.
Перекуём баги на фичи!
Re[3]: Регулярное выражение для CS
От: regexp  
Дата: 22.11.09 23:18
Оценка:
Здравствуйте, Кодт, Вы писали:

К>но закомментировано.


Уже было.

>А также — всё, что находится внутри методов и является не атрибутами, а вызовами оператора []...


Это предусмотренный случай ССЗБ. Ничто, конечно, не мешает передать атрибут в индексер, но он не для этого предназначен.

>и так далее, и тому подобное.


А именно?
Re[4]: Регулярное выражение для CS
От: regexp  
Дата: 22.11.09 23:23
Оценка:
Здравствуйте, Mr.Cat, Вы писали:

MC>Здравствуйте, regexp, Вы писали:

R>>Парсер-шмарсер... Хотелось бы взять одно готовое выражение, отформатировать его (string.Format()) согласно прилагающейся инструкции и получить искомое.
MC>Ты задачу штоле поподробнее опиши.

Да ерунда, обычный редактор:

[+] [foo]
[-] void bar(object o)
|   {
|        int i = 0;
|   }


С некоторой спецификой, правда, не имеющей отношения к теме.

MC>Но скорее всего регулярные выражения не самый удачный вариант — быстро накатаешь половину рабочей программы — потом напорешься на несколько хитрых частных случаев и будешь их до посинения отлаживать.
Re[4]: Регулярное выражение для CS
От: _DAle_ Беларусь  
Дата: 23.11.09 06:47
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, _DAle_, Вы писали:


_DA>>Строго говоря, "регулярные выражения" в том виде, в котором они реализованы в большинстве языков/библиотек, выходят за рамки автоматных грамматик, но эта тема не для "Коллеги, улыбнитесь"


К>Вот, кстати, давно хотел выяснить: регекспы с расширениями (perl-compatible) дотягивают до КС-грамматики, или образуют какой-то промежуточный класс грамматик между КС и регулярными (автоматными)?


Немножко про это есть в википедии http://en.wikipedia.org/wiki/Regular_expression#Patterns_for_non-regular_languages

К>И если дотягивают — как можно построить регексп из, например, БНФ?

К>У меня есть подозрение, что в любом случае размер регекспа очень нелинейно (вплоть до экспоненты) зависит от размера БНФ.
К>Поэтому, даже если автор и родит регексп, он либо не влезет в память, либо наглухо загрузит интерпретатор.
Re[5]: Регулярное выражение для CS
От: midcyber
Дата: 23.11.09 08:31
Оценка:
Здравствуйте, regexp, Вы писали:

R>я оценил количество работы с парсером и сразу решил, что сделаю как можно более работоспособный регэксп, но не больше.


Начать работать с парсерами легко! На примере C# версии 2.0:

1. Скачиваешь Coco/R
Тебе понадобятся файлы Coco.exe, Scanner.frame, Parser.frame, CSharp2.ATG, CS2Parser.cs

2. Редактируешь файл CSharp2.ATG (сделай копию на всякий случай) — это описание грамматики
Первая треть файла — между COMPILER CS2 и CHARACTERS (SCANNER DESCRIPTION) — обычный C# код, можешь заводить там свои переменные, списки и методы.
Вторая часть — между CHARACTERS и PRODUCTIONS — описание терминалов — меняй, только если у тебя язык отличается от C#
Третья часть — после PRODUCTIONS — собственно грамматика. Свой C# код надо писать в блоках (. .), после соответствующих частей правил разбора.

Для нашего примера:
Описание StructMemberDeclaration<Modifiers m> дополняешь (мои правки выделены курсивом):
StructMemberDeclaration<Modifiers m> (. TypeKind type; Operator op; string memberName; .)
...
VariableDeclarators ";"
| /* Property | Indexer | Method */
MemberName<out memberName>    (. Console.WriteLine(memberName); .)

Тут мы указываем парсеру при каждой встрече элемента MemberName сохранять (out) его имя в переменную memberName (объявлена в самом начале правила) и выводить ее в консоль

Меняешь описание MemberName на такое:
MemberName<out string name>
= ident    (. name = t.val; .)
[ "::" ident (. name += "::"+t.val; .) ]
  [ IF (la.kind == _lt && IsPartOfMemberName()) TypeArgumentList ]
  { IF (la.kind == _dot && Peek(1).kind == _ident)
    "." ident (. name += "."+t.val; .)
    [ IF (la.kind == _lt && IsPartOfMemberName()) TypeArgumentList ]
  }
.

Тут мы просим MemberName накопить в строку то, что нашел парсер (t.val — это текущий найденный парсером токен,
то есть для строки "Buffer.Close" будут последовательно найдены "Buffer", ".", "Close", соответственно сработают первая и последняя части правил)

3. Генерируешь исходники сканера/парсера (я делал в командной строке):
coco.exe CSharp2.ATG

(должно быть сообщение parser + scanner generated, 0 errors detected)
4. Собираешь все это вместе (как вызывать парсер из своего кода, смотри в CS2Parser.cs)
csc.exe CS2Parser.cs Scanner.cs Parser.cs

5. Проверяешь
CS2Parser.exe somesourcefile.cs

Должна получиться распечатка имен методов.

Когда разберешься, можешь переходить к сигнатурам (TypeArgumentList), конструкторам и тому подобному, потом к квалифицированным именам.
Для последнего придется написать в первой части файла какой-то простенький стек, который хранит имя класса на текущей глубине разбора.
Re[5]: Регулярное выражение для CS
От: Mr.Cat  
Дата: 23.11.09 10:20
Оценка: +1
Здравствуйте, regexp, Вы писали:
R>Да ерунда, обычный редактор:
R>
R>[+] [foo]
R>[-] void bar(object o)
R>|   {
R>|        int i = 0;
R>|   }
R>

Ну если нужны только подсветка, фолдинг и прочие нехитрые вещи — тогда погляди, как это сделано в vim или notepad++. Думаю, в итоге там все сводится к прогону разными регулярными выражениями с разными приоритетами: сперва комментарии выявляются (и внутри них больше ничего не подсвечивается), потом строки и т.п.
Re[5]: Регулярное выражение для CS
От: Кодт Россия  
Дата: 23.11.09 11:38
Оценка:
Здравствуйте, _DAle_, Вы писали:

К>>Вот, кстати, давно хотел выяснить: регекспы с расширениями (perl-compatible) дотягивают до КС-грамматики, или образуют какой-то промежуточный класс грамматик между КС и регулярными (автоматными)?


_DA>Немножко про это есть в википедии http://en.wikipedia.org/wiki/Regular_expression#Patterns_for_non-regular_languages


Как-то уж очень немножко
Я так понял, регекспы с обратными отсылками описывают контекстно-зависимые грамматики (наверно, не всевозможные, а некое подмножество?)
Например,
/ alfa (beta) gamma \1 delta /

Соответствуют правила вывода
Regex -> Use beta
Use X -> alfa X gamma X delta


Кстати, неутешительно для топикстартера: сопоставление регекспа с бэкреференсами — NP-полная задача, т.е. парсер выжрет время-память.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Re[6]: Регулярное выражение для CS
От: _DAle_ Беларусь  
Дата: 23.11.09 23:07
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, _DAle_, Вы писали:


К>>>Вот, кстати, давно хотел выяснить: регекспы с расширениями (perl-compatible) дотягивают до КС-грамматики, или образуют какой-то промежуточный класс грамматик между КС и регулярными (автоматными)?


_DA>>Немножко про это есть в википедии http://en.wikipedia.org/wiki/Regular_expression#Patterns_for_non-regular_languages


К>Как-то уж очень немножко

К>Я так понял, регекспы с обратными отсылками описывают контекстно-зависимые грамматики (наверно, не всевозможные, а некое подмножество?)

Я тут сразу рванул писать, что Back references не спасают даже от классического контекстно-свободного языка AnBn (ну в смысле ab, aabb, aaabbb, ...). Но потом, погуглив и поспрашивав в IRC, нашел, что, например, в perl 5.10 можно сейчас вроде бы написать /^(a(?1)?b)$/, и таким образом используя рекурсию победить эту проблему. Но с другой стороны контекстно-зависимый AnBnCn уже так с помощью backreferences и recursion не воспроизведешь.

В общем, вроде бы получается так..
Множество языков, которые описывают regexp c Back references, пересекается с контекстно-свободными языками.
Множество языков, которые описывают regexp с Back references и recursion, содержат в себе все контекстно-свободные, и сами содержатся в множестве контекстно-зависимых.
Это все может оказаться неправдой, но похоже на нее
Re[7]: Регулярное выражение для CS
От: Кодт Россия  
Дата: 24.11.09 10:09
Оценка:
Здравствуйте, _DAle_, Вы писали:

_DA>Я тут сразу рванул писать, что Back references не спасают даже от классического контекстно-свободного языка AnBn (ну в смысле ab, aabb, aaabbb, ...). Но потом, погуглив и поспрашивав в IRC, нашел, что, например, в perl 5.10 можно сейчас вроде бы написать /^(a(?1)?b)$/, и таким образом используя рекурсию победить эту проблему. Но с другой стороны контекстно-зависимый AnBnCn уже так с помощью backreferences и recursion не воспроизведешь.


_DA>Множество языков, которые описывают regexp c Back references, пересекается с контекстно-свободными языками.


А не с КЗ? /([A-Z]+)_(?1)_(?1)/ как представить в КС?
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Re[8]: Регулярное выражение для CS
От: _DAle_ Беларусь  
Дата: 24.11.09 10:16
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, _DAle_, Вы писали:


_DA>>Я тут сразу рванул писать, что Back references не спасают даже от классического контекстно-свободного языка AnBn (ну в смысле ab, aabb, aaabbb, ...). Но потом, погуглив и поспрашивав в IRC, нашел, что, например, в perl 5.10 можно сейчас вроде бы написать /^(a(?1)?b)$/, и таким образом используя рекурсию победить эту проблему. Но с другой стороны контекстно-зависимый AnBnCn уже так с помощью backreferences и recursion не воспроизведешь.


_DA>>Множество языков, которые описывают regexp c Back references, пересекается с контекстно-свободными языками.


К>А не с КЗ? /([A-Z]+)_(?1)_(?1)/ как представить в КС?


Под пересекается я имел ввиду, что ни одно из множеств не содержит другое.
Re[6]: Регулярное выражение для CS
От: Au1  
Дата: 24.11.09 12:14
Оценка: -1
Здравствуйте, Mr.Cat, Вы писали:


MC>Ну если нужны только подсветка, фолдинг и прочие нехитрые вещи — тогда погляди, как это сделано в vim или notepad++. Думаю, в итоге там все сводится к прогону разными регулярными выражениями с разными приоритетами: сперва комментарии выявляются (и внутри них больше ничего не подсвечивается), потом строки и т.п.



Не прокатит по причине возможной вложенности одного в другое. Например:

/* ......... " ..../*...*/.... " ....... */..........."
и
".........../*...*/...".....".....*/........"

как ни парси регекспами, контрпример можно будет построить в общем случае.
Re[7]: Регулярное выражение для CS
От: Mr.Cat  
Дата: 25.11.09 11:11
Оценка:
Здравствуйте, Au1, Вы писали:
Au1>Не прокатит по причине возможной вложенности одного в другое. Например:
Au1>/* ......... " ..../*...*/.... " ....... */..........."
Au1>и
Au1>".........../*...*/...".....".....*/........"
В чем конкретно ты тут видишь проблему? Как, на твой взгляд, это распарсится регекспами? И как оно, на твой взгляд, должно распарситься? Я проблемы не вижу. Вот как парсит тутошний регексповый форматтер.
/* ......... " ..../*...*/.... " ....... */..........."

".........../*...*/...".....".....*/........"

VS парсит точно так же.

Au1>как ни парси регекспами, контрпример можно будет построить в общем случае.

Если речь идет о подсветке и фолдинге редакторе, то 100% корректной работы не нужно. Достаточно покрытия определенного процента ситуаций, я считаю.
Re[8]: Регулярное выражение для CS
От: Au1  
Дата: 25.11.09 12:41
Оценка:
Здравствуйте, Mr.Cat, Вы писали:

MC>
MC>/* ......... " ..../*...*/.... " ....... */..........."
MC>

MC>
MC>".........../*...*/...".....".....*/........"
MC>

MC>VS парсит точно так же.

Au1>>как ни парси регекспами, контрпример можно будет построить в общем случае.

MC>Если речь идет о подсветке и фолдинге редакторе, то 100% корректной работы не нужно. Достаточно покрытия определенного процента ситуаций, я считаю.

Возможно, пример не очень удачный. Давай попробую так:

MC>
MC>/* ......... " ..../*...*/.... " ....... */..........."
MC>

MC>
MC>".../* ......... " ..../*...*/.... " ....... */..........."
MC>

MC>
MC>"...".../* ......... " ..../*...*/.... " ....... */..........."
MC>

MC>
MC>"..."...".../* ......... " ..../*...*/.... " ....... */..........."
MC>


Если не трудно, приведи кусок местного кода, который различает эти ситуации. А именно, умеет понимать разницу между первыми тремя ситуациями. Может я не умею готовить регекспы, но с ходу не могу придумать, как различить эти ситуации. Зато умею это делать без регекспов — проходом по коду и запоминанием уровня вложенности и типа парной конструкции для каждого символа.
Re[4]: Регулярное выражение для CS
От: Au1  
Дата: 25.11.09 12:45
Оценка:
Здравствуйте, regexp, Вы писали:

R>А именно?


Текст, похожий на атрибут внутри строковой константы, например.
Re[9]: Регулярное выражение для CS
От: Mr.Cat  
Дата: 25.11.09 12:50
Оценка:
Здравствуйте, Au1, Вы писали:
Au1>Если не трудно, приведи кусок местного кода, который различает эти ситуации.
Код форматтера открыт — http://rsdn.ru/forum/rsdn/3465135.1.aspx
Автор: AndrewVK
Дата: 12.07.09
— найти нужное место недолго.
Емнип, там создается огромный регексп с именованными группами через | и на каждый матч проверяется, какая группа заматчилась. Что делается далее — не помню. Вроде особо никакого волшебства.
Re[2]: Регулярное выражение для CS
От: vdimas Россия  
Дата: 03.12.09 22:55
Оценка:
Здравствуйте, Петрухин Эдуард, Вы писали:

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

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

Не совсем так. Перловые регулярные выражения могут порождать грамматики, выходящие за рамки регулярных. Но с указанной задачей не справятся точно.
Re[7]: Регулярное выражение для CS
От: vdimas Россия  
Дата: 03.12.09 22:59
Оценка:
Здравствуйте, _DAle_, Вы писали:

_DA>Множество языков, которые описывают regexp с Back references и recursion, содержат в себе все контекстно-свободные, и сами содержатся в множестве контекстно-зависимых.


Т.е. задача все-таки решаема через regexp?
Фига се...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.