Ver Mensaje Individual
  #2 (permalink)  
Antiguo 07-11-2006, 09:30:51
acalanto acalanto is offline
Moderador
 
Registrado: dic 2002
Ubicación: Madrid
Posts: 4.271
acalanto ha deshabilitado la reputación
Predeterminado

Para realizar un compilador de un determinado lenguaje, lo primero es crear un parser sintáctico de las sentencias recogidas en el código. Sinceramente es un tema en el que, una vez comprendida la mecánica de análisis, no es tan complejo de desarrollar, pero sí de escribir sin que tenga errores de detección y que pase cosas 'por alto'.

El siguiente paso sería 'linkar' todos los objetos y convertirlos a código binario (Entendible por el procesador) o a un BYTECODE o precompilado que pueda procesar un Framework (.NET), una máquina virtual (JAVA) o cualquier otro kernel creado por ti misma.

Copia este código en el formulario y si quieres puedes ampliar la función 'menmotecnicos' tanto como necesites. Así podrás compilar una, dos o doscientas líneas de código. Como ves, a pesar de que VB60 no es la mejor herramienta para desarrollar un compilador, se puede intentar.



Código:
Option Explicit

                Dim Data_Error As Integer
                Dim err_var As String
                
                'Segmentos de datos, código, pila y extra
                Dim ds()            As Variant
                Dim cs()            As String
                Dim ss()            As String
                Dim es()            As Variant
                
                'Punteros de base
                Dim bp              As String
                
                'Nombre programa
                Dim program         As String
                Dim devices         As String

Private Sub Mn_Salir_Click()
    End
End Sub
Private Sub Mn_Nuevo_Click()
    On Local Error Resume Next
    'Limpiamos consolas de código y mnemotécnicos
    Me.txtConsola.Text = ""
    Me.List1.Clear
End Sub
Private Function parse(lin As String) As String()
    Dim arr()       As String
    Dim prs()       As String
    Dim itms        As Long
    Dim mnt()       As String
    Dim mbp         As Integer
    On Local Error Resume Next
    'Eliminar tabulaciones y espacios
    Do Until InStr(lin, vbTab) = 0
        lin = Mid(lin, 1, InStr(lin, vbTab) - 1) + Mid(lin, InStr(lin, vbTab) + 1)
    Loop
    Do Until InStr(lin, " ") = 0
        lin = Mid(lin, 1, InStr(lin, " ") - 1) + Mid(lin, InStr(lin, " ") + 1)
    Loop
    'Desmembrar comandos de la línea
    itms = 0
    Do Until InStr(lin, ";") = 0
        itms = itms + 1
        ReDim Preserve arr(1 To itms)
        arr(itms) = Mid(lin, 1, InStr(lin, ";"))
        lin = Mid(lin, InStr(lin, ";") + 1)
    Loop
    If itms = 0 Then
        ReDim arr(1 To 1)
        arr(1) = lin
        parse = mnemotecnicos(arr())
    Else
        parse = mnemotecnicos(arr())
    End If
End Function
Private Sub Mn_Compilar_Click()
    Dim arr()           As String
    Dim cmds()          As String
    Dim i               As Long, j As Long
    Dim objetos         As Long
    Dim errores         As Long
    On Local Error Resume Next
    'Iniciar objetos
    program = ""
    devices = ""
    objetos = 0
    errores = 0
    Erase es
    Erase ds
    Erase ss
    Me.List1.Clear
    'Desmemmbrar líneas de texto
    arr = Split(Me.txtConsola.Text, vbCrLf)
    For i = LBound(arr) To UBound(arr)
        cmds = parse(arr(i))
        For j = LBound(cmds) To UBound(cmds)
            objetos = objetos + 1
            If Left(cmds(j), 3) = "ERR" Then
                errores = errores + 1
                Me.List1.AddItem "Error en línea: " + CStr(i) + " :: " + Mid(cmds(j), 4)
            Else
                If Trim(cmds(j)) <> "" Then Me.List1.AddItem cmds(j)
            End If
        Next j
        'por seguridad destruimos array
        Erase cmds
    Next i
    'Informa final
    Me.List1.AddItem " "
    Me.List1.AddItem " INFORME DE PARSER"
    Me.List1.AddItem " ================="
    If program = "" Then
        Me.List1.AddItem "PROGRAM:<falta nombre aplicación>"
    Else
        Me.List1.AddItem "PROGRAM:" + program
        If devices = "" Then
            Me.List1.AddItem "DISPOSITIVOS:<ninguno>"
        Else
            Me.List1.AddItem "DISPOSITIVOS:" + devices
        End If
    End If
    Me.List1.AddItem "Objetos procesados: " + CStr(objetos)
    Me.List1.AddItem "Errores: " + CStr(errores)
