De volledige grammatica: hoe Pliro in elkaar zit
Grammatica beschrijft welke combinaties van woorden en tekens geldige code vormen. Deze pagina gebruikt een korte technische notatie: EBNF. Je hoeft die niet uit je hoofd te leren om te beginnen. Gebruik eerst de beginnersartikelen waarnaar wordt verwezen.
Zo lees je de notatie
EBNF staat voor Extended Backus–Naur Form. Daarmee schrijf je regels over een taal op. Denk aan een recept dat vertelt welke ingrediënten waar mogen staan. Het is geen Pliro-code om uit te voeren.
| Notatie | Zo lees je dit |
|---|---|
naam = ... ; |
De regel met deze naam bestaat uit de onderdelen rechts. De puntkomma sluit de regel af. |
"laat" |
Dit woord of teken schrijf je letterlijk in het programma. |
a, b |
Eerst a, daarna b. |
a | b |
Kies a of b. |
[ a ] |
a is optioneel: je mag het weglaten. |
{ a } |
Herhaal a nul of meer keer. |
( a | b ) |
Houd deze keuzemogelijkheden bij elkaar als groep. |
(* ... *) |
Een toelichting voor de lezer van de grammatica. |
Namen zonder aanhalingstekens verwijzen naar andere regels. Die heten ook niet-terminalen: je moet hun regel nog verder uitwerken. identifier betekent een naam, expression code die een waarde oplevert en statement een opdracht. newline sluit een regel af. EOF (end of file) betekent dat het bronbestand op is. INDENT en DEDENT geven het begin en einde van een ingesprongen blok aan. Commentaar wordt voor deze grammaticaregels overgeslagen.
Een token is één herkend stukje code, bijvoorbeeld een naam, een getal of +. De parser zet die stukjes volgens de grammatica bij elkaar. &TOKEN betekent: “controleer of dit stukje hierna komt, maar laat de omringende regel het verwerken.” De tekens in deze tabel beschrijven de grammatica. Tekens tussen aanhalingstekens binnen een regel beschrijven wat je in Pliro typt.
Deze EBNF gebruikt Nederlandse trefwoorden. De Engelse namen van
niet-terminalen zijn beschrijvende grammaticanamen, geen broncode.
INDENT en DEDENT ontstaan uit inspringing; commentaar is weggelaten.
program = { newline | statement }, EOF ;
statement = useStatement
| letStatement
| setStatement
| ifStatement
| whileStatement
| forStatement
| functionDeclaration
| eventHandler
| returnStatement
| commandCallStatement
| expressionStatement ;
useStatement = "gebruik", moduleName, lineEnd ;
moduleName = identifier, { ".", identifier } ;
letStatement = "laat", identifier, "=", expression, lineEnd ;
setStatement = "zet", assignmentTarget, "=", expression, lineEnd ;
assignmentTarget = identifier,
{ "[", expression, "]" | ".", identifier } ;
ifStatement = "als", expression, block,
[ "anders", block ] ;
whileStatement = "zolang", expression, block ;
forStatement = "voor", identifier, "in", expression, block ;
functionDeclaration
= "functie", identifier,
"(", [ parameters ], ")", block ;
parameters = identifier, { ",", identifier }, [ "," ] ;
eventHandler = "wanneer", expression, block ;
returnStatement = "geef", [ expression ], lineEnd ;
commandCallStatement
= commandTarget, commandFirstArgument,
{ ",", expression }, [ "," ], lineEnd ;
commandTarget = identifier, { ".", identifier } ;
commandFirstArgument
= expression
(* eerste token: identifier, number, string, waar, onwaar,
geen, niet of "{" *) ;
expressionStatement
= expression, lineEnd ;
block = ":", newline, { newline }, INDENT,
statement, { newline | statement }, DEDENT ;
lineEnd = newline | &DEDENT | &EOF ;
expression = logicalOr ;
logicalOr = logicalAnd, { "of", logicalAnd } ;
logicalAnd = equality, { "en", equality } ;
equality = comparison, { ( "==" | "!=" ), comparison } ;
comparison = additive, { ( "<" | "<=" | ">" | ">=" ), additive } ;
additive = multiplicative, { ( "+" | "-" ), multiplicative } ;
multiplicative = unary, { ( "*" | "/" | "%" ), unary } ;
unary = ( "niet" | "+" | "-" ), unary | postfix ;
postfix = primary, { callSuffix | indexSuffix | memberSuffix } ;
callSuffix = "(", [ arguments ], ")" ;
arguments = expression, { ",", expression }, [ "," ] ;
indexSuffix = "[", expression, "]" ;
memberSuffix = ".", identifier ;
primary = number
| string
| "waar"
| "onwaar"
| "geen"
| identifier
| "(", expression, ")"
| listLiteral
| mapLiteral ;
listLiteral = "[", [ arguments ], "]" ;
mapLiteral = "{", [ mapEntry,
{ ",", mapEntry }, [ "," ] ], "}" ;
mapEntry = expression, ":", expression ;
&TOKEN vereist het volgende token zonder het te verbruiken. Het omvattende
blok of programma verwerkt uiteindelijk DEDENT of EOF.
De opdrachtvorm zonder haakjes heeft beperkingen aan het eerste argument;
zie paragraaf 5.4. De expressie na wanneer moet bovendien een toegestane
directe gebeurtenisbeschrijving zijn; zie paragraaf 5.9.
Gerelateerde lemma’s
Syntaxis en waarden · Ingebouwde functies · Programmeergidsen
