🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: es.comp.os.linux.programacion
7 messages
7 total messages Started by F Sat, 08 Oct 2005 10:29
expresion regular para comprobar Expresion matematicas
#1505
Author: F
Date: Sat, 08 Oct 2005 10:29
27 lines
1647 bytes
Hola, necesito comprobar que una expresion matematica este bien formada.

por ejemplo 1+2+3 esta bien 1*/3 no

Para ello, cuando no hay parentesis es bastante facil


$num="-?\\d*\\.?\\d+";
$op='\*\/\%\+\-';

$_="12+1 * 4/2";
if (
/^$num\s*([$op]\s*$num\s*)*$/
){
  print "Esta bien\n";
}

Pero cuando hay parentesis, lo unico que se ocurre, es hacer una funcion 
recursiva, que compruebe  cada vez que hay un parentesis, lo de dentro esta 
bien formado.

Resumiendo, no se hacer que la expresion regular permita parentesis dentro 
de parentesis, y demas, me imagino que esto es posible

Alguna idea?

Gracias
Re: expresion regular para comprobar Expresion matematicas
#1506
Author: Claudio
Date: Sat, 08 Oct 2005 13:14
13 lines
1675 bytes
On 2005-10-08, F <esnewsfQuItAeStO@EsToCaMbIeNyahoo.es> wrote:
> Hola, necesito comprobar que una expresion matematica este bien formada.
[...]
> Alguna idea?

La primera idea r�pida es que t� necesitas lex � flex.  � No te vale eso
? No s� si lo conoces. Se basa en expresiones regulares, permite al
recursividad, posibilita aplicar una funci�n inform�tica a cada
expresi�n calculada (que puede ser tan simple como un printf o tan
complejo como se quiera)...

Un saludo.
--claudio--
Re: expresion regular para comprobar Expresion matematicas
#1507
Author: iarenaza
Date: Sat, 08 Oct 2005 23:26
29 lines
2308 bytes
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

>>>>> "Claudio" == Claudio  <claudio@example.org> writes:

    Claudio> La primera idea r�pida es que t� necesitas lex � flex.  �
    Claudio> No te vale eso ? No s� si lo conoces. Se basa en
    Claudio> expresiones regulares, permite al recursividad,

En realidad con lex/flex no le bastara. Necesita un analizador
sintactico (parser), solo con uno lexico no le bastara (a menos que se
lo construya el mismo con ayuda de lex/flex, lo cual es mas
trabajoso). yacc/bison son las opciones tradicionales en este area.

Dicho de otro modo, solo con expresiones regulares no es posible.

Saludos. I�aki.

- -- 
  Get PGP/GPG Keys at  http://www.escomposlinux.org/iarenaza/pgpkey.php
  I use free software / Yo uso software libre
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Processed by Mailcrypt 3.5.8 <http://mailcrypt.sourceforge.net/>

iD8DBQFDSFWmZXLnGT1HLgcRAs7rAJwMKzz2i3/88CZaafKPMxtG/Gm9TQCfY73A
iOTLZrLTyKTekfBMs8UUjkg=
=iAc1
-----END PGP SIGNATURE-----
Re: expresion regular para comprobar Expresion matematicas
#1508
Author: Javier M Mora (jamarier)
Date: Sun, 09 Oct 2005 11:29
37 lines
2492 bytes
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

F escribi�:
On Sat, 08 Oct 2005 10:29:28 GMT, F wrote:
> Hola, necesito comprobar que una expresion matematica este bien formada.
>
> por ejemplo 1+2+3 esta bien 1*/3 no
>
> Para ello, cuando no hay parentesis es bastante facil [...]

Como te han comentado ya, eso m�s que un asunto de expresi�n regular, es
m�s un tema relacionado con Analizadores de sintaxis. Como veo que usas
Perl, Te recomiendo que pases de lex,flex,bison y otros y uses uno de
los modulos disponibles en Perl ;-)

