Elementele limbajului ALLO

    Pe baza alfabetului si a vocabularului se construiesc noi cuvinte de vocabular sau asamblaje din ce in ce mai complexe pina la asamblajul cu maxima incarcatura sintactica si semantica numit program sau model. Elementele de baza ale limbajului ALLO sunt :

            comentarii;
            nume sau identificatori;
            constante;
            tablouri;
            indici;
            variabile;
            operatori aritmetici;
            operatori functionali;
            paranteze;
            delimitatori;
            expresii;
            lista de argumente de apel functie;
            lista dimensionala;
            lista indiciala;
            asamblaj de ciclare;
            instructiuni;
            lista de instructiuni;
            lista de conditii;
            sectiuni;
            program

    In continuare vom detalia fiecare din elementele de baza din constructia unui model prezentate mai sus. Despre unele deja am spus suficiente elemente de definire si nu mai insistam asupra lor.

Comentarii

    Cometariile sunt elemente deosebit de utile in orice program indiferent de limbajul in care este scris. In limbajul ALLO comentariile sunt acceptate oriunde in fisierele sursa ce tin de un program/model.

Un comentariu ALLO este o secventa de caractere din setul ALLO care este imbricata de inceput si sfirsit comentariu . Dupa ce comentariul este deschis analizorul lexical scaneaza sirul de intrare pina intilneste secventa de inchidere. Daca este nevoie se depaseste secventei <CR><LF> de sfirsit linie sursa ceea ce inseamna ca un comentariu poate sa se intinda pe mai multe linii. Acest fapt este util nu numai in ceea ce priveste comentariile de explicare a modelului ci si intr-o posibila utilizare a lor in procesul de depanare. Comentariile si zonele de spatii sunt elemente neproductive cu rol de design si explicare model sursa.

Nume

    Numele este un element esential in constructia oricarui program ALLO fiind un element de vocabular, un token identificabil de catre analizorul lexical ALLO. Numele se formeaza cu ajutorul literelor, cifrelor si caracterului subliniere care are rol de legatura intre doua sau mai multe componente de nume mai scurte carora utilizatorul le da un inteles. Desigur nimeni nu ne impiedeca sa lipim aceste nume si sa nu utilizam aceasta legatura. Depinde de preferinta, de design. Totusi folosirea caracterului este chiar utila caci pune in evidenta componentele.

    Un nume valid incepe numai cu litera care poate sa fie urmata de : o litera, o cifra, caracterul de legatura underscore. Lungimea trebuie sa nu depaseasca maximul permis caz rezolvat prin trunchere.

Precizari de metalimbajul folosit in definirea sintaxei ALLO

::= semnifica faptul ca elementul din stinga acestui simbol se construieste dupa cum se indica in dreapta sa sau ca este prin definitie dupa cum se spune in dreapta sa;

| semnifica faptul ca putem alege pe oricare element din lista ale carei elemente sunt separate de acest simbol;

Spatiu dintre doua elemente de metalimbaj sau dintre un element de metalimbaj si un atom (cum este cazul dintre nume si caracterul de link _ din finalul listei de mai jos) inseamna operatia de concatenare dintre doua siruri ce apartin clasei(multimii) din care fac parte cele doua elemente. Un element de metalimbaj semnifica in fapt o clasa(multime) de asamblaje (siruri pe alfabet in cele din urma) ce se obtin prin aplicarea regulilor implicate in construirea acelui element.

lambda este simbolul elementului nul fata de operatia de concatenare caractere sau siruri de caractere. Il putem considera ca un sir vid deci care n-are nici un caracter in el fiind astfel de lungime zero.

Sintaxa

nume ::= litera | nume litera | nume cifra | nume _
litera ::= orice element al multimii litere definita in setul caractere

(partea dreapta este un text comentariu ce nu se supune regulilor de interpretare metalimbaj asertiune valabila si pentru definitia <cifra> )

