Библиотека синтаксического анализа строки .Net или регулярное выражение для анализа файлов кода - PullRequest
3 голосов
/ 05 марта 2009

Я бы хотел иметь возможность анализировать файлы кода vb.net, чтобы я мог изучить коллекцию подпрограмм, функций (и их содержимое, включая комментарии), личных переменных и т. Д.

I может быть открытыми файлами исходного кода.

Так, например, если у меня есть:

Public Function FunctionOne(arg1 As String, arg2 as String) as Integer
   here is some code
   ''//here are some comments
End Function

Public Sub FunctionOne(arg1 As integer, arg2 as integer)
   here is some code
   ''//here are some comments
End Sub

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

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

Есть предложения?

UPDATE: Главное, чего я пытаюсь добиться, - это разбор исходного кода, так что рефлексия вполне подходит для получения списка функций, а что нет, и я знаю, как это сделать, но это правильный способ парсинг исходного кода пытаюсь выяснить.

Ответы [ 7 ]

6 голосов
/ 05 марта 2009

А как насчет компиляции их во время выполнения из вашей программы и последующего использования отражения в скомпилированной библиотеке?

посмотрите на эту ветку Microsoft , чтобы узнать, как это сделать!

3 голосов
/ 06 марта 2009

Вы должны использовать библиотеку NRefactory, поставляемую с SharpDevelop .

Эта библиотека позволяет вам анализировать файлы VB или C #. Он в основном используется для преобразователя кода , но может использоваться и для анализа кода (это то, что мы делаем в нашей компании).

С этим кодом:

Imports System

Class MainClass
  Public Function FunctionOne(arg1 As String, arg2 As String) As Integer
    Return Int32.Parse(arg1) + Int32.Parse(arg2)
  End Function

  Public Sub FunctionOne(arg1 As Integer, arg2 As Integer)
    Return
  End Sub

End Class

Вы можете получить такой результат (я использовал приложение NRefactoryDemo здесь) альтернативный текст http://img15.imageshack.us/img15/3564/stackoverflownrefactory.png

1 голос
/ 16 октября 2009

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

Большое спасибо!

1 голос
/ 07 марта 2009

Этот код является грубым, но более или менее выполняет то, что я намеревался сделать:

Private _SourceCode As String = Nothing
Private ReadOnly Property SourceCode() As String
                Get
                    If _SourceCode = Nothing Then
                        Dim thisCodeFile As String = Server.MapPath("~").ToString & "\" & Type.GetType(Me.GetType.BaseType.FullName).ToString & ".aspx.vb"
                        _SourceCode = My.Computer.FileSystem.ReadAllText(thisCodeFile)
                    End If
                    Return _SourceCode
                End Get
End Property  

Private Function extractProcedureDefinition(ByVal procedureName As String) As String
   Return extractStringContents(Me.SourceCode, "Sub " & procedureName & "()", "End Sub", True)
End Function  

Private Function extractFunctionDefinition(ByVal procedureName As String) As String
   'TODO: This works now, but wouldn't if we wanted includeTags = False, as it does not properly handle the "As xxxxx" portion
   Return extractStringContents(Me.SourceCode, "Function " & procedureName, "End Sub", True)
End Function

    Private Function extractStringContents(ByVal body As String, ByVal openTag As String, ByVal closeTag As String, ByVal includeTags As Boolean) As String
                Dim iStart As Integer = body.IndexOf(openTag)
                Dim iEnd As Integer = body.IndexOf(closeTag, iStart)
                If includeTags Then
                    iEnd += closeTag.Length
                Else
                    iStart += openTag.Length
                End If
                Return body.Substring(iStart, iEnd - iStart)
    End Function  
1 голос
/ 05 марта 2009

Я думаю, вы могли бы использовать Visual Basic.NET Lexical Grammar и генераторы синтаксических анализаторов, такие как Flex и Bison (в C / C ++) или что-то в этом роде. как Antlr (для .NET).

Вот как компиляторы анализируют языки для выполнения своей работы.

0 голосов
/ 05 марта 2009

Вы можете скомпилировать объект, а затем использовать инструмент Reflector . Мы все думаем о Reflector как о основном инструменте с графическим интерфейсом, и одна из его замечательных функций - возможность декомпиляции сборки .NET. Это может произвести источник из DLL или EXE. Но сам Reflector может управляться программно. Так что ваше приложение может

  • Скомпилируйте источник в сборку
  • вызовите Reflector, попросите декомпилировать
  • программно возиться с выходом Reflector - получить список функций и декомпилированный источник, связанный с ним.

Пример .

Этот подход может не удовлетворить - потому что источник, который вы получаете от Reflector, является не исходным, а декомпилированным источником. Комментарии пропадут, и декомпиляция не на 100% верна оригиналу. Функционально эквивалентен, но не на 100% текстуально одинаков.

Во всяком случае, стоит посмотреть.

0 голосов
/ 05 марта 2009

Я думаю, что вы ищете Microsoft.CSharp.CSharpCodeProvider, он принимает файл и обеспечивает прямой доступ к генератору и компилятору кода C #. Я полагаю, что он также может принимать строку.

MSDN: http://msdn.microsoft.com/en-us/library/microsoft.csharp.csharpcodeprovider.aspx

Edit:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...