End Sub

Private Function mnemotecnicos(arr() As String) As String()
    Dim m()         As String
    Dim mns         As Long
    Dim i           As Long
    Dim ptr         As Long
    On Local Error Resume Next
    mns = 0
    For i = LBound(arr) To UBound(arr)
        mns = mns + 1
        ReDim Preserve m(1 To mns)
        If InStr(arr(i), ";") = 0 Then
            'SENTENCIAS SIN TERMINADOR
            If Left(arr(i), 1) = "{" Or Left(arr(i), 2) = "{*" Then
                m(mns) = "[COMENTARIO]            "
            ElseIf Left(LCase(arr(i)), 3) = "if(" Then
                m(mns) = "[IF        ]"
                m(mns) = m(mns) + Mid(arr(i), 4)
                m(mns) = Left(m(mns), Len(m(mns)) - 1)
            ElseIf Left(LCase(arr(i)), 5) = "endif" Then
                m(mns) = "[ENDIF      ]"
            ElseIf Left(LCase(arr(i)), 7) = "elseif(" Then
                m(mns) = "[ELSEIF    ]"
            ElseIf Left(LCase(arr(i)), 7) = "program" Then
                If InStr(arr(i), "(") <> 0 Then
                    arr(i) = Mid(arr(i), 8)
                    program = Mid(arr(i), 1, InStr(arr(i), "(") - 1)
                    devices = Mid(arr(i), InStr(arr(i), "(") + 1)
                    devices = IIf(Right(devices, 1) = ")", Mid(devices, 1, Len(devices) - 1), devices)
                Else
                    program = Mid(arr(i), 8)
                    devices = ""
                End If
            Else
                If Trim(m(mns)) <> "" Then
                    m(mns) = "ERRError: Falta ';'"
                End If
            End If
        Else
            'SENTENCIAS CON TERMINADOR
            'Eliminamod el terminador ';'
            arr(i) = Left(arr(i), Len(arr(i)) - 1)
            If Left(LCase(arr(i)), 4) = "cons" Then
                m(mns) = "[CONST     ]"
                'Añadimos en el segmento extra
                ptr = UBound(es)
                ptr = ptr + 1
                ReDim es(1 To ptr + 1)
                es(ptr) = Mid(arr(i), InStr(arr(i), "=") + 1)
                'Agregamos el puntero del ESEGMENT que recoge el valor de la constante
                m(mns) = m(mns) + "ES:" + CStr(ptr)
            ElseIf Left(LCase(arr(i)), 3) = "var" Then
                m(mns) = "[VAR       ]"
                'Añadimos en el segmento extra
                ptr = UBound(ds)
                ptr = ptr + 1
                ReDim ds(1 To ptr + 1)
                ds(ptr) = Mid(arr(i), InStr(arr(i), "=") + 1)
                'Agregamos el puntero del DATASEGEMENT que recoge el valor de la variable
                m(mns) = m(mns) + "DS:" + CStr(ptr)
            Else
                If InStr(arr(i), "=") <> 0 Then
                    m(mns) = "[OPR       ]"
                    'Añadimos en el segmento stack
                    ptr = UBound(ss)
                    ptr = ptr + 1
                    ReDim ds(1 To ptr + 1)
                    ss(ptr) = Mid(arr(i), InStr(arr(i), "=") + 1)
                    'Agregamos el puntero del STACKSEGMENT que recoge la expresión
                    m(mns) = m(mns) + "SS:" + CStr(ptr)
                Else
                    m(mns) = "ERRError: Instrucción de sintáxis"
                End If
            End If
        End If
    Next i
    mnemotecnicos = m()
End Function

Espero que te resulte útil, que comprendas la técnica y desde luego que sepas perdonar los posibles errores de bulto, ya que lo he escrito 'al vuelo'.
__________________
Un cordial saludo
-Acalanto-

Madrid - España

Visual Basic
Videos Programacion
Foro Programacion
Tutoriales Programacion
Responder Con Cita