
Caracteristicas del lexer Slex
(Simusol lex)

Que es un lexer???
==================

Es un program que divide una secuencia de caracteres en tokens. En este caso la división se produce comparando la secuencia con un conjunto de expresiones regulares y eligiendo para definir el proximo token el que mas caracteres captura de la secuencia.

Existen varios lexers en el mundo del software libre por ejemplo el "lex" y el "flex", version mejorada del "lex" creado por la FSF. Slex incorpora algunas carácterísticas extras requeridas en nuestros proyectos, características que se pueden ver mas adelante. Los lexer trabajando junto con los parsers (intérpretes gramáticales) se usan por ejemplo para interpretar o compilar programas en codigo fuente y traducirlos al lenguaje de cada  computadora según su modelo.

Cada token tiene un tipo dado por la expresion regular que lo "capturo".

Basicamente un lexer divide un texto en, por ejemplo, palabras, números, instrucciones, etc.

Muchas veces un lexer es usado por un parser, que analiza la lista de tokens (segun su tipo) e identifica "las frases" de acuerdo a una gramatica dada. En nuestro caso se puede usar el programa bison si se requiere analizar la secuencia de tokens  en el marco de una gramática.

Que es una  expresion regular?
==============================

Es una cadena de caracteres que es utilizada para describir o encontrar patrones dentro de otras cadenas, contra las cuales se aplican.

Por ejemplo la expresion "^\d+", encuenta uno o más digitos, a partir del comienzo de una cadena. Usa  "^", llamado ancla inicial, para indicar que busca a partir del comienzo de la cadena. usa "\d" para indicar cualquiera de los caracteres 0 1 2 3 4 5 6 7 8 9, y el caracter "+" mas para indicar uno o mas.

De cada una de las siguientes cadenas:
 "876" es correctamente capturada al 100% por la expresion regular dada.

 "123pepe", tambien es correctamente capturada, pero
 solo lo hace en  los primeros 3 caracteres.

 "pepe123", es rechazada porque no hay un numero al comienzo.


"12,45" solo encuentra 12, ya que no especificamos como caracter válido a ",".

Es decir que la informacion encontrada al estudiar una secuencia de caracteres
con una expresion regular es si cumple o no, y que caracteres coinciden con el patron.

Se podria resumir lo anterior en
que toda expresion regular captura ciertos caracteres
de una secuencia dada  y que si captura 0 caracteres rechaza a la misma.


El Pcre2 tal como es usado por slex permite ademas ante una cadena dada saber
si la cadena podria seguir cumpliendo o dejar  de cumplir de ampliarse 

Por ejemplo

"123" cumple y de ampliarse podria seguir cumpliendo.

Una expresion regular como "\(\d+\)", donde los parentesis con la barra que los precede inican los respectivos caracteres parentesis.

No verifica la cadena

"(123"

Pero podria eventualmente verificarla si crece, por ejemplo,llegando a:

"(123456)" o no si llega a "(1233p"


En ambo casos nuestro lexer espera leer mas el archivo antes de evaluar definirse por cada expresion regular incorporada.

Siempre toma la primera expresion regular definida de entre las que "extraigan"
la mayor cantidad de caracteres de la secuencia.

Hablo de extraer porque se lee, por ejemplo el comienzo de
un archivo hacia una cadena.  Se encuentra un token, se "extrae" imprimiendolo y comunicandolo a otros programas, y se elimina ese token de la cadena, incorporando más caracteres del archivo.

Al encontrar un token se pueden ejecutar acciones, por ejemplo un token puede ser un comando (\include(otro.txt)) para abrir otro archivo (otro.txt) y seguir leyendo del mismo, al terminar ese otro archivo continuara con el primero.

Si ninguna expresion regular aplica a una cadena en algun momento se termina de procesar avisando de la situacion. Es como que una persona empiece a hablar en otro lenguaje que no entendemos y dejamos de escucharla.




Caracteristicas particulares de Slex
====================================


0) Las funciones de usuario para las regexps reciben informacion
sobre las substrings detectadas por las regexp.
MOTIVACION BASE PARA DESARROLLAR Slex, en el marco del proyecto Simusol/Ututo.

Las substrings son porciones de una expresion regular rodeadas de parentesis (sin las barras que mostramos antes).
Por ejemplo una expresion regular (\d+)a(\d+) tiene un numero natural
seguido de una letra a y seguido por otro numero. Notese que los parentesis al no llevar "\" no son pedidos en la cadena sino indica que identificaremos subcadenas.

Slex al detectar esa expresion regular identifica, no solo la cadena completa, sino un "vector" que incluye las subcadenas. En este caso, el vector tendra tres componentes: la cadena completa, el primer numero y el segundo numero.

La expreson regular \d+a\d encuentra las mismas cadenas que la anterior, 
pero no informa de cual es el primer número ni cual es el segundo. Si nos interesa saberlo deberemos encontrarlos de otra forma.


1) CONFIGURACION

No es compatible en su configuracion con lex, ni flex: No lee ese tipo de archivos. Si bien sería posible incorporar este formato, para los comportamientos compatibles.

Usa:

a) un archivo slex.slex (nombre que puede cambiarse) con otra configuracion
   donde se cargan las expresiones regulares a usar, que pueden estar asociadas a uno o mas estados
   
b)  un archivo userfuncs.c / (eventualmente userfuncs.h) donde se escriben las funciones disponibles, vinculadas a una o mas expresiones regulares. Estas funciones tienen argumentos con tipos predefinidos, siempre los mismos.


c) pueden tambien incorporarse estas configuracion en los programas con funciones, y tambien en las fuentes mediante comandos especiales.

2) REENTRANTE, y RECURSIVO, HILOS
   
    Pueden llamarse en forma simultanea y recursiva a varios lexers en un programa, cada lexer se asocia a un hilo, o thread, que es lo primero que se crea al usarlo.

   Cada thread puede abrir una o varias fuentes (sources/buffers) de donde obtener tokens. estas fuentes se mantienen abiertas, mientras no se agoten.

Hay 3 tipos de fuentes: strings, archivos, e hilos.
Con un hilo se puede hacer un lexer que lea tokens de otro lexer, por ejemplo con el primer lexer se abren archivos en forma recursiva (usando el comando \include() o el que se configure) y con el segundo se capturan tokens que involucran caracteres de varios archivos

Desde octubre de 2026 el estado de un lexer --sus reglas, acciones, hilos,
fuentes y tokens-- esta en un contexto (struct slex_ctx) que crea y libera
quien lo usa. Hay tantos lexers independientes como contextos, uno puede
usarse desde la accion de otro, y dos contextos distintos pueden usarse a la
vez desde dos hilos del sistema (los hilos de slex de este punto son flujos
dentro de un lexer, no hilos del sistema). Como se usa y que garantiza esta
en doc/API-CONTEXTO.md; la API de siempre, que sigue estando, en doc/API.md.


3) Es UTF-8 compatible. Si bien no todas las impresiones que hace  printf calculan correctamente la longuitud de las strings,se intentga usar solamente las que si. Slex tiene una funcion que calcula OK la longitud de las cadenas utf-8, en algunas de las tablas que imprime a pedido.  Se ha intenado no usar printf con formatos con este problema.


4) Puede trabajar con archivos que van creciendo a medida que se extraen
tokens.

Usa la libreria pcre2-8 y en particular la funcion de PARTIAL_MATCH, para saber si debe leer mas de una fuente antes de extraer un token.

5) Podria beneficiarse de un módulo perl que con varias regexps contruye una.

6) interactua con bison, cuando este se configura de las formas previstas por
Slex, como ser reentrante y con YYlex() argumentos especificos. 

7) No tiene ningún limite mas allá del espacio de memoria y disco de la computadora donde funciona. El limite de memoria es importante en cuanto al mayor token que pueda reconocer, dado que los archivos fuente puden crecer a medida que se los usa. Quedaria pendiente alguna funcion que avise si se achican, del corrimiento de la posicion ya leida.

Los tokens extraidos se almacenan por defecto, pero esto puede anularse.

8) No se ha hecho esfuerzo alguno en acelerar el funcionamiento, de hecho para ser compatible con algunos parametros de bison se entregan las posiciones en la linea, archivothread y objeto. Como se leen los archivos con bloques, no se sabe
donde hay fines de linea. Asi que se leen los tokens a estos efectos. Esto enlentece y puede ser deshabilitado.

Las expresiones regulares de pcre2 son complejas y sus algoritmos no son tan veloces ni lineales como las de los benemeritos programas de la FSF y otros.

9) Permite definir objetos en un thread, es decir que su entrada se divide en
objetos a requerimiento. Se sabe a que objeto pertenece cada token (asi como a que hilo).

10) Requiere un paquete mem_util con funciones que uso en otros programas

11) Se distribuye en fuentes que usan autoconf automake y libtool.
Se instala por defecto en /usr/src, a los efectos que que el que lo desea tenga facil cambiarlo y si cambia la version de su SO, pueda recompilarlo sin reinstalarlo de nuevo. Utiliza la filosofia de Summapack y antidistro.

12) La idea es que se pueda instalar en HOME, para que lo pueda usar quien no tenga derechos de supervisor.  Usa en tal caso ~/bin ~/share. ~/src
Los Makefiles de los ejemplos proveen Makefiles que usan dichas formas de instalacion.


13) ESTADO, a septiembre de 2026.

Slex es la base de los lexers de los programas de este arbol: Simulparser,
el parser en Perl, se retira.

Lo que hay probado, y como se comprueba:

 - tests/run_tests.sh: 38 pruebas de la API, funcion por funcion, mas la
   regresion de los ejemplos 07, 08 y 10. Todas pasan.
 - examples/09 tokeniza los 246 archivos .d y .ds del corpus
   corpus, todos.
 - examples/11 tokeniza los netlists de SPICE de siru/corpus/spice y su
   cir2ds los traduce a .ds: rc-tran corre en siru y coincide con
   ngspice y con la solucion analitica.
 - d2datdinc los lleva al dato de Simul (.dat) y da EXACTAMENTE el mismo
   JSON que Simulparser: sobre el corpus, 191 iguales y 0 distintos. Los 55
   restantes son los que al de Perl tampoco le salen, por includes que en el
   corpus no existen. Se comprueba con
   d2datdinc/pruebas/contra-ds2dat, que conviene seguir corriendo: comparar
   dos implementaciones independientes sobre archivos reales atrapa mas que
   cualquier prueba escrita a mano.

Esta empaquetado: libslex0 y libslex-dev, con slex.pc que pide PCRE2 y
mem_util por Requires. Se instala con  sudo ../instalar slex .

Los casos de prueba donde falle siguen siendo bienvenidos; es la forma en
que crecio hasta aca.



-------------------------------------------------------





Hola

sudo apt-get install autogen autoconf libtool automake  autoconf-archive pkg-config



autoreconf --install


#configure.ac: installing './install-sh'
#configure.ac: installing './missing'
#configure.ac: installing './compile'
#src/Makefile.am: installing './depcomp'


#Running autoreconf is only needed 
#initially when the GNU Build System does not exist. 
#When you later change some instructions in a Makefile.am 
#or configure.ac, the relevant part of the build 
#system will be regenerated automatically when you execute make.

./configure

make

make distcheck

sudo make install
sudo ldconfig


define findfirstSB
$(shell $(shellpath) if test -s ./$1 ; then \
                   echo .;\
                 elif test -s ~/$1 ; then \
                    echo ~;\
                 elif test -s /usr/local/$1 ; then \
                   echo /usr/local;\
                 elif  test -s /usr/$1 ; then \
                    echo /usr;\
                 fi;)
endef
PREFIXMLIB=$(call findfirstSB,share/summapack/data/makefile.lib)

ifneq ("$(wildcard $(PREFIXMLIB)/share/summapack/data/makefile.lib)","")
  include $(PREFIXMLIB)/share/summapack/data/makefile.lib
endif
$(info MAKELIB: ${PREFIXMLIB})

usar svnversion de makefile.lib

sacado de src/makefeil
#hello_LDADD = libgettext.la