cifra ::= orice element al multimii cifre definita in setul caracte

Exemple : nrfprod, fprod, ump, xprod, cost_prod, st_cost, per_1

Cuvinte cheie ALLO


Nr
Nume
Descriere rol
01 MODEL Inceput model 
02 END Sfirsit model
03 VARIABLES Inceput sectiune variabile model
04 OBJECTIVES Inceput sectiune functii obiectiv
05 CONSTRAINTS Inceput sectiune restrictii
06 FILE Inceput instructiune definire fisiere secundare cu date 
07 RANGE Inceput instructiune definire domenii intregi sau reale
08  INTEGER Inceput instructiune definire variabile aux. intregi
09 REAL Inceput instructiune definire variabile auxiliare reale
10 READ Comanda de citire date de initializare din fisier sec.
11 IN Inceput conditie de apartenenta la un domeniu de valori
12 IS Clauza de definire globala
13 FOR Inceput secventa de ciclare
14 SUM Inceput functie de sumare
15 MINIMIZE Inceput instructiune de selectie functie obiectiv 
16 MAXIMIZE Inceput instructiune de selectie functie obiectiv
Actiuni intermediare de tip functii
17 ABS Valoarea absoluta
18 AND Si logic
19 APX Ridicare la putere cu baza variabila
20 ATR Functie de schimbare valori pentru unele variabile aux.
21 DIP Diferenta pozitiva
22 IFP Test de pozitivitate cu intoarcere valoare selectata
23 IFS Test logic cu intoarcere valoare selectata
24 LOR Sau logic
25 LOG Logaritm zecimal
26 MAX Maxim a doua valori
27 MIN Minim a doua valori
28 MOD Restul impartirii intregi
29 NOT Negare logica
30 SEARCH Cautare existenta valoare cu intoarcere rezultat si loc
31 SIG Semnul valorii
32 SQR Radical de ordin doi
33 XOR Sau exclusiv

Precizari

    Cuvintele din tabelul de mai sus sunt rezervate si pot fi utilizate si prin scriere combinata litere mari cu mici dupa cum doreste utilizatorul. Toate (inclusiv combinatiile rezultate) nu mai pot face obiectul unor instructiuni de definire variabila de orice natura ar fi. Functiile trebuie sa fie apelate conform definitiei lor cu respectarea numarului de argumente actuale si a tipului cerut.

Constante

    Constantele sunt elemente necesare oricarui limbaj de programare sau specializat. In limbajul ALLO ele sunt utilizate fie direct in constructia unui model fie indirect prin faptul ca servesc la initializarea unor variabile auxiliare care sunt utilizate in constructia respectiva. ALLO permite construirea si utilizarea urmatoarelor tipuri de constante :

            - constante intregi;
            - constante reale;
            - constante domeniu;
            - siruri de caractere.

Constante Intregi

    O constanta intreaga este o secventa de cifre zecimale in fata careia poate apare semnul + sau minus. ALLO permite constante intregi in domeniul de valori pe simplu cuvint, adica [ -32768 , + 32767 ]. Pentru valori mai mari sunt constante reale sau variabile intregi care pot fi asignate cu expresia dorita.

Sintaxa

secv_cifra ::= cifra | cifra secv_cifra
numar_intreg ::= semn secv_cifra
semn ::= - | + | lambda

Exemple : 3457 -15481 +12 -32768 +32767

Constante Reale

    Constantele reale sunt compuse din semn, parte intreaga, punct zecimal, parte fractionala si eventual de exponentul E sau e urmat de semn si de numar exponent. Domeniul aproximativ de valori al unei astfel de constante este [ - 3.4028235E+38, - 1.1754944E-38 ] (domeniu negativ) plus domeniul pozitiv [ 1.1754944E-38 , 3.4028235E+38 ] si desigur valoarea 0 ca element obligatoriu in operatii.

Sintaxa

