Oberon-2
Az Oberon-2 szintaxisa
2.1. Lexikális elemek
-
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
-
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 |
-
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:
-
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."
-
Szimbólumok:
symbol = "+" | "-" | "*" | "/" | "~" | "&" | "."
| "," | ";" | "|" | "(" | ")" | "{" | "}" | "[" | "]" | ":=" | "^" | "=" | "#"
| "<" | ">" | "<=" | ">=" | "=" | "<>" | ".." | ":"
-
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"
-
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:
- 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)
- Egy objektumra csak a hozzá tartozó láthatósági blokkon belül lehet
hivatkozni.
- 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.
- 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
- v változó típusú rekord paraméter vagy pointer és
- 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:
- ~ (logikai negáció)
- multiplikativ operátorok (* / DIV MOD &)
- additív operátorok (+ - OR)
- 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