Documente Academic
Documente Profesional
Documente Cultură
de la Costa Grande
QBASIC
PRESENTA
MATERIA
LENGUAJES Y AUTOMATAS II
NDICE DE CONTENIDO
NDICE DE CONTENIDO
ANTESCEDENTES
1.1
QBASIC
1.2
JavaCC
INTRODUCCION
CONTENIDO
3.1
Analisis lxico
3.2
Analisis sintctico
3.3
Analisis semntico
ANEXOS
4.1
Analizabasic.java
4.2
basicFrame.java
4.3
Tokenasignaciones.java
4.4
Lenguaje_QBASIC.jj
REFERENCIAS
1 ANTECEDENTES
1.1 QBASIC
QBasic fue creado con el objeto de reemplazar al BASIC y GW-BASIC alrededor de
1985 como un lenguaje de programacin para el usuario final.
Es un descendiente del lenguaje de programacin BASIC que Microsoft Corporation
desarroll para su uso con el sistema operativo MS-DOS.
Microsoft sac a la venta QuickBasic como un paquete de desarrollo comercial, lo
incluy como opcional en los discos de instalacin de Windows 95 y Windows 98,
incluido en el paquete olddos.exe, hasta Windows 2000 donde se dejo de distribuir pero
dejo la compatibilidad.
En su tiempo, QBasic provey de un IDE avanzado, incluyendo un depurador con
caractersticas tales como evaluacin de expresiones y modificacin del cdigo al vuelo.
Puede correr bajo casi todas las versiones del DOS y de Windows, o con
DOSBox/DOSEMU, en Linux y FreeBSD, su extensin es .BAS.
INSTRUCCIONES BSICAS
Las instrucciones bsicas incluyen palabras reservadas del lenguaje QBASIC. Lo que se
conoce comnmente como comandos. Independientemente de que los escribamos con
maysculas o minsculas, cuando QBASIC detecte que hemos escrito una palabra
asociada a un comando, automticamente lo escribir con letras maysculas.
REM
Sirve para introducir comentarios en el programa. Al ejecutar el programa, QBASIC no
tiene en cuenta las lneas que comienzan con el comando REM.
CLS
Borra la informacin que aparece en la pantalla. Conviene utilizar este comando al
comienzo del programa para eliminar la informacin de programas anteriores.
PRINT
Se utiliza para escribir datos en la pantalla. Con esta instruccin se pueden escribir
constantes o variables en pantalla, as como cadenas formadas por estas.
INPUT
Se utiliza para ingresar datos, y almacenarlos en una variable.
CONSTANTES Y VARIABLES
CONSTANTE:
Una constante es un dato cuyo valor no cambia durante la ejecucin del programa.
Puede ser:
Numrica: Una cifra, un valor numrico.
Alfanumrica: Cadena de caracteres encerrados entre comillas.
VARIABLE:
Una variable es una porcin de la memoria del ordenador que reservamos para
almacenar un valor. Para identificar esa zona de la memoria el cdigo del programa le
asigna un nombre. Al igual que las constantes las variables pueden ser numricas y
alfanumricas.
TIPOS DE DATOS
NOMBRE
STRING
SUFIJO
INTEGER
LONG
%
&
SINGLE
DOUBLE
DESCRIPCIN
Texto con
cualquier carcter
Nmeros enteros
Nmeros enteros
ms grandes
Nmeros con
decimales
Nmeros con ms
decimales
MNIMO Y MXIMO
0 a 32767
caracteres
-32768 a 32767
2.147.483.647 a
-2.147.483.648
2,8x1045 a -2,8x1045
4,9x10324 a
-4,9x10324
1.2 JavaCC
JavaCC es el principal metacompilador en JavaCC, tanto por sus posibilidades, como
por su mbito de difusin. Facilita la construccin de analizadores lxicos y sintcticos
por el mtodo de las funciones recursivas. De esta manera, los analizadores generados
utilizan la tcnica descendente a la hora de obtener el rbol sintctico.
Integra en una misma herramienta al analizador lexicogrfico y al sintctico, y el cdigo
que genera es independiente de cualquier biblioteca externa.
Algunas de sus caractersticas son:
2 INTRODUCCION
A continuacin se mostraran los pasos para la realizacin de un compilador utilizando la
herramienta de Java, JavaCC.
El compilador fue hecho orientado al lenguaje de programacin QBASIC.
Y de acuerdo al anlisis lxico, sintctico y semntico que consisten en lo siguiente:
3 CONTENIDO
3.1 ANLISIS LXICO
Es la primera fase de un compilador consistente en un programa que recibe como
entrada el cdigo fuente de otro programa y produce una salida compuesta de tokens o
smbolos.
El anlisis lxico es el encargado de verificar que el usuario ha escrito bien las palabras
reservadas del lenguaje. Se define la declaracin de tokens en el archivo jj (javacc) para
que ah se almacenen las palabras reservadas del lenguaje que en este caso el lenguaje a
definir es QBASIC.
A continuacin un pequeo fragmento de cdigo donde se declaran tokens para las
palabras reservadas del lenguaje.
TOKEN: // Comillas
{
<Comillas : "\"">//12
| <Espacio : " ">//13
}
TOKEN :
{
<Pal_res_PRINT : ("PRINT" | "PRINT ")>//14
| <Pal_res_INPUT : ("INPUT" | "INPUT ")>//15
| <Pal_res_CLS : "CLS">//16
| <pal_res_REM : "REM">//17
| <pal_res_Com : "'">//18
| <pal_res_Pan : "SCREEN" | "SCREEN ">//19
| <pal_res_Col : "COLOR" | "COLOR ">//20
}
String lexico() :
{
String resultado;
}
{
( <Pal_res_PRINT> { resultado = new String(token.image); tipo = new
String("Etiqueta PRINT");}
.
.
.
.
}
Anexos: Lenguaje_QBASIC.jj
4 ANEXOS
Para mejor comprensin del compilador a continuacin se mostraran los cuatro archivos
utilizados para la realizacin del mismo, los cuales consisten en tres archivos .java y
un archivo .jj
4.1 Analizabasic.java
Programa principal del cual se mandan a llamar todos los dems archivos.
public class Analizabasic {
public static void main(String[] args){
basicFrame frame = new basicFrame();
frame.setVisible(true);
}
}
4.2 basicFrame.java
Contiene el cdigo orientado a objetos del compilador, hace uso de las funciones del
archivo JavaCC.
/*
Descripcion: Archivo en el que se crea el frame y los elementos principales del mismo,
como el menu, que permite mandar llamar el procedimiento que compila el codigo
antes escrito.
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.util.*;
import javax.swing.text.*;
import java.util.HashMap;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.*;
public class basicFrame extends JFrame{
//Se crean los componentes a utilizar
public JTextPane txtCodigo = new JTextPane();
public JTextPane txtTokens = new JTextPane();
public JTextArea txtError = new JTextArea();
private JScrollPane jScrollPane1 = null;
private JScrollPane jScrollPane2 = null;
private JScrollPane jScrollPane3 = null;
private JPanel pnlCentral = new JPanel();
private BorderLayout layoutMain = new BorderLayout();
private BorderLayout borderLayout1 = new BorderLayout();
//Estos permiten aadir estilos al texto escrito
private StyledDocument EstiloDocumento = null, EstiloDocumento2 = null;
private MutableAttributeSet AtributosError = null, AtributosNormal = null;
//Variables globales
private File file;
private FileInputStream fin;
Boolean salir;
int contador = 0;
StringTokenizer Arreglo_de_tokens;
//Constructor
public basicFrame(){
//Se establece el estilo a usar c uando ocurre error
txtCodigo.setFont(new Font("Courier New", 0, 14));
EstiloDocumento = txtCodigo.getStyledDocument();
AtributosError = new SimpleAttributeSet();
StyleConstants.setBackground(AtributosError, Color.YELLOW);
txtError.setFont(new Font("Courier New", 0, 14));
txtError.setBackground(new Color(235, 235, 235));
//Se establece el estilo a usar cuando se esta corrigiendo un error
EstiloDocumento2 = txtCodigo.getStyledDocument();
AtributosNormal = new SimpleAttributeSet();
StyleConstants.setBackground(AtributosNormal, Color.WHITE);
//Componente a utilizar
menuAcercaDe.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e){
basicFrame.this.AcercaDe();
}
}
);
/*se aade un key listener para recuperar el estilo normal de txtCodigo*/
txtCodigo.addKeyListener(new KeyAdapter(){
public void keyTyped(KeyEvent e){
char caracter = e.getKeyChar();
RecuperaEstilo();
}
});
//se aaden las opciones disponibles al menu
menuArchivo.add(menuArchivoAbrir);
menuArchivo.add(menuArchivoGuardar);
menuArchivo.add(menuArchivoGuardarC);
menuArchivo.add(menuArchivoSalir);
menuEditar.add(menuCopiar);
menuEditar.add(menuCortar);
menuEditar.add(menuPegar);
menuAnalizar.add(menuAnalizarCompilar);
menuAyuda.add(menuAcercaDe);
menuBar.add(menuArchivo);
menuBar.add(menuEditar);
menuBar.add(menuAnalizar);
menuBar.add(menuAyuda);
//proporccionar un medio para acomodar los componentes
this.getContentPane().setLayout(layoutMain);
pnlCentral.setLayout(borderLayout1);
//se crea instancias y se aaden componentes al panel principal
jScrollPane1 = new JScrollPane(txtCodigo,JScrollPane.VERTICAL_SCROLLBA
R_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
jScrollPane2 = new JScrollPane(txtTokens,JScrollPane.VERTICAL_SCROLLBA
R_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
jScrollPane3 = new JScrollPane(txtError,JScrollPane.VERTICAL_SCROLLBA
R_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
pnlCentral.add(jScrollPane1, BorderLayout.CENTER);
//SE aaden componentes al frame
this.getContentPane().add(pnlCentral, BorderLayout.CENTER);
this.getContentPane().add(jScrollPane2, BorderLayout.EAST);
this.getContentPane().add(jScrollPane3, BorderLayout.SOUTH);
setTitle("QBASIC");
setJMenuBar(menuBar);
txtCodigo.setText( contenido );
}catch( Exception exp){}
}
}
public String getArchivo( String ruta ){
FileReader fr = null;
BufferedReader br = null;
//Cadena de texto donde se guardara el contenido del archivo
String contenido = "";
try{
//ruta puede ser de tipo String o tipo File
fr = new FileReader( ruta );
br = new BufferedReader( fr );
String linea;
//Obtenemos el contenido del archivo linea por linea
while( ( linea = br.readLine() ) != null ){
contenido += linea + "\n";
}
}catch( Exception e ){ }
finally
{
try{
br.close();
}catch( Exception ex ){}
}
return contenido;
}
public void Guardar(){
catch(IOException io)
{
txtCodigo.setText("Error al abrir el fichero");
return;
}
//Escribimos
try
{
fw.write(txtCodigo.getText());
txtTokens.setText("Fichero guardado");
}
catch(IOException io)
{
txtError.setText("Error al escribir");
}
//cerramos el fichero
try
{
fw.close();
}
catch(IOException io)
{
txtError.setText("Error al cerrar el archivo");
}
}
}
..
. ...
try {
String
resultado
(String)clipData.getTransferData(DataFlavor.stringFlavor);
String txt = txtCodigo.getText();
txtCodigo.setText(txt+resultado);
} catch (Exception ex) {
System.err.println("Not String flavor");
}
}
}
// Procedimiento para cerrar la aplicacin
protected void Salir() {
// Salir de la aplicacin
System.exit(0);
}
/* Procedimiento que encarga de mandar llamar los analizadores lxico y
* sintctico */
protected void AnalisisCompilar() {
// Se crean declaran lo respectivo a los archivos a utilizar
FileInputStream archivo_temp, archivo_temp2;
FileOutputStream fout;
PrintWriter pw;
// Se declaran las variables a utilziar
String archivo = Long.toString(System.currentTimeMillis()) + ".txt";
String respTokens = "";
String []respTokens2 = txtCodigo.getText().split("\n");
salir = false;
try {
fout = new FileOutputStream(archivo);
pw = new PrintWriter(fout);
pw.print(txtCodigo.getText());
pw.close();
fout.close();
} catch (IOException ioe) {
txtError.setText("Error de escritura en el archivo");
}
/* Procedimiento que manda llamar a los analizadores lxico y
* sintctico */
try {
BASIC comp;
archivo_temp = new FileInputStream(archivo);
comp = new BASIC(archivo_temp);
comp.setEditor(this);
Arreglo_de_tokens
=
new
StringTokenizer(txtCodigo.getText());
String
tokens[]
String[Arreglo_de_tokens.countTokens()];
txtTokens.setText("");
txtError.setText("");
new
try {
comp.lenguaje();
} catch(ParseException pe){
comp.addError("Error en el proceso de Compilacion - " +
pe.toString(), comp.token);
salir = true;
} catch(Error e){
comp.addError("Error en el proceso de Compilacion - " +
e.toString(), comp.token);
salir = true;
}
archivo_temp.close();
if (salir == false){
archivo_temp2 = new FileInputStream(archivo);
// Se manda dicho archivo al constructor en HTML
comp = new BASIC(archivo_temp2);
// Se establece el editor por defecto
comp.setEditor(this);
// Se prueba escribir los tokens en el componente txtTokens
try{
do{// ciclo do while modificar , agregar un gaurda como
if(respTokens == "")
respTokens = comp.lexico() + " - " + comp.tipo;
else
respTokens = respTokens + "\n" + comp.lexico()
+ " - " + comp.tipo;
.
}
while(comp.resultado1=="1");//System.out.println(comp.lexic
o());
txtTokens.setText(respTokens);
} catch(ParseException pe){
comp.addError("Error en el proceso de Compilacion - " +
pe.toString(), comp.token);
}
archivo_temp2.close();
}
File file = new File(archivo);
if(!file.delete())
comp.addError("No se pudo borrar archivo = " + archivo, null);
comp = null;
this.resize(750, 600);
txtTokens.resize(300, 650);
this.repaint();
txtError.resize(650, 200);
this.repaint();
this.resize(600, 400);
this.repaint();
}catch (IOException ioe){
txtError.setText("Error de apertura del archivo.");
}
}
//procedimiento acerca de..
protected void AcercaDe(){
System.out.println("Acerca de...");
JOptionPane.showMessageDialog(null, "Unidad 1 - practica . \n" + "Materia:
Lenguajes y Automatas II. \n");
}
}
4.3 Tokenasignaciones.java
En este archivo se hace la creacin de las tablas hash para llevar a cabo el anlisis
semntico.
import java.io.PrintStream;
import java.util.Hashtable;
import java.lang.String;
import java.util.ArrayList;
class TokenAsignaciones
{
//Variable para validar asignaciones a caracteres(ichr)
public static int segunda = 0;
//Tabla que almacenara los tokens declarados
private static Hashtable tabla = new Hashtable();
//Listas que guardaran los tipos compatibles de las variables
private static ArrayList<Integer> intComp = new ArrayList();
private static ArrayList<Integer> decComp = new ArrayList();
private static ArrayList<Integer> strComp = new ArrayList();
//variable
//tipoDato
public static void InsertarSimbolo(Token identificador, int tipo)
{
//En este metodo se agrega a la tabla de tokens el identificador que esta siendo
declarado junto con su tipo de dato
tabla.put(identificador.image, tipo);
}
public static void SetTables(){
intComp.add(23);
decComp.add(25);
strComp.add(26);
}
public static String checkAsing(Token TokenIzq, Token TokenAsig)
{
//variables en las cuales se almacenara el tipo de dato del identificador y de las
asignaciones (ejemplo: n1(tipoIdent1) = 2(tipoIdent2) + 3(tipoIdent2))
int tipoIdent1;
int tipoIdent2;
/* De la tabla obtenemos el tipo de dato del identificador asi como, si el token
enviado es diferente a algun tipo que no se declara como los numeros(48), los
decimales(50), caracteres(52) y cadenas(51) entonces tipoIdent1 = tipo_de_dato, ya
que TokenAsig es un dato*/
if(TokenIzq.kind != 23 && TokenIzq.kind != 25)
{
try
{
tipoIdent1 = (Integer)tabla.get(TokenIzq.image);
}
catch(Exception e)
{
//Si TokenIzq.image no se encuentra en la tabla en la cual se agregan los
.....
//tokens, el token no ha sido declarado, y se manda un error
return "Error: El identificador " + TokenIzq.image + " No ha sido declarado
\r\nLinea: " + TokenIzq.beginLine;
}
}
else
tipoIdent1 = 0;
if(TokenAsig.kind == 24)
{
/*Si el tipo de dato que se esta asignando, es algun identificador(kind == 49)
se obtiene su tipo de la tabla de tokens para poder hacer las comparaciones*/
try
{
tipoIdent2 = (Integer)tabla.get(TokenAsig.image);
}
catch(Exception e)
{
//si el identificador no existe manda el error
return "Error: El identificador " + TokenAsig.image + " No ha sido
declarado \r\nLinea: " + TokenIzq.beginLine;
}
}
//Si el dato es entero(48) o decimal(50) o caracter(51) o cadena(52)
//tipoIdent2 = tipo_del_dato
else if(TokenAsig.kind == 23 || TokenAsig.kind == 25 || TokenAsig.kind == 26)
tipoIdent2 = TokenAsig.kind;
else
tipoIdent2 = 0;
if(tipoIdent1 == 23) //Int
{
//Si la lista de enteros(intComp) contiene el valor de tipoIdent2, entonces es .
//compatible y se puede hacer la asignacion
if(intComp.contains(tipoIdent2))
return " ";
else //Si el tipo de dato no es compatible manda el error
return "Error: No se puede convertir " + TokenAsig.image + " a Entero
\r\nLinea: " + TokenIzq.beginLine;
}
else if(tipoIdent1 == 25) //double
{
if(decComp.contains(tipoIdent2))
return " ";
else
return "Error: No se puede convertir " + TokenAsig.image + " a Decimal
\r\nLinea: " + TokenIzq.beginLine;
} else if(tipoIdent1 == 26) //string
{
if(strComp.contains(tipoIdent2))
return " ";
else
return "Error: No se puede convertir " + TokenAsig.image + " a Cadena
\r\nLinea: " + TokenIzq.beginLine;
}
else
{
return "El Identificador " + TokenIzq.image + " no ha sido declarado" + "
Linea: " + TokenIzq.beginLine;
}
}
/*Metodo que verifica si un identificador ha sido declarado,
ej cuando se declaran las asignaciones: i++, i--)*/
public static String checkVariable(Token checkTok){
try
{
//Intenta obtener el token a verificar(checkTok) de la tabla de los tokens
int tipoIdent1 = (Integer)tabla.get(checkTok.image);
return " ";
}
catch(Exception e)
{
//Si no lo puede obtener, manda el error
return "Error: El identificador " + checkTok.image + " No ha sido declarado
\r\nLinea: " + checkTok.beginLine;
}
}
}
4.4 Lenguaje_QBASIC.jj
Archivo de JavaCC donde se crean los tokens para el anlisis del compilador:
options {
LOOKAHEAD = 1;
CHOICE_AMBIGUITY_CHECK = 2;
OTHER_AMBIGUITY_CHECK = 1;
STATIC = false; //Esta opcion es importante para integrar el analizador al editor
DEBUG_PARSER = false;
DEBUG_LOOKAHEAD = false;
DEBUG_TOKEN_MANAGER = false;
ERROR_REPORTING = true;
JAVA_UNICODE_ESCAPE = false;
UNICODE_INPUT = false;
IGNORE_CASE = true; // Esta opcion ignora la diferencia entre mayusculas y
//minusculas
USER_TOKEN_MANAGER = false;
USER_CHAR_STREAM = false;
BUILD_PARSER = true;
BUILD_TOKEN_MANAGER = true;
SANITY_CHECK = true;
FORCE_LA_CHECK = false;
}
PARSER_BEGIN(BASIC)
//AQUI SE PUEDEN IMPORTAR LOS PAQUETES QUE SEAN NECESARIOS
import java.io.FileInputStream;
import java.io.IOException;
import javax.swing.JEditorPane;
import javax.swing.JScrollPane;
import java.awt.Color;
public class BASIC {
public basicFrame editor = null; //Variable para referenciar al editor
public String tipo = "";
public String errores = "";
public void setEditor(basicFrame ed){
editor = ed;
}
tipo = new
tipo = new
tipo = new
tipo = new
tipo
new
tipo = new
tipo
new
tipo
new
tipo = new
v2 = token;
TokenAsignaciones.InsertarSimbolo(v1, v2.kind);
TokenAsignaciones.InsertarSimbolo(v2, v2.kind);
res = TokenAsignaciones.checkAsing(v1, v2);
if(res != " ")
{
System.out.println(res);
imp = true;
}
}
(LOOKAHEAD(2)OpAritmetico()
TiposAsignaciones()
{
v3 = token;
TokenAsignaciones.InsertarSimbolo(v3, v3.kind);
res = TokenAsignaciones.checkAsing(v1, v3);
if(res != " " && !imp)
{
System.out.println(res);
}
})*
)
}
void TiposAsignaciones() :
{}
{
<Number>
| <Identifier>
| <Cadena>
| <Decimal>
}
void OpAritmetico() :
{}
{
<MAS>
| <Resta>
| <Multi>
| <Divide>
| <Mod>
| <Potencia>
}
void limpiar() :
{}
{
<Pal_res_CLS>
}
void Mensaje() :
{}
{
<Pal_res_PRINT> ( <Cadena> | <Identifier>(<EOL>|<single>| <LONG>|
<DOUBLE>)?(( <Resta>|<Multi> | <Divide>| <Mod>
| <Potencia>)<Identifier>)?)
(
(<MAS>|<DELIMITADOR>)(<Espacio>)?<Identifier>(<EOL>|<Mod>|<single>|
<LONG>| <DOUBLE> )? )?
}
void IngresaDato() :
{}
{
<Pal_res_INPUT>(<Cadena>(<Coma>|<DELIMITADOR>))?(<Espacio>)?
<Identifier>(<EOL>|<Mod>|<single>| <LONG>| <DOUBLE> )?
}
void Comentarios() :
{}
{
(<pal_res_REM><Cadena>)
|(<pal_res_Com><Cadena>)
}
void Apariencia() :
{}
{
(<pal_res_Col><Number><Coma><Number>)
|(<pal_res_Pan><Number>)
}
5 REFERENCIAS
Java a Tope: Compiladores - Traductores y Compiladores con Lex/Yacc, JFlex/Cup y
JavaCC.
Autores: Sergio Galvez Rojas, Miguel Angel Mora Mata
Editorial :Universidad de Malaga
[1995-1997] etsimo WWW team
http://www6.uniovi.es/qbasic/qbasic1.html
Garca Merayo, Flix; Alcalde Lancharro, Eduardo (4 de 1998) (en Espaol).
Programacin bsica con Logo y QBasic : (gua prctica para estudiantes) (1 edicin).
McGraw-Hill / Interamericana de Espaa, S.A.. pp. 64.
Moldes Teo, Francisco Javier (9 de 1991) (en Espaol). QBasic (1 edicin). Anaya
Multimedia-Anaya Interactiva. pp. 272.