domingo, 29 de mayo de 2011

LeJOS y Eclipse

Compilar Lejos Con Eclipse

jueves, 12 de mayo de 2011

Como unir varios archivos de felx y bison en un mismo proyecto

Supongamos que en un proyecto necesitan analizar varios archivos uno tiene extensión .conf, que tiene la estructura de su tabla de símbolos, otro tiene extensión .sql que trae instrucciones para insertar datos y varios archivos  con extensión .dbf que tienen los datos ya insertados.  Y todos estos archivos deben de ser analizados con flex y bison.

Si ya han creado todos sus scanners y parsers, uno para el archivo con extensión  .conf, uno para el .sql, otro para los .dbf, ahora como llamarlos desde la aplicación?  Si todos los archivos generados  los tenemos con el nombre parser y si los agregan  a su proyecto les darán  errores.  Tienen  que hacer varias cosas antes de integrar más de un archivos felx y bison en un mismo proyecto, para eso sigan los siguientes pasos:

1)      Es mejor tener todos los analizadores en carpetas diferentes, es decir creas una carpeta conf y en ella guardar los  archivos .l y .y.  para analizar el .conf.   En otra carpeta, por ejemplo sql, guardas otros archivos .l y .y para analizar los .sql.   Esto en realidad no es necesario, solo es para tener una estructura ordenada de nuestro proyecto.

2)      Van a nombrar a  cada archivo .l y .y diferentes. por ejemplo para analizar el .conf pueden llamarlos lexico1.l y sintactico1.y y para el .sql poden llamarlo lexico2.l y sintactico2.y.  Esto es un ejemplo, poden llamarlos como ustedes quieran, pero tomen en cuenta que son nombres diferentes.

3)      En  sus archivos .l y .y existen funciones como yylval, yytext, yyparse, etc.  deben de cambiarle el "yy" a cada uno de ellos, por ejemplo yy1lval, yy1text, yy1parser, etc. esto para que no exista conflicto luego de juntar los dos analizadores. 

4)      Si usan una variable por ejemplo linea o archivo en su lexico1.l o sintactico1.y , y usan estas mismas variables en los archivos lexico2 y sintactico2, deben de cambiarlo, también por conflictos de que existen 2 variables declaradas en diferentes archivos entonces deben de llamarlos de diferente forma, por ejemplo linea1 y archivo1 en su primer analizador y linea2 y archivo2 en el otro.  (Nota: Existe conflicto solo cuando usan extern para hacer referencia a una variable que está en otro archivo).

5)      Ahora para compilar cada uno de estos archivos lo haces con los mismos comandos, pero las salidas van a nombrarlas de diferente manera y agregar el parámetro –P y –p en flex y bison respectivamente.

Para el .conf

                            > flex -P yy1 --header-file=scanner1.h -o scanner1.cpp lexico1.l
                             > bison -p yy1 – o parser1.cpp --defines=parser1.h sintactico1.y  

Para  el .sql


                           > flex -P yy2 --header-file=scanner2.h -o scanner2.cpp lexico2.l
                             > bison -p yy2 – o parser2.cpp --defines=parser2.h sintactico2.y  

Por  último, cuando quieran  usar los diferentes parser lo haces de la siguiente forma

            Para el .conf


                         yy1in=fopen( "entrada.conf","rt");
                         if (!yyin)
                            cout<<"error al abrir"<<endl;

                        yy1parse();

             Para el .sql

                      
          yy2in=fopen( "entrada.sql","rt");
                         if (!yy2in)
                            cout<<"error al abrir"<<endl;

                        yy2parse();


Nota:  En resumen, al compilar usan los parámetros -P yy1 en flex y -p yy1 en bison, esto hace que todas las funciones como yylval, yytext, yyparser, etc, cambie el "yy" por el "yy1" que esta en comando para compilar, entonces al generar los archivos las funciones se llamen yy1lval, yy1text, yy1parser.  Por eso es que cambiamos en el paso tres el nombre de las funciones que inician con yy en los archivos lexico.l y sintactico.y.  Y de esta forma evitan que se dupliquen las funciones y que exista un conflicto y les de error  en su proyecto.

lunes, 9 de mayo de 2011

Ejemplo Programa con LeJOS para el Lego NXT Mindstorms






Realizaremos un programa muy sencillo para familiarizarnos con java y el robot de lego, primero lo que necesitamos es “Lejos” para poder compilar nuestro programa en lenguaje java y poder subírselo al robot.

Ya que lo descargaron, ejecútenlo e instalen el programa, son unos pocos pasos y muy fáciles de instalar.

Nuestro primer ejemplo será muy sencillo, usaremos los sensores ultrasónico, táctil y de sonido y los motores. El robot empezará a caminar, si está en marcha y hacemos un ruido como un silbido o una palmada el robot se detiene, en caso contrario si el robot esta en reposo y hacemos un ruido el robot empezara a moverse.  Si el robot se acerca a un objeto, se detendrá y si presionamos el sensor táctil entonces girara.  El código para esto es el siguiente:


  1. import lejos.nxt.*;
  2. public class Practica1 {
  3. public static void main(String[] args) throws Exception {
  4. LCD.drawString("Iniciando",1,3);
  5. //Instanciamos los puertos para casa sensor del lego
  6. UltrasonicSensor sonic = new UltrasonicSensor(SensorPort.S1);
  7. TouchSensor touch = new TouchSensor(SensorPort.S2);
  8. SoundSensor sound = new SoundSensor(SensorPort.S3);
  9. // Se repite hasta que precionemos el boton escape
  10. while (!Button.ESCAPE.isPressed()) {
  11. //Sonido
  12. if (sound.readValue()>86){
  13. if (Motor.A.isMoving()){
  14. Motor.B.stop();
  15. Motor.A.stop();
  16. }
  17. else{
  18. Motor.A.forward();
  19. Motor.B.forward();
  20. }
  21. }
  22. //Distancia
  23. LCD.drawString(" "+sonic.getDistance()+" ",0,3);
  24. LCD.clear();
  25. if (sonic.getDistance()<21&&Motor.A.isMoving()&&
  26. Motor.B.isMoving())
  27. {
  28. Motor.A.stop();
  29. Motor.B.stop();
  30. }
  31. //Tacto
  32. if(touch.isPressed())
  33. {
  34. Motor.B.stop();
  35. Motor.A.rotate(800);
  36. }
  37. try {Thread.sleep(80);} catch (Exception e) {}
  38. }
  39. }
  40. }






El archivo lo guardamos con el nombre Practica1.java.  Como pueden ver es un código muy fácil de entender, para compilar abran una consola y deberán de usar el siguiente comando

nxjc Practica1.java

Para subirlo al robot usan el comando

nxj Practica1

Existen mas funciones para poder mover el motor pueden ver ejemplos y más explicaciones sobre estas funciones desde su página oficial,  Pronto estaré haciendo otros ejemplos mucho mas complejos.

En el siguiente link esta el video de como actúa el robot al ejecutar el programa anterior.