numar_real ::= semn p_int . p_frac exponent
p_int ::= secv_cifra | lambda
p_frac ::= secv_cifra | lambda
exponent ::= lambda | E numar_intreg | e numar_intreg

Observatii.

    1. p_int poate lipsi cind este prezenta <p_frac> si invers. dar nu pot lipsi simultan.

    2. Dupa cum se vede exponent nu este obligatoriu fapt semnalat prin posibilitatea de alegere a lui lambda.

    3. exponent se incadreaza relativ in limita a doua cifre zecimale utile.

Exemple : .517 -32.7564 +3. 0.342E-15 -2.51e+9 -3.4028235E+38

Constante domeniu

    Sunt elemente ale limbajului ALLO ce definesc un interval pe axa reala sau in multimea numerelor intregi. Ele contin cele doua marimi care definesc un asemenea interval : marginea inferioara si marginea superioara.Aceste marimi sunt inchise intre paranteze drepte si sunt separate de o virgula. Marimile pot fi constante numere reale sau intregi dar pot fi expresii aritmetice calculabile in acel punct in care apare si este utilizata constanta domeniu respectiva ca marime de initializare a unei variabile domeniu sau ca un domeniu adhoc. Tipul rezultat din evaluarea unei expresii aritmetice este intreg daca operanzii sunt toti intregi, altfel este tipul real. Constantele domenii reale sunt de regula utilizate in clauzele de dubla marginire atunci cind nu se folosesc variabile domeniu definite anterior. In functie de context se apreciaza daca constanta reprezinta un domeniu intreg sau un domeniu real chiar daca rezultatul de evaluare al expresiilor de margini contrazic tipul. De exemplu intr-o clauza de ciclare o constanta este evaluata cu margini intregi deci trebuie sa reprezinte un interval intreg. De asemenea intr-o lista de dimensiuni o constanta este evaluata la un interval de numere intregi. Daca o constanta initializeaza o variabila domeniu a carei utilizare nu se cunoaste inca atunci pentru domeniu se pastreaza cele doua valori : interval intreg si interval real.

Trebuie mentionat ca in ALLO sunt permise constante domeniu care nu pot fi evaluate decit intr-un anumit context si a caror valoare poate fi diferita in functie de valoarea unor indici de ciclare care participa in expresiile de margini. Este cazul asa numitelor constante domeniu dinamice care suporta reevaluarea lor de fiecare data cind se initializeaza ciclul de care tine.

Sintaxa

const_domeniu ::= [ expr_aritm , expr_aritm ]

Exemple : [ -2,17] [ 34.5,70.18] [ m/2,3*n ] [ a+3.2*(k+1), b+18.65 ]

    Observatie. Variabile auxiliare intregi m,n sunt definite anterior, deci expresiile sunt calculabile in acest moment. La fel a,b sunt variabile auxiliare ale caror valori se cunosc deja iar k este un indice de ciclare intr-o clauza FOR in al carei bloc cu instructiuni apare aceasta constanta de tip domeniu, deci in acest ciclu expresiile sunt calculabile.

Siruri de caractere

Sunt compuse din unul sau mai multe caractere ale alfabetului ALLO delimitate de o pereche de ghilimele duble care astfel nu mai pot fi incluse in nici un sir. Sirurile sunt utilizate in definirea specificatiei externe de identificare fisier sub sistemul de operare DOS. O asemenea specificatie poate sa contina numai numele si tipul despartite de punct, caz in care fisierul este cautat in directorul de lucru al translatorului, sau poate contine si path-ul respectiv caz in care este cautat in concordanta cu acesta.

Sintaxa

sir ::= " secv_car "
secv_car ::= car | car secv_car
car ::= caracter ASCII recunoscut de ALLO (text comentariu)

Exemple : "e:\lpmodels\allo\prod.dat" "cetsud.dat" "twood.dat"

Masive

    Masivele sunt creatii speciale ale unui limbaj de programare si nu numai. Ele sunt formate din unul sau mai multe celule/obiecte identice organizate dupa o regula dimensionala cunoscuta care permite identificarea locului ocupat (in aceasta structura) de catre fiecare obiect. Masivele sunt caracterizate printr-o lista de dimensiuni, prin spatiul alocat fiecarei celule si prin regula de alocare sau de regasire a fiecarei celule. Masivele unidimensionale sunt cunoscute sub denumirea de vectori, cele cu doua dimensiuni sub numele matrici. Masivele cu trei dimensiuni sunt numite masive tridimensionale, cu n dimensiuni masive n-dimensionale.

Sintaxa

masiv ::= nume_masiv [ l_dim ]
nume_masiv ::= nume

Exemple : storcost [rmat] ump [rmat,fprod] xsmat[rmat,perpext]

Lista dimensiuni

    Dupa cum am spus un masiv este marcat de o lista de dimensiuni care-i definesc dimensiunea, forma sa. O dimensiune a unui masiv este reprezentata de un domeniu de intregi care are un numar de elemente dat de diferenta dintre marginea superioara si marginea inferioara la care trebuie adaugat unu. Acest numar participa la calculul numarului total de elemente al tabloului ca fiind produsul tuturor numerelor astfel asociate dimensiunilor. O dimensiune clasica reprezinta un domeniu [1, n] astfel ca numarul de elemente reprezentat de aceasta dimensiune este n-1+1 = n, chiar marginea superioara. Este inteles ca in aceasta situatie marginea inferioara nu mai trebuia retinuta. Mai mult un domeniu intreg oarecare poate fi pus in corespondenta biunivoca cu un astfel de domeniu clasic dimensional incit mai jos vom face citeva considerente pe acest caz.

Sintaxa

l_dim ::= dim | dim , l_dim
dim ::= domeniu
domeniu ::= const_domeniu | var_domeniu
var_domeniu ::= nume

Exemple : rmat | rmat,fprod | [1,10] , dim2 , dim3

Observatie. [1,10] prima dimensiune din lista 3 este o constanta de tip domeniu, celelalte doua dimensiuni dim2, dim3 sunt nume de domenii care ar trebui sa fie definite inainte de utilizarea lor in alt loc sau in aceasta lista.

Mod de alocare

    Se cunosc doua reguli de alocare si regasire a elementelor unui tablou : regula de liniarizare pe coloane si regula de liniarizare pe linii cu referire la modul de liniarizare a unei matrici mod mai usor de explicat si de inteles.

    O matrice a[m,n] (cu prima dimensiune domeniul [1,m] iar a doua domeniul [1,n]) poate fi privita ca avind elementele dispuse pe m linii dar poate fi privita ca avind elementele dispuse pe n coloane.

    Daca alocam intii elementele coloanei 1, apoi elementele coloanei 2, si in final elementele coloanei n avem alocarea si regasirea pe coloane. In acest caz elementele matricei ar fi privite in felul urmator : a[1,1], a[2,1]...,a[m,1], a[1,2], a[2,2]..., a[m,2]..., a[1,n], a[2,n]... a[m,n]. Se observa ca cel mai activ sau mai rapid indice a fost indicele unu in timp ce indicele doi a stat nemiscat pina ce indicele unu a trecut prin toate liniile coloanei respective. In acest caz locul elementului a[i,j] in aceasta lista liniarizata este dat de formula loc(a[i,j]) = (j-1)* m+ i.

    Daca alocam intii elementele liniei 1, apoi elementele liniei 2, si in final elementele coloanei n avem alocarea si regasirea pe linii. In acest caz elementele matricei ar fi privite in felul urmator : a[1,1], a[1,2]...,a[1,n], a[2,1], a[2,2]..., a[2,n]..., a[m,1], a[m,2]... a[m,n]. Se observa ca cel mai activ sau mai rapid indice a fost indicele doi in timp ce indicele unu a stat nemiscat pina ce indicele doi a trecut prin toate coloanele liniei respective. In acest caz locul elementului a[i,j] in aceasta lista liniarizata este dat de formula loc(a[i,j]) = (i-1)* n+ j.

    Se observa ca acelasi element a[i,j] poate avea alt loc care depinde de modul de alocare utilizat.

    In implementarea masivelor ALLO am ales solutia liniarizarii pe linii ceace inseamna ca ultimul indice este cel mai activ urmat de penultimul si in cele din urma ramine primul indice. Dupa cum se vede prima dimensiune nu este implicata in aceasta formula de alocare. Sa o vedem si pentru trei dimensiuni. Daca a[m,n,p] este un masiv tridimensional (pe care putem sa-l privim ca un cub format din m*n*p cubulete identice) atunci pentru cubuletul a[i,j,k] (pe stratul de inaltime k la intersectia liniei i cu coloana j) avem loc(a[i,j,k])=((i-1)*n +j-1)*p +k.

    In AlLO variabilele auxiliare de tip intreg sau real, variabilele modelului, variabilele functii obiectiv si variabilele restrictii pot fi declarate ca masive de variabile vectori,matrici,tridimensionale,etc. Aceasta usureaza munca de scriere a unui model complex de mari dimensiuni.

Referinta la un element de masiv

    Dupa cum am vazut un masiv este o colectie de celule/obiecte de acelasi tip (cu aceleasi atribute) organizate dupa o procedura de alocare si regasire cunoscuta. Accesul la o astfel de celula/obiect se face prin invocarea numelui acelui masiv si a unei liste de expresii indici al carei numar de elemente coincide cu numarul de dimensiuni ale masivului. Aceasta constituie asa numita referinta la acel element din masiv pe baza caruia se regaseste.

    Expresia indice este o expresie aritmetica calculabila (in momentul utilizarii ei) care indeplineste rolul unui indice in lista de referinta a unui element de masiv. Valoarea acesteia este convertita la o valoare intreaga dupa care se face testul de apartenenta la domeniul corespunzator dimensiunii locului. Similar se procedeaza cu orice expresie indice dintr-o lista de expresii indiciale. Dupa aceasta se trece la calculul indicelui liniarizat care reprezinta locul elementului referit. Pe baza locului se poate calcula si adresa fata de inceput prin inmultirea (loc -1) cu unitatea de alocare a tipului variabilei.

Sintaxa

ref_element_masiv ::= nume_masiv [ l_expr_ind ]
l_expr_ind ::= expr_ind | expr_ind , l_expr_ind
expr_ind ::= expr_aritm

Exemple : ump [r,f] storcost [r] xprod[f,p]

Oprd [ ATR(opczindl[j],h) + ATR((h-1)/nrprod+1,m)+h-(m-1)*nrprod , m]

    Observatie. Expresiile indiciale din primele trei exemplele de aici sunt cele mai simple formate pe baza invocarii numelui de variabila auxiliara de tip indice r, f, p. In ultimul exemplu prima expresie indiciala este dupa cum se vede o expresie aritmetica mai complicata in care intervin doua actiuni intermediare. ATR(opczindl[j],h) este o functie a carei valoare este zero (in orice apel) nu inainte de a atribui lui h valoarea calculata a elementului de vector opczindl[j]. Aceasta actiune usureaza calculul si scrierea primei expresii indiciale care are in continuare citat pe h ca operand cit calculul si scrierea celei de-a doua expresie indicial redusa la numele m care a fost calculat ca o necesitate in prima expresie indiciala. ATR((h-1)/nrprod+1,m) face actiunea intermediara de atribuire lui m a valorii expresiei (h-1)/nrprod+1. Dupa cum am spus acest fapt usureaza calculul si scrierea celor doua expresii indiciale cit si referinta la elementul corespunzator din matricea Oprd.