Exempel: Språket som består av satserna JAG VET, JAG TROR, DU VET
och DU TROR definieras av syntaxen
<Sats> ::= <Subj> <Pred>
<Subj> ::= JAG | DU
<Pred> ::= VET | TROR
I syntaxen ovan har vi tre omskrivningsregler.
Varje regel består av ett vänsterled med en icke-slutsymbol
(t ex <Sats>
ovan)
och ett högerled som talar om vad man kan ersätta vänsterledet med.
I högerledet får det förekomma både icke-slutsymboler och
slutsymboler (t ex JAG
i exemplet ovan).
Tecknet |
betyder eller.
Meningar av typen
JAG VET ATT DU TROR ATT JAG VET OCH JAG TROR ATT DU VET ATT JAG TROR
definieras nu så här:
<Mening> ::= <Sats> | <Sats><Konj><Mening> <Konj> ::= ATT | OCHMed hjälp av den rekursiva definitionen av Mening har vi plötsligt fått en syntax som beskriver en oändlig massa meningar!
Syntaxen för programspråk beskrivs ofta i BNF. Så här beskrivs Pythons tilldelningssatser i dokumentationen:
<assignment_stmt> ::= (<target_list> "=")+ <expression_list> <target_list> ::= <target> ("," <target>)* [","] <target> ::= <identifier> | "(" <target_list> ")" | "[" <target_list> "]" | <attributeref> | <subscription> | <slicing>
Man kan förstås beskriva syntaxen för BNF i BNF, och det ser ut så här:
<syntax> ::= <regel> | <regel> <syntax> <regel> ::= "<" <regelnamn> ">" "::=" <uttryck> <radslut> <uttryck> ::= <lista> | <lista> "|" <uttryck> <radslut> ::= <RETURTECKEN> | <radslut> <radslut> <lista> ::= <term> | <term> <lista> <term> ::= <slutsymbol> | "<" <regelnamn> ">" <slutsymbol> ::= '"' <text> '"' | "'" <text> "'"
källkod --> lexikal analys --> syntaxanalys --> semantisk analys --> --> kodgenerering --> målkod
lab6.pyc
).
Den första delen av sytaxanalysen, att kontrollera om ett program följer syntaxen kan göras med rekursiv medåkning eller med en stack.
readSats()
readSubj()
readPred()
readMening()
readKonj()
q.peek()
som vi har lagt till i klassen WordQueue.
När något strider mot syntaxen låter vi ett särfall skickas iväg.
Här följer ett program som undersöker om en mening följer vår syntax.
# Syntaxkontroll class Grammatikfel(Exception): pass def readMening(): readSats() if q.peek() == ".": q.get() else: readKonj() readMening() def readSats(): readSubj() readPred() def readSubj(): ordet = q.get() if ordet == "JAG": return if ordet == "DU": return raise Grammatikfel("Fel subjekt:" + ordet) def readPred(): ordet = q.get() if ordet == "TROR": return if ordet == "VET": return raise Grammatikfel("Fel predikat:" + ordet) def readKonj(): ordet = q.get() if ordet == "ATT": return if ordet == "OCH": return raise Grammatikfel("Fel konjunktion:" + ordet) def main(): q = WordQueue() mening = input("Skriv en mening:") mening = mening.split() for ordet in mening: q.put(ordet) try: readMening() print("Följer syntaxen!") except Grammatikfel as fel: print(fel, "före", end ="") while not q.isempty(): print(q.get(), end = "") print() main()
[
), lägg den på stacken.
]
), titta på stacken.
Om stacken är tom eller om den symbol som poppar ut inte matchar slutsymbolen
har vi ett syntaxfel.