Aquest es el tercer escrit d’una sèrie que repassarà el desenvolupament d’un llenguatge de programació amb el qual poder fer JailGames de forma ràpida i còmoda. En aquest post vorem una descripció pseudo-formal del llenguatge.
Nivell lèxic
A nivell lèxic, el llenguatge distingirà entre tres tipus genèrics de paraula:
- Numèrics: 1 o més dígits, seguits opcionalment per un punt "." i 1 o mes dígits.
- Alfanumèrics: Una lletra o "_", opcionalment seguida de lletra, dígit o "_".
- Cadenes: doble cometa (") fins a la següent doble cometa.
- Símbols: Operadors del tipus "=", ",", "+", "<=" o inclús "\n".
Els numèrics sempre seran constants numèriques i ja està. Però els alfanumèrics poden ser paraules clau del llenguatge (IF, ELSE...), tipus de dades (NUMBER, STRING o els que defineixca l’usuari), funcions (internes o externes) o variables. Les cadenes agafen qualsevol caràcter que hi haja entre les dobles cometes. Per últim, si no es numèric, alfanumèric o cadena, es comprovarà si es un dels operadors (matemàtics, lògics, de control...) coneguts pel llenguatge. En cas contrari, tindrem un error de sintaxi.
Gramàtica
Vaig a expressar la gramàtica del llenguatge, o siga les frases vàlides, en una espècie de pseudo forma de Backus-Naur, però sense crear realment regles de producció. Es un poc rotllo així que passe de liar. Pero abans de vomitar-les totes, un poquet d’explicació amb un exemple:
ASSIGNSTAT = <ID_VAR> = <EXPR>
Espera... que cony es això? Explique: Vaig a definir una assignació de valor a una variable, bàsicament açò:
peric = delgat + 3
“ASSIGNSTAT” es el nom d’esta regla o frase. “ID_VAR” representa a una paraula alfanumèrica asociada a una variable ja declarada abans (en el exemple, “peric”). “=” se representa a si mateix. <EXPR> representa a una expressió, o siga, una combinació de operacions matemàtiques i lògiques entre constants, variables i resultats de funcions que donarà com a resultat un valor (en l’exemple “delgat + 3”).
STRUCTSTAT = STRUCT <UNK> [ <UNK> AS <TYPE> ]+ END
FUNSTAT = FUNCTION <UNK> ( [ <UNK> AS <TYPE> [ , <UNK> AS <TYPE> ]* ) [ AS <TYPE> ] <LOCAL> END
VARSTAT = VAR <UNK> AS [ ARRAY OF <NUM> ] <TYPE> [ = <EXPR> ]
CONSTSTAT = CONST <UNK> = <EXPR>
ASSIGNSTAT = <ID_VAR> = <EXPR>
CALLSTAT = <ID_FUN> ( [ <EXPR> [ , <EXPR> ]* ] )
IFSTAT = IF <EXPR> THEN <LOCAL> [ ELSE <LOCAL> ] END
WHILESTAT = WHILE <EXPR> DO <LOCAL> END
REPEATSTAT = REPEAT <LOCAL> UNTIL <EXPR>
FORSTAT = FOR <UNK> = <EXPR> TO <EXPR> [ STEP <EXPR> ] DO <LOCAL> END
RETURNSTAT = RETURN [ <EXPR> ]
<UNK> es refereix a un identificador que no s’haja definit encara en el àmbit actual.
<TYPE> es refereix a un tipus que ja s’haja declarat.
<ID_VAR> i <ID_FUN> es refereixen a identificadors assignats a una variable i a una funció.
<EXPR> es refereix a una expressió, tindrem un capítol nomes per a les expressions més avant.
<LOCAL> es refereix a un context, ara ho vorem.
Contextos
Hi ha dos tipus de context definits: Global i local. El context global es el que hi ha a la part mes externa del programa. En eixe context nomes podem declarar variable, constants, estructures i implementar funcions.
GLOBAL = [ VARSTAT | CONSTSTAT | STRUCTSTAT | FUNSTAT ]*
Als contextos locals (que es corresponen als elements <LOCAL> de les gramàtiques anteriors) no es poden declarar estructures ni implementar funcions, però poden aparèixer totes les demes regles.
LOCAL = [ VARSTAT | CONSTSTAT | ASSIGNSTAT | CALLSTAT | IFSTAT | WHILESTAT | REPEATSTAT | FORSTAT | RETURNSTAT ]*
Àmbits
Les variables es declaren a un cert àmbit. Les variables declarades al context global tenen l’àmbit més ample, al poder ser accedides des de qualsevol context (el que coneguem com a “variables globals”).
Per altra part, les variables declarades dins d’un context local nomes podran ser accedides des d’eixe context i els contextos interns. Per exemple, si tenim una funció i dins d’ella declarem una variable “teib”. I a més dins de la funció tenim després un “if”, i dins del “if” declarem una variable “peiv”. Des de dins del “if” podem accedit tant a “teib” com a “peiv”, però desde la funció, fora del “if”, tant abans com després, no podrem vore “peiv”.
Els contextos i els àmbits es corresponen quasi totalment, excepte per les següents excepcions:
- Els paràmetres de una funció formen part de l’àmbit del context <LOCAL> de dins de la funció.
- La variable d'iteració d’un bucle FOR forma part de l’àmbit del context <LOCAL> de dins del FOR.
A més, STRUCT crea una especie d’àmbit “privat”.
Si re-declarem una variable ja declarada en un àmbit pare, la nova variable ocultarà a l’anterior, no havent forma de accedir a l’anterior des de l’àmbit actual. El compilador soltarà un “warning” quan ho detecte. Obviament, açò no afecta als STRUCTs.
Que rollo! En el pròxim post canviaré un poc el focus i parlaré de la màquina virtual.
Cap comentari:
Publica un comentari a l'entrada