日期:2009-06-03  浏览次数:20502 次

一个简明的编译器



多次看到有人提起文本表达式的计算问题,就动手整理以前的代码并加上注释。

写一个简单的编译器并不是很复杂的,当中要用到些反射的知识。自已觉得,反射的使用在NET中真是无处不在,使用反射没什么效率不效率的问题,毕竟现在的电脑配置并不是很低。适当使用反射,或者通过使用反射本身,会使自己加深对NET的理解。以后会写些运用反射增加代码灵活性的小”文章”供初学者参考。



如果只是计算表达式的值的,当然用不了那么多的代码.这样写法,只是使它通用性强些.


以下的我直接贴代码了,不再说些什么(可以说如何如何臭,只是不许骂人)。



Imports System.Reflection

Imports System.CodeDom

Imports System.CodeDom.Compiler

Public Class SourceComp



'//编译器接口

Private m_Compiler As ICodeCompiler

'//编译器参数

Private m_CompilerParameters As CompilerParameters

'//引用的程序集

Private m_RefAssemblies As String() = {"System.dll", "System.Data.dll"}

'//源代码

Private m_Source As String = ""

'//记录是否是默认的源代码

Private m_Is_Default As Boolean = True

'//记录编译状态

Private m_Compiled As Boolean = False

'//编译生成的程序集

Private m_Assembly As System.Reflection.Assembly

'//默认源代码生成的实例

Private m_tmpClass As Object

'//默认源代码生成的实例函数

Private m_MethodInfo As System.Reflection.MethodInfo

'//默认源代码函数的表达式参数

Private m_Expression As String

'//返回程序集

Public ReadOnly Property cpAssembly() As System.Reflection.Assembly

Get

Return Me.m_Assembly

End Get

End Property

Sub New()

'//获取VB编译器实例

Me.m_Compiler = New VBCodeProvider().CreateCompiler

'//初始编译器参数

Me.m_CompilerParameters = New CompilerParameters

With Me.m_CompilerParameters

.GenerateExecutable = False '//False值指定编译为类集,True编译为可执行程序

.GenerateInMemory = False '//只在内存中生成程序集,不输出到磁盘

'//添加默认的程序集

Me.Add_CompilerParameters()

End With

End Sub



'//添加要引用的程序集

Private Sub Add_CompilerParameters()

Me.m_CompilerParameters.ReferencedAssemblies.AddRange(Me.m_RefAssemblies)

End Sub

'//添加指定的引用程序集

Public Sub Add_CompilerParameters(ByVal RefAssemblies As String())

Me.m_RefAssemblies = RefAssemblies

Me.m_CompilerParameters.ReferencedAssemblies.Clear() '//清除原有的程序集,重复引用编译会产生异常

Me.Add_CompilerParameters()

End Sub



'//生成默认的源代码

'//类名:tmpClass

'//函数名:GetExpressionValue ,参数:Expression ,参数类型:字符串

'//主要功能:返回表达式Expression的值 ,返回值类型:Object

Private Sub BuildDefaultSource()

Dim mCodeBuilder As CodeBuilder = New CodeBuilder

With mCodeBuilder

.AppendCode("Imports System")

.AppendCode("Imports System.Data")

.AppendCode("Imports System.Math")

.AppendCode("Imports Microsoft.VisualBasic")

.AppendCode()

.AppendCode("Public Class tmpClass")

.AppendCode(" Public Function GetExpressionValue() As Object")

.AppendCode(" Dim Result As Object")

.AppendCode(" Result={0}") '这里传入表达式

.AppendCode(" Return Result")

.AppendCode(" End Function")

.A