#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 все еще работает у вас? В прошлый раз, когда я пытался его использовать, он сам себя удалил.