Concretamente hay un m�dulo llamado Parser:RecDescent que hace lo que
quieres. En el defines una gram�tica (las reglas que quieres que cumpla
tu expresi�n y el m�dulo se encarga de determinar si tu expresi�n cumple
y cuales son los datos que quieres extraer posteriormente.

Hay un tutorial en http://www.perl.com/pub/a/2001/06/13/recdecent.html
que te puede dar una idea de si es justamente lo que necesitas o no.

atte. javier m mora

- -- 
	Javier Maria Mora Merchan
	(GPGP) Key ID: 0x794F3D83

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iD8DBQFDSP8upRHCj3lPPYMRAsH6AJ4vICAUlh0lK30w08utp3Q3++2r0QCeKgxb
cdWqnecxUwIhsfXzZj15Nlo=
=ZbtF
-----END PGP SIGNATURE-----
Re: expresion regular para comprobar Expresion matematicas
#1509
Author: Han Solo
Date: Sun, 09 Oct 2005 21:01
47 lines
2634 bytes
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

"Javier M Mora (jamarier)" <javiermm@bigNOfootSPAM.com> writes:

> F escribi�:
> On Sat, 08 Oct 2005 10:29:28 GMT, F wrote:
>> Hola, necesito comprobar que una expresion matematica este bien formada.
>>
>> por ejemplo 1+2+3 esta bien 1*/3 no
>>
>> Para ello, cuando no hay parentesis es bastante facil [...]
>
> Como te han comentado ya, eso m�s que un asunto de expresi�n regular, es
> m�s un tema relacionado con Analizadores de sintaxis. Como veo que usas
> Perl, Te recomiendo que pases de lex,flex,bison y otros y uses uno de
> los modulos disponibles en Perl ;-)
>
> Concretamente hay un m�dulo llamado Parser:RecDescent que hace lo que
> quieres. En el defines una gram�tica (las reglas que quieres que cumpla
> tu expresi�n y el m�dulo se encarga de determinar si tu expresi�n cumple
> y cuales son los datos que quieres extraer posteriormente.

Ese m�dulo no lo conozco, pero para perl yo usaba en tiempos algo
llamado perl-byacc, que era una implementaci�n de yacc para perl. La
parte del flex me la hac�a a mano, no es tan complicada (al menos para
lo que yo hac�a).

Un Saludo
- -- 
Han Solo
The Rebel Alliance

Emacs is not on every system

So what? [...] Do you tell your administrative people to stick with
notepad.exe? Do you tell your fat kids they can only have the crummy
games that come with their video games or plain dress that comes with
Barbie?
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Processed by Mailcrypt 3.5.8 <http://mailcrypt.sourceforge.net/>

iD8DBQFDSYUP4FjpJaPEp20RAmAfAKC5Y24ztl0ea9m+avstc6qfkr6lnQCfZ+DB
UlUBEPo7Hm8VQfnrMS5nKIM=
=sqYt
-----END PGP SIGNATURE-----
Re: expresion regular para comprobar Expresion matematicas
#1510
Author: Javier M Mora (jamarier)
Date: Mon, 10 Oct 2005 05:24
40 lines
2593 bytes
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Han Solo escribi�:
> Javier M Mora escribi�:
>> Concretamente hay un m�dulo llamado Parser:RecDescent que hace lo que
>> quieres. En el defines una gram�tica (las reglas que quieres que cumpla
>> tu expresi�n y el m�dulo se encarga de determinar si tu expresi�n cumple
>> y cuales son los datos que quieres extraer posteriormente.
>
> Ese m�dulo no lo conozco, pero para perl yo usaba en tiempos algo
> llamado perl-byacc, que era una implementaci�n de yacc para perl. La
> parte del flex me la hac�a a mano, no es tan complicada (al menos para
> lo que yo hac�a).
>

En CPAN hay toda una serie de m�dulos para construir parsers, unos m�s
espec�ficos que otros. Pero ahora el que es �chachi� es este RecDescent
que est� hecho por Damian Conway (uno de las cabezas pensantes de Perl)
y que tiene, al parecer, las funciones de yacc y flex incorporadas. 

Quiero decir que �ltimamente s�lo oigo hablar de el cuando se habla de
an�lisis de gram�tica.

La penalizaci�n es que no es lo m�s r�pido que hay.

atte. javier m mora


- -- 
	Javier Maria Mora Merchan
	(GPGP) Key ID: 0x794F3D83

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iD8DBQFDSfshpRHCj3lPPYMRAgNvAKCy0SeefaPxR2DoUuB5Igc7B/FD6ACffG3n
KhbRBo97sT5tTXgSSHKFw/w=
=1pPr
-----END PGP SIGNATURE-----
Re: expresion regular para comprobar Expresion matematicas
#1511
Author: F
Date: Mon, 10 Oct 2005 08:43
109 lines
3713 bytes

"F" <esnewsfQuItAeStO@EsToCaMbIeNyahoo.es> escribi� en el mensaje 
news:ccN1f.4441850$I96.7525036@telenews.teleline.es...
> Hola, necesito comprobar que una expresion matematica este bien formada.
>
> por ejemplo 1+2+3 esta bien 1*/3 no
>
> Para ello, cuando no hay parentesis es bastante facil

...

Muchas gracias a todos por las contestaciones, me ha habeis dichos cosas muy 
interesantes, que mirare con mas detenimiento.  (ma�ana voy a intenar 
hacerlo con perlredescent).

finalmente me decidi por implementarlo manualmente, como un especie de 
automata a pila, lo dejo por si a alguien le sirve, falta implementar las 
funciones (sin, cos, tan), pero es algo bastante facil, similar a los 
parentesis.

Un saludo y gracias




$num   = "-?\\d*\\.?\\d+";
$op    = '\*|\/|\%|\+|\-';
$TRUE  = 1;
$FALSE = 0;

sub verificar {
    $expr = shift();

    #Inicializo varables
    $expr2    = $expr;
    $correcta = $TRUE;
    $q        = 0;
    @pila     = ("x");

    # 0--> S
    # 1--> N
    # 3 --> final
    # S::= num$|numN|(S
    # N::= $opS|)$|)N
    #
    #

    print "$expr2: ";
    while ( $q != 3 ) {
        print "q$q ";
        if ( ( $q == 0 ) && ( $expr2 =~ s/^\s*$num\s*$//i ) ) {
            $q = 3;
            last;
        }
        elsif ( ( $q == 0 ) && ( $expr2 =~ s/^\s*$num\s*//i ) ) {
            $q = 1;
        }
        elsif ( ( $q == 0 ) && ( $expr2 =~ s/^\s*\(\s*// ) ) {
            $q = 1;
           unshift @pila, "(";
        }
        elsif ( ( $q == 1 ) && ( $expr2 =~ s/^\s*$op\s*// ) ) {
            $q = 0;
        }
        elsif ( ( $q == 1 ) && ( $expr2 =~ s/^\s*\)\s*$// ) ) {
            $p = shift(@pila);
            $q = 3;
            if ( $p ne "(" ) {
              print "$p ";
                $correcta = $FALSE;
                last;
            }
        }
        elsif ( ( $q == 1 ) && ( $expr2 =~ s/^\s*\)\s*// ) ) {
            $p = shift(@pila);
            $q = 1;
            if ( $p ne "(" ) {
                print "$p ";
                $correcta = $FALSE;
                $q        = 3;
                last;
            }
        }
        else {
            $q        = 3;
            $correcta = $FALSE;
            last;
        }

    }

    $p=shift(@pila);
    print "$p \n";
    if ($correcta eq $FALSE || $p ne "x"){
      return 0;
    }else {
      return 1;
    }

}

print "introduce la expresion aritmetica: ";
$expr=<STDIN>;
chomp($expr);

$compro = verificar($expr);

print "La comprobacion es $compro\n";
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads