analizador con el yapps (solucion casi completa)
Attila Saorin
mostroratas en yahoo.es
Mie Ago 21 12:23:54 CEST 2002
--- Esteban Manchado Velázquez <zoso en demiurgo.org> escribió:
> Si ya sabes de gramáticas va a ser trivial implementar el analizador para
> esas expresiones. Ten en cuenta que necesitarías, probablemente, cinco
> terminales («and», «or», «paréntesis abierto», «paréntesis cerrado»,
> «literal») y una gramática *muy* simplona para resolver eso. Luego pones los
> trocitos de Python donde haga falta para manejar los casos y listo.
>
> ¡Ánimo! :-)
pues nada, envio el mail para contaros como ha salido todo, estoy contento pq ya sale casi todo (a
ver si consigo que vaya todo, pero...)
al final use el yapps para resolver mi problemilla y despues de trastear un poco, me ha quedado
una gramatica de la forma:
-----------pred.g-------------------------------------
parser BoolOp:
option : "context-insensitive-scanner"
ignore : "[ \t\n\r]"
token END: "\\'"
token TERM: '[a-zA-Z][a-zA-Z_0-9]*'
token AND: "&"
token OR: "|"
token NOT: "!"
rule expr: pred END -> << pred >>
rule pred: TERM pred_rest<<TERM>> -> << pred_rest >>
| NOT pred -> << 'Not'+"("+pred+")">>
| "(" pred ")" par_rest<<pred>> -> << par_rest >>
rule pred_rest<<pred1>>: -> << 'Terminal'+"('"+pred1+"')" >>
| opbool pred -> << opbool+"("+'Terminal'+"('"+pred1+"')"+","+pred+")">>
rule opbool: AND -> << 'And' >>
| OR -> << 'Or' >>
rule par_rest<<pred2>>: -> << pred2 >>
| opbool pred -> << opbool+"("+pred2+","+pred+")">>
-------------------------------------------------------------------------
asi que luego genero el modulo python con el yapps y hago una purbecillas con los parentesis
anidados o en distintos formatos y va bien :)
>>> pred.parse('expr','linux & pc')
"And(Terminal('linux'),Terminal('pc'))"
>>> pred.parse('expr','linux & pc4')
"And(Terminal('linux'),Terminal('pc4'))"
>>> pred.parse('expr','2linux & pc4') <---- no deberia ir por empezar por numero
Bad Token on line 1:
> 2linux & pc4
> ^
List of nearby tokens:
>>> pred.parse('expr','linux|(sun&(!pc))')
"Or(Terminal('linux'),And(Terminal('sun'),Not(Terminal('pc'))))"
>>> pred.parse('expr','(www|http)&!bsd')
"And(Or(Terminal('www'),Terminal('http')),Not(Terminal('bsd')))"
>>> pred.parse('expr','linux')
"Terminal('linux')"
>>>
Asi que ya digo digo que funciona con parentesis anidados y con parentesis antes y o despues de
otras cosas. Con eso ya funciona :) Ahor ya solo falta para hacerlo mas completo que tambien
pudiera reconocer los tokens 'and, 'or' y 'not' ademas de los simbolos (y poder escribir algo
como: 'linux and sun') y esto no lo he conseguido aun, no se muy bien por que, intenta asignarlo a
un terminal en vez con un operador booleano :(
obviamente no es la misma gramatica, esta prueba es para ver si reconoce esos caracteres en vez de
los simbolos:
token AND: "and"
token OR: "or"
token NOT: "not"
>>> predl.parse('expr','linux and www')
Could not match pred_rest on line 1:
> linux and www
> ^
List of nearby tokens:
(@0) TERM = 'linux'
(@6) TERM = 'and'
>>>
bueno, si a alguno le interesa, cuando lo consiga os lo mando.
Un saludo y por cierto, a veces me desborda ver de las cosas de las cosas de las que hablais y que
no tengo ni idea ni de que son, pero en el fondo me gusta intentar entender el codigo o del tema,
al menos veo que hay montones de cosas en python, para hacer de, casi todo o todo? :)
Attila
_______________________________________________________________
Yahoo! Messenger
Nueva versión: Webcam, voz, y mucho más ¡Gratis!
Descárgalo ya desde http://messenger.yahoo.es
Más información sobre la lista de distribución Python-es