C #: создание анализатора Methodheader

#c# #parsing #methods #text-parsing

#c# #синтаксический анализ #методы #синтаксический анализ текста

Вопрос:

Я хотел бы написать синтаксический анализатор, который сообщал бы мне, какая часть строки является methodheader. Каков наилучший способ сделать это на C #?

Спецификацию грамматики языка можно найти здесь . Я не думаю, что это правильный BNF / EBNF, поэтому, возможно, есть способ преобразовать его в такой (например, анализатор html, который помещает его в правильный BNF.)

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

Комментарии:

1. Что касается меня ограничивает то, что мне нужно создать его самостоятельно, без помощи внешних инструментов. … это домашнее задание?

2. Вау, 4 с. Циничная толпа, я полагаю. Нет, это не домашнее задание. Просто мне не нравится использовать инструменты других людей, и я знаю, как люди любят использовать их здесь, когда речь идет о синтаксическом анализе.

3. Итак, вам нравится заново изобретать колесо? В этом очень мало пользы, IMO.

4. Причина, по которой я спросил о «без помощи внешних инструментов», заключается в том, что… что ж, смотрите мой ответ.

5. Хммм, все вы, пожалуйста, не поймите это неправильно, но то, как происходит этот диалог с комментариями, вероятно, непродуктивно.

Ответ №1:

Я обнаружил, что библиотека NRefactory, входящая в состав инструмента SharpDevelop с открытым исходным кодом, очень хороша при разборе модулей C # в абстрактное синтаксическое дерево.Получив это, вы можете очень легко сканировать, чтобы найти заголовки методов, местоположения и так далее.

Хотя в основном он используется в SharpDevelop (инструмент с графическим интерфейсом), это автономная библиотека DLL, и ее можно использовать в любой .СЕТЕВОЕ приложение. Документация, насколько я мог судить, не очень подробная, но Reflector позволил мне изучить ее и довольно легко во всем разобраться.

некоторый код:

     internal static string CreateAstSexpression(string filename)
    {
        using (var fs = File.OpenRead(filename))
        {
            using (var parser = ParserFactory.CreateParser(SupportedLanguage.CSharp,
                                                           new StreamReader(fs)))
            {
                parser.Parse();

                // RetrieveSpecials() returns an IList<ISpecial>
                // parser.Lexer.SpecialTracker.RetrieveSpecials()...
                // "specials" == comments, preprocessor directives, etc.

                // parser.CompilationUnit retrieves the root node of the result AST
                return SexpressionGenerator.Generate(parser.CompilationUnit).ToString();
            }
        }
    }
  

Класс ParserFactory является частью NRefactory.
В моем случае мне нужно было s-выражение lisp, описывающее буфер C #, поэтому я написал генератор S-выражений, который проходил через «CompilationUnit». Это просто дерево узлов, начинающееся с пространства имен, затем class / struct / enum. Внутри узла класса / структуры есть узлы метода (а также поле, свойство и т.д.).


Если эта готовая DLL не представляет интереса, то, возможно, это.

Прежде чем найти и использовать NRefactory, я попытался создать грамматику wisent для c #. Это было сделано для использования в emacs, который имеет движок wisent.

Я никогда не мог заставить его работать должным образом. Может быть, это вам пригодится.


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

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

Комментарии:

1. Спасибо. Возможно, мне придется пересмотреть свое ограничение.

2. В итоге я установил git, чтобы получить весь репозиторий sharp development. Был ли простой способ получить только DLL? Кроме того, reflector все еще работает у вас? В прошлый раз, когда я пытался его использовать, он сам себя удалил.