Parse more schema

This commit is contained in:
Emery Hemingway 2023-12-25 17:39:58 +02:00
parent 18f8f8e6b2
commit b165c64475
1 changed files with 43 additions and 32 deletions

View File

@ -63,13 +63,9 @@ proc match(text: string; p: var ParseState)
const parser = peg("Schema", p: ParseState):
S <- *{ ' ', '\t', '\r', '\n' }
Schema <- S * +Clause * !1
Schema <- +Clause * S * !1
Clause <- *LineComment * S * (Version | EmbeddedTypeName | Include | Definition) * S * '.'
LineComment <- S * '#' * @'\n'
Clause <- (Version | EmbeddedTypeName | Include | Definition | +LineComment) * S * '.' * S
Version <- "version" * S * >(*Digit):
if parseInt($1) != 1: fail()
@ -86,18 +82,19 @@ const parser = peg("Schema", p: ParseState):
match(readFile path, state)
p.schema = move state.schema
Definition <- >id * S * '=' * S * (OrPattern | AndPattern | Pattern):
Definition <- ?Annotation * *LineComment * id * '=' * S * (OrPattern | AndPattern | Pattern):
if p.schema.definitions.hasKey(Symbol $1):
raise newException(ValueError, "duplicate definition of " & $1)
raise newException(ValueError, "duplicate definition of " & $0)
var
node = popStack()
def: Definition
if not fromPreserve(def, node):
raise newException(ValueError, $1 & ": " & $node)
raise newException(ValueError, "failed to convert " & $1 & " to a Definition: " & $node)
p.schema.definitions[Symbol $1] = def
p.stack.setLen(0)
OrPattern <- ?('/' * S) * AltPattern * +(S * '/' * S * AltPattern):
OrDelim <- *LineComment * '/' * S * *LineComment
OrPattern <- ?OrDelim * AltPattern * +(S * OrDelim * AltPattern):
var node = initRecord(toSymbol("or"), toPreserve takeStackAt())
pushStack node
@ -107,11 +104,11 @@ const parser = peg("Schema", p: ParseState):
AltRef |
AltLiteralPattern
AltNamed <- '@' * >id * S * Pattern:
AltNamed <- atId * ?Annotation * Pattern:
var n = toPreserve @[toPreserve $1] & takeStackAt()
pushStack n
AltRecord <- '<' * >id * *(S * NamedPattern) * '>':
AltRecord <- '<' * id * *NamedPattern * '>':
var n = toPreserve @[
toPreserve $1,
initRecord(
@ -140,13 +137,13 @@ const parser = peg("Schema", p: ParseState):
initRecord(toSymbol"lit", parsePreserves $1)]
pushStack n
AndPattern <- ?('&' * S) * NamedPattern * +(S * '&' * S * NamedPattern):
AndPattern <- ?'&' * S * NamedPattern * +('&' * S * NamedPattern):
var node = initRecord(toSymbol("and"), toPreserve takeStackAt())
pushStack node
Pattern <- ?Annotation * (SimplePattern | CompoundPattern)
Pattern <- SimplePattern | CompoundPattern
SimplePattern <-
SimplePattern <- (
AnyPattern |
AtomKindPattern |
EmbeddedPattern |
@ -154,7 +151,7 @@ const parser = peg("Schema", p: ParseState):
SequenceOfPattern |
SetOfPattern |
DictOfPattern |
Ref
Ref ) * S
AnyPattern <- "any":
pushStack toSymbol"any"
@ -189,17 +186,17 @@ const parser = peg("Schema", p: ParseState):
LiteralPattern <- ('=' * >symbol) | ("<<lit>" * >Preserves.Value * ">") | >nonSymbolAtom:
pushStack initRecord(toSymbol"lit", parsePreserves($1))
SequenceOfPattern <- '[' * S * SimplePattern * S * "..." * S * ']':
SequenceOfPattern <- '[' * S * SimplePattern * "..." * S * ']':
var n = initRecord(toSymbol"seqof", popStack())
pushStack n
SetOfPattern <- "#{" * S * SimplePattern * S * '}':
SetOfPattern <- "#{" * S * SimplePattern * '}':
var n = initRecord(toSymbol"setof", popStack())
pushStack n
DictOfPattern <-
'{' *
S * SimplePattern * S * ':' * S * SimplePattern * S * "...:..." * S *
'{' * S *
?Annotation * SimplePattern * ':' * S * SimplePattern * "...:..." * S *
'}':
var
val = popStack()
@ -214,14 +211,15 @@ const parser = peg("Schema", p: ParseState):
var n = initRecord(toSymbol"ref", path, name)
pushStack n
CompoundPattern <-
CompoundPattern <- (
RecordPattern |
VariableRecordPattern |
TuplePattern |
VariableTuplePattern |
DictionaryPattern
DictionaryPattern ) * S
RecordPattern <-
("<<rec>" * S * NamedPattern * *(S * NamedPattern) * '>') |
("<<rec>" * S * NamedPattern * *NamedPattern * '>') |
('<' * >Value * *(S * NamedPattern) * '>'):
if capture.len == 2:
var n = initRecord(toSymbol"rec",
@ -232,20 +230,30 @@ const parser = peg("Schema", p: ParseState):
var n = initRecord(toSymbol"rec", takeStackAfter())
pushStack n
VariableRecordPattern <- '<' * >Value * S * *(NamedPattern) * "..." * S * '>':
var fields = takeStackAfter()
var tail = fields.pop
tail[1] = initRecord(toSymbol"seqof", tail[1])
var n = initRecord(
toSymbol"rec",
toSymbolLit $1,
initRecord(toSymbol"tuplePrefix", toPreserve fields, tail))
pushStack n
TuplePattern <-
'[' * S * *(NamedPattern * S) * ']':
'[' * S * *NamedPattern * ']':
var n = initRecord(toSymbol"tuple", toPreserve takeStackAfter())
pushStack n
VariableTuplePattern <-
'[' * S * *(NamedPattern * S) * ?(Pattern * S) * "..." * S * ']':
'[' * S * *NamedPattern * ?Pattern * "..." * S * ']':
var fields = takeStackAfter()
var tail = fields.pop
tail[1] = initRecord(toSymbol"seqof", tail[1])
var node = initRecord(toSymbol"tuplePrefix", toPreserve fields, tail)
pushStack node
DictionaryPattern <- '{' * S * *(>Value * S * ':' * S * NamedSimplePattern * ?',' * S) * '}':
DictionaryPattern <- '{' * *(S * >Value * S * ':' * S * NamedSimplePattern * ?',') * S * '}':
var dict = initDictionary(void)
for i in countDown(pred capture.len, 1):
let key = toSymbol capture[i].s
@ -253,19 +261,18 @@ const parser = peg("Schema", p: ParseState):
var n = initRecord(toSymbol"dict", dict)
pushStack n
NamedPattern <- ('@' * >id * S * SimplePattern) | Pattern:
NamedPattern <- ((atId * ?Annotation * SimplePattern) | Pattern):
if capture.len == 2:
var n = initRecord(toSymbol"named", toSymbol $1, popStack())
pushStack n
NamedSimplePattern <- ('@' * >id * S * SimplePattern) | SimplePattern:
NamedSimplePattern <- ((atId * ?Annotation * SimplePattern) | SimplePattern):
if capture.len == 2:
var n = initRecord(toSymbol"named", toSymbol $1, popStack())
pushStack n
id <- Alpha * *Alnum
Comment <- '#' * @'\n'
id <- >(Alpha * *Alnum) * S
atId <- ?Annotation * '@' * id
symbol <- Preserves.Symbol
@ -280,7 +287,11 @@ const parser = peg("Schema", p: ParseState):
Value <- Preserves.Value:
discard
Annotation <- S * '@' * Value
Annotation <- '@' * (Preserves.String | Preserves.Record) * S
S <- *{ ' ', '\t', '\r', '\n' }
LineComment <- '#' * @'\n' * S
proc match(text: string; p: var ParseState) =
let match = parser.match(text, p)