Commit 32993d06 authored by Paul Roberts's avatar Paul Roberts
Browse files

farighas tre rafinita nun!

parent c1fe5978
import streams, unicode, strukt
import streams, unicode, strukt, strutils
type
ParseError = object of ValueError
......@@ -65,6 +65,9 @@ proc nextToken(s: Stream): Tk =
return Tk(k: tkNumber, value: $c & s.readNumber())
else:
case $c
of "#":
while not s.atEnd() and s.readChar() != '\n': discard
continue
of "\"": return Tk(k: tkString, value: s.readString())
of "{": return Tk(k: tkOpenBr)
of "}": return Tk(k: tkCloseBr)
......@@ -85,6 +88,9 @@ proc accept(tk: var Tokeniser, k: TkKind): Tk =
else:
raise newException(ParseError, "expected " & $k & ", got: " & $tk.token.k)
proc acceptInt(tk: var Tokeniser): int =
tk.accept(tkNumber).value.parseInt
proc acceptStr(tk: var Tokeniser): string =
result = tk.accept(tkString).value
......@@ -92,39 +98,73 @@ proc acceptIdent(tk: var Tokeniser): string =
result = tk.accept(tkIdent).value
# template for a named object delimited by {}
template parseObject(body: untyped) =
result.nomo = tk.acceptIdent()
template parseObjectBody(body: untyped) =
discard tk.accept(tkOpenBr)
while true:
if tk.token.k == tkCloseBr:
tk.accept()
break
elif tk.token.k == tkEof:
raise newException(ParseError, "incomplete object (input ended before closing brace)")
body
proc parseAjho*(tk: var Tokeniser; ejo: var Ejo): Ajho =
result.loko = ejo.nomo
template parseObject(body: untyped) =
result.nomo = tk.acceptIdent()
parseObjectBody(body)
proc parseFenomeno(tk: var Tokeniser; ajho: Ajho): Fenomeno =
result.ajho = ajho.nomo
parseObjectBody:
let id = tk.acceptIdent()
case id
of "verbo":
result.verbo = tk.acceptStr()
of "mesaĝo":
result.mesagho = tk.acceptStr()
else:
raise newException(ValueError, "unexpected ajho id: " & id)
proc parseAjho(tk: var Tokeniser; ludo: var Ludo; loko: avtId): Ajho =
result.loko = loko
parseObject:
tk.accept()
let id = tk.acceptIdent()
case id
of "fenomeno":
ludo.fenomenoj.add parseFenomeno(tk, result)
of "priskribo":
result.priskribo = tk.acceptStr()
of "alinomo":
result.aliaj_nomoj.add tk.acceptStr()
of "fermebla":
result.atribuoj.incl(atrFermebla)
of "fermita":
result.atribuoj.incl(atrFermita)
of "enhavo":
result.enhavo = tk.acceptInt()
of "grando":
result.grando = tk.acceptInt()
of "pezo":
result.pezo = tk.acceptInt()
of "aĵo":
ludo.ajhoj.add tk.parseAjho(ludo, result.nomo)
else:
raise newException(ParseError, "unexpected identifier: " & id)
proc parseEjo(tk: var Tokeniser; ludo: var Ludo): Ejo =
parseObject:
case tk.token.k
of tkIdent:
case tk.token.value
of "priskribo":
tk.accept()
result.priskribo = tk.acceptStr()
of "norden":
tk.accept()
result.norden = tk.acceptIdent()
of "suden":
tk.accept()
result.suden = tk.acceptIdent()
of "aĵo":
tk.accept()
ludo.ajhoj.add tk.parseAjho(result)
else: tk.accept() # XXX error here
else: tk.accept() # XXX error here
let id = tk.acceptIdent()
case id
of "priskribo":
result.priskribo = tk.acceptStr()
of "norden":
result.norden = tk.acceptIdent()
of "suden":
result.suden = tk.acceptIdent()
of "elen":
result.elen = tk.acceptIdent()
of "aĵo":
ludo.ajhoj.add tk.parseAjho(ludo, result.nomo)
else: raise newException(ParseError, "bad identifier " & id)
proc parseLudo(tk: var Tokeniser): Ludo =
while true:
......@@ -157,62 +197,13 @@ proc parseLudo*(s: Stream): Ludo =
result = parseLudo(tk)
when isMainModule:
let s = """
nomo "La Kongreso"
aŭtoro "Neil Roberts"
jaro "2021"
enkonduko "
Vi vekiĝas konfuzite en la mallumo. Kie vi estas? Vi strebas funkciigi
vian cerbon kaj viaj memoroj malrapide revenas. Ho jes, vi partoprenas
la Internacian Junularan Kongreson. La lasta okazaĵo kiun vi memoras
estas ke vi babiladis kun interesa homo pri la gramatiko de la franca.
Vi volis klarigi interesan parton kaj vi diris ekzemplan frazon.
Subite malantaŭ vi, vi aŭdis viran voĉon krii «NE KROKODILU!». Vi
sentis fortan doloron sur la kapo, la mondo mallumiĝis kaj vi
senkonsciiĝis. Nun vi ŝajne troviĝas en malluma loko. Aĥ, via kapo
doloras.
"
ejo ŝranko {
priskribo "Vi estas en malgranda ŝranko kie oni stokas la purigilojn.
Ĉe la suda muro estas pordo por eliri."
suden koridoro
elen koridoro
aĵo malnova_balailo {
priskribo "Ĝi aspektas tre malnova kaj malpura."
fenomeno {
verbo "preni"
mesaĝo "La balailo estas tro granda por facile porti kaj vi preferas
lasi ĝin kie ĝi estas."
}
}
aĵo ilara_kesto {
alinomo "ilaro"
priskribo "Ĝi estas nigra plasta kesto por iloj."
fermebla
fermita
enhavo 50
grando 50 pezo 5
aĵo blua_ŝraŭbilo {
priskribo "Ĝi estas blua ŝraŭbilo kun plata pinto."
pezo 1 grando 1
fenomeno {
verbo "uzi"
mesaĝo "Mi ne scias kion vi volas fari per la $A. Eble vi
povas trovi pli precizan verbon."
}
}
}""".newStringStream
echo parseLudo(s)
var s = openFileStream("kongreso1.avt", fmRead)
try:
echo parseLudo(s)
except ParseError:
echo "parse error: ", getCurrentExceptionMsg()
finally:
s.close()
# while true:
# let t = s.nextToken()
# echo t
......
type
avtId = string
avtId* = string
Ejo* = object
nomo*: avtId
priskribo*: string
suden*, norden*, orienten*, okcidenten*: avtId
elen*: avtId
AjhoAtribuo* = enum atrFermebla, atrFermita
Ajho* = object
nomo*: avtId
loko*: avtId
aliaj_nomoj*: seq[avtId]
priskribo*: string
atribuoj*: set[AjhoAtribuo]
enhavo*, grando*, pezo*: int
Fenomeno* = object
ajho*: avtId
verbo*: string
mesagho*: string
Ludo* = object
nomo*, autoro*, jaro*: string
enkonduko*: string
ejoj*: seq[Ejo]
ajhoj*: seq[Ajho]
fenomenoj*: seq[Fenomeno]
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment