Oberon-2

Az Oberon-2 szintaxisa



2.1. Lexikális elemek

  1. Azonosítók:

    Egy azonosító betûkbol és számokból állhat, az elsõ karakternek betûnek kell lennie.

    ident = letter { letter | digit } 
      

    letter = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" | "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | T" | "U" | "V" | "W" | "X" | "Y" | "Z" digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"

    Példák:
    x Scan Oberon2 GetSymbol firstLetter m16b24

  2. Numerikus konstansok:

    Egy numerikus konstans egy elõjel nélküli egész vagy valós szám. Az egész szám állhat decimális alakban, ami decimális számjegyek sorozata, vagy hexadecimális alakban, ami hexadecimális számjegyek sorozata a végén egy 'H' betuvel. A valós szám mindig decimális alakban áll, és tizedes pontot tartalmaz. Ezenkívül állhat a végén egy E (REAL típus esetén) vagy D (LONGREAL típus esetén) betûvel bevezetett kitevõ is.

    number = integer | real

    integer = digit {digit} | digit {hexDigit} "H"

    real = digit {digit} "." {digit} [ScaleFactor]

    ScaleFactor = ("E" | "D") ["+" | "-"] digit {digit}

    hexDigit = digit | "A" | "B" | "C" | "D" | "E" | "F"

    Példák:
    1991
    INTEGER
    1991
    0DH
    SHORTINT
    13
    12.3
    REAL
    12.3
    4.567E8
    REAL
    456700000
    0.57712566D-6
    LONGREAL
    0.00000057712566

  3. Karakter konstansok:

    Egy karakter konstans egy idézõjelek közé zárt tetszõleges karatkter, vagy egy hexadecimális szám egy azt követõ 'X' betûvel. Utóbbi esetben a szám egy karakter kódját jelenti.

    character = '"'char'"' | digit {hexdigit} "X"

    Példák:
    "a" "z" 41X 0FX

  4. Karakterfüzér konstansok:

    Egy karakterfüzér konstans tetszõleges karakterek sorozatából áll. Meg lehet adni egyszeres (') vagy kétszeres (") idézõjelben is, de a nyitó- és a záró idézõjelnek meg kell egyeznie és nem fordulhat elõ a karaktersorozatban. Egy karakterfüzér nem nyúlhat át másik sorba. Karakterfüzért értékül lehet adni és össze lehet hasonlítani karaktertömbbel.

    stringconst = '"'{char}'"' | "'"{char}"'"

    Példák:
    "OBERON" 'password: "12345"' "'Crunchy frog' - hip good."

  5. Szimbólumok:

    symbol = "+" | "-" | "*" | "/" | "~" | "&" | "." 
      | "," | ";" | "|" | "(" | ")" | "{" | "}" | "[" | "]" | ":=" | "^" | "=" | "#" 
      | "<" | ">" | "<=" | ">=" | "=" | "<>" | ".." | ":" 

  6. Kulcsszavak:

    keyword = "ARRAY" | "BEGIN" | "CASE" | "CONST" | "DEFINITION" | "DIV" | "DO" | "ELSE" | "ELSIF" | "END" | "EXIT" | "IF" | "IMPORT" | "IN" | "IS" | "LOOP" | "MOD" | "MODULE" | "NIL" | "OF" | "OR" | "POINTER" | "PROCEDURE" | "RECORD" | "REPEAT" | "RETURN" | "THEN" | "TO" | "TYPE" | "UNTIL" | "VAR" | "WHILE" | "WITH"

  7. Megjegyzések:

    Bárhol két szimólum között el lehet helyezni a programban. A megjegyzés kezdetére a '(*' a befejezésére a '*)' szolgál.

    comment = '(*' {anything but not '*)'} '*)'

    Példa:
    (* Ez itt egy megjegyzés! *)

2.2. Deklarációk és láthatósági szabályok

A programban minden azonosítót deklarálni kell, kivéve az elõre definiált azonosítókat. A deklaráció láthatósága a deklarációtól a blokk (eljárás, modul) végéig tart.

Néhány kiegészítés a láthatósághoz:

  1. Egy azonosító nem jelölhet több objektumot ugyanazon láthatósági blokkon belül. ( pl. nem lehet kétszer deklarálni egy azonosítót egy blokkban)
  2. Egy objektumra csak a hozzá tartozó láthatósági blokkon belül lehet hivatkozni.
  3. Ha egy T típus POINTER TO T1-nek van deklarálva, a T1 deklarációja lehet késõbb, mint a T deklarációja, de csak ugyanazon láthatósági blokkon belül.
  4. Rekord mezõinek azonosítóira csak a rekord típusú változó, konstans vagy formális paraméter nevével minõsítetten lehet hivatkozni.

    Példa:
    R = RECORD
       x : INTEGER;
    END;
    
    VAR a : R;
    Ekkor az a-beli x csak a.x-ként látszik.

Azonosító lehet minõsített modul nevével minõsített is (idegen modulban deklarált azonosítókra csak így lehet hivatkozni):

QualIdent = [ident "."] ident

Az elõre definiált azonosítók Oberonban a következõk:

ABS ADR ASH BOOLEAN BYTE CAP CHAR CHR DEC ENTIER EXCL FALSE HALT INC INCL 
INTEGER LEN LONG LONGINT LONGREAL MAX MIN NEW ODD ORD REAL SET SHORT SHORTINT 
SIZE TRUE 

Konstans deklarációk:

Egy konstans azonosítónak egy fordításkor meghatározható kifejezéssel értéket adhatunk.

ConstDeclarations = "CONST" {ConstDeclaration}

ConstDeclaration = ident "=" Constexpr

ConstExpr = Expression

Példa:
CONST
   N = 100;
   limit = 2 * N - 1;
   FULLSET = { MIN ( SET ) .. MAX ( SET ) };

Típus deklarációk

A típus deklarációval egy típust rendelünk egy azonosítóhoz. Az alaptípusok és a már meglévõ típusok segítségével újabb típusokat hozhatunk létre.

TypeDeclarations = "TYPE" {TypeDeclaration}

TypeDeclaration = ident "=" Type

Type = QualIdent | ArrayType | RecordType | PointerType | ProcedureType

Példa:
TYPE
   Table = ARRAY N OF REAL;
   Tree = POINTER TO Node;
   Node = RECORD
      key : INTEGER;
      left, right : TREE
   END;
   CenterNode = RECORD ( Node )
      name : ARRAY 32 OF CHAR;
      subnode : List
   END;
   Function = PROCEDURE ( INTEGER ) : INTEGER;

TYPE
   T0 = RECORD … END
   T1 = RECORD(T0) … END
   P0 = POINTER TO T0;
   P1 = POINTER TO T1;
 
HA T1 kiterjesztése T0-nak, akkor P1 is kiterjesztése P0-nak és P0 a P1 bázistípusa.

Változódeklarációk:

A változóneveknek egy láthatósági blokkon belül egyedieknek kell lenniük. A rekordoknak és a mutatóknak van statikus (az a típus, amit a deklarációval hozzájuk rendelünk) és dinamikus (az a típus ami futás idoben a típusa) típusa.

VariableDeclarations = "VAR" {VariableDeclaration}

VariableDeclaration = IdentList ":" Type

IdentList = ident {"," ident}

Azonos típusú változókat vesszõvel elválasztva is deklarálhatunk.

Példa:
VAR i, j, k : INTEGER; x, y : REAL; p, q : BOOLEAN; s : SET; a : ARRAY 100 OF REAL; w : ARRAY 16 OF RECORD name : ARRAY 32 OF CHAR; count : INTEGER END;

2.3. Kifejezések

Operandusok:

Designator = Qualident {"." ident I "[" ExpressionList "]" I "^" I "(" Qualident ")"}

ExpressionList = Expression {"," Expression}

Ha a tömb, e INTEGER típusú kifejezés, akkor a[e] az a tömb e-dik eleme. Az a[e0,e1,...,en] kifejezés ugyanazt jelenti, mint az e[e0][e1]...[en] kifejezés. Ha r rekord, akkor az f nevû mezõjét r.f-el lehet elérni. Ha p pointer, akkor p^ a p által mutatott objektum. A p^.f illetve p^[e] kifejezések helyett írható p.f illetve p[e] is.

Típusõr: v(T) megvizsgálja, hogy a v által jelölt objektum dinamikus típusa T-e (vagy T-nek leszármazottja-e). He nem, akkor a program futása megszakad. Az õrfeltétel teljesül, ha

  1. v változó típusú rekord paraméter vagy pointer és
  2. T kiterjesztése a v statikus típusának
Ha a leírt objektum konstans vagy változó, akkor a leíró az aktuális értékét jelöli. Ha eljárás, akkor ezt az eljárást jelöli, kivéve, ha a leírót egy (esetleg üres) paraméter-lista követi, amely esetben az eljárás végrehajtódik, és visszatérési értéke lesz a leírt objektum. Az aktuális paraméterek meg kell, hogy feleljenek a formális paramétereknek.
Példák:
i
(INTEGER)
a[i]
(REAL)
w[3].name[i]
(REAL)
t.left.right
(Tree)
t(CenterTree).subnode
(Tree)

Operátorok:

Minden operátor a következõ négy precedenciaosztály valamelyikébe tartozik, melyek közül az elsõ osztálynak van a legnagyobb, az utolsónak pedig a legkisebb precedenciája:
  1. ~ (logikai negáció)
  2. multiplikativ operátorok (* / DIV MOD &)
  3. additív operátorok (+ - OR)
  4. relációk (= # < <= > >= IN IS)
Expression = SimpleExpression [Relation SimpleExpression]

SimpleExpression = ["+" | "-" ] Term {AddOperator Term}

Term = Factor {MulOperator Factor}

Factor = Designator[ActualParameters] | number | character | string | NIL | Set | "("Expression")" | "~" Factor

Set = "{"[Element {"," Element}]"}"

Element = Expression [".." Expression]

ActualParameters = "(" [ExpressionList] ")"

Relation = "=" | "#" | "<" | "<=" | ">" | ">=" | IN | IS

AddOperator = "+" | "-" | OR

MulOperator = "*" | "/" | DIV | MOD | "&"

A most következõ operátoroknál azonos jelölés esetén az operandusok típusa határozza meg, hogy melyik operátorról van szó.

Logikai operátorok
OR
logikai diszjunkció (vagy)
&
logikai konjunkció (és)
&
negáció (nem)
A logikai operátorok BOOLEAN típusú operandusokkal használhatók, és BOOLEAN típusú eredményt adnak vissza.

Aritmetikai operátorok
+
összeadás
-
kivonás
*
szorzás
/
osztás
DIV
egész osztás
MOD
moduló képzés
Halmaz operátorok
+
unió
-
különbség
*
metszet
/
szimmetrikus differencia
Relációk
=
egyenlõ
#
nem egyenlõ
<
kisebb
<=
kisebb vagy egyenlõ
>
nagyobb
>=
nagyobb vagy egyenlõ
IN
eleme (halmaznak)
IS
típusvizsgálat
Aritmetikai és relációs kifejezések
TYPE Person = RECORD Name: ARRAY 32 OF CHAR; IdNumber: INTEGER; Salary: REAL END; PersonPtr = POINTER TO Person; VAR i: INTEGER; j: LONGINT; r: REAL; set: SET; s: ARRAY 32 OF CHAR; sp: POINTER TO ARRAY OF CHAR; p, p1: PersonPtr; (*Pointer to person which is a record(name,idNumber,salary).*) proc: PROCEDURE (x: INTEGER); Expression Result type 3 SHORTINT 300 INTEGER 100000 LONGINT 0X CHAR i+j LONGINT i+3*(r-j) REAL i DIV j LONGINT i/j REAL s=”a” BOOLEAN p#p1 BOOLEAN proc = NIL BOOLEAN ~(I IN set) BOOLEAN
Logikai kifejezések

a&b if a then b else false end
a OR b if a then true else b end
IF (p#NIL)&(p.name=”John”) THEN … END

Halmaz kifejezések
+ Unió {1..7}+{5..9}={0..9} - Differencia x-y=x*(-y) {1..7}-{5..9}={0..4} * Direktszorzat {1..7}*{5..9}={5..7} / Szimmetrikus differencia x/y=(x-y)+(y-x) {1..7}/{5..9}={0..4,8..9}
Kifejezés kompatibilitás
Operátor Elsõ operandus Második operandus Eredmény típusa + - * numerikus numerikus A kisebbik operandus típusa / numerikus numerikus A kisebbik operandus típusa DIV MOD egész egész A kisebbik operandus típusa + - * / SET SET SET OR & ~ BOOLEAN BOOLEAN BOOLEAN numerikus numerikus BOOLEAN = # < <= > >= CHAR CHAR BOOLEAN kar.tömb,string kar.tömb,string BOOLEAN BOOLEAN BOOLEAN BOOLEAN SET SET BOOLEAN = # NIL, pointer type T0 or T1 NIL, p.t.TO or T1 BOOLEAN NIL, procedure type T NIL, pr.t. T BOOLEAN IN egész SET BOOLEAN IS type T0 type T1 BOOLEAN