C #: создание синтаксического анализатора метода - PullRequest
0 голосов
/ 20 апреля 2011

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

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

1 Ответ

4 голосов
/ 20 апреля 2011

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

Хотя его основное использование для SharpDevelop (инструмент с графическим интерфейсом), это отдельная DLL, и ее можно использовать в любом приложении .NET.Насколько я могу судить, документация не очень тщательная, но 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, я попытался создать мудрую грамматику для c # .Это было для использования в Emacs, который имеет движок.

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


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

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

...