OM INDENTERINGSKÄNSLIGHET ========================= Några projektspråk planeras att vara indenteringskänsliga, så att man måste skriva t.ex. WHILE (uttryck) Sats1 Sats2 Sats3 Sats-efter-while med en sats på varje rad och lika indentering för alla satser som ingår i while-loopen, dvs mer eller mindre som i Pythons hantering. Problemet har då varit hur man ska hantera det, t.ex. i grammatiken. En rad ur Pythons grammatik ser ut så här, där "suite" är en sekvens av satser: suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT Det finns alltså *ett* INDENT i regeln, men det innebär ändå ett krav på indentering av alla satser i suiten. Scannern/lexern håller reda på hur mycket varje rad indenteras. Om en rad är *mer* indenterad än senast genereras ett INDENT-token, om den är *mindre* indenterad genereras ett DEDENT-token. Om flera rader har samma indentering genereras alltså inget INDENT-token, och grammatikregeln fungerar. Så här beskrivs det i samband med Pythongrammatiken: "Before the first line of the file is read, a single zero is pushed on the stack; this will never be popped off again. The numbers pushed on the stack will always be strictly increasing from bottom to top. At the beginning of each logical line, the line's indentation level is compared to the top of the stack. If it is equal, nothing happens. If it is larger, it is pushed on the stack, and one INDENT token is generated. If it is smaller, it must be one of the numbers occurring on the stack; all numbers on the stack that are larger are popped off, and for each number popped off a DEDENT token is generated. At the end of the file, a DEDENT token is generated for each number remaining on the stack that is larger than zero." Det är självklart viktigt att definiera hur man räknar indentering. Det kan ju ligga en blandning av mellanslags- och tab-tecken i början av en rad, och t.ex. om koden är skriven i Emacs kan ju antal mellanslag som en tab motsvarar ha satts olika från gång till gång. GRAMMATIKREGLER =============== Apropå den där Pythongrammatikregeln: För att ni ska kunna överföra reglerna till parserns så måste ni skriva om ::= + som ::= | (alernativt ) OM DANGLING ELSE ================ Om man har en if-konstruktion utan tvång antingen på indentering eller på avslutande endif eller "}" så uppstår följande problem: if villkor1 then if villkor2 then sann2 else falsk; Är det villkor1-if:en eller villkor2-if:en som har en else-gren? I Pascal löstes problemet i löpande text till grammatiken, som beskrev att ett else som påträffas tillhör den innersta if:en som ännu saknsr else-gren, alltså i det här fallet villkor2-if:en. Ett annat sätt att lösa det är mha grammatikregler som t.ex.: ::= | ::= | else | ::= | else | Lätt modifierat efter http://www.parsifalsoft.com/ifelse.html . Se den webbsidan för diskussion kring lösningen.