Here is the PEGjs syntax for items. You can test it at https://pegjs.org/online (https://pegjs.org/online)
namespace prefix : "filename"
item id -> [ meta | data ]
item id -> relation type { slot1: item1, item2, ... ; slot2: item3; }
item id -> ( behavior node, ... , ... )
namespace / namespace / item id
sourceCode
= ns:namespace* id:itemDef* _ { return { namespaces:ns, definitions:id }; }
_
= [ \t\r\n]*
namespace
= _ ns:namespaceId _ ":" _ '"' fp:filepath '"' { return { namespace: ns, filepath: fp }; }
itemDef
= _ id:localItemId _ "->" _ iv:itemValue { return { item:id, value:iv }; }
namespaceId
= c:normalChar* { return c.join('').trim(); }
filepath
= c:[^"\t\r\n]* { return c.join('').trim(); }
itemValue
= metadata / relationship / behavior
localItemId
= c:normalChar+ { return c.join('').trim(); }
itemId
= fns:namespaceId nns:nextItemPath* {
var whole = [fns].concat(nns);
var id = whole.pop();
return { type:"item", id:id, path:whole };
}
nextItemPath
= "/" ns:namespaceId { return ns; }
metadata
= _ "[" meta:metadataContent+ "|" data:metadataContent+ "]" {
return { type:"meta/data", content: { meta:meta, data:data } };
}
relationship
= _ ri:relationshipId _ "{" _ sd:slotDef* _ "}" {
return { type:"relation", name:ri, content: sd };
}
behavior
= _ "(" fb:behaviorContent nb:nextBehaviorContent* ")" {
return { type:"behavior", content: [fb].concat(nb)};
}
metadataContent
= itemValue
/ textContent
textContent
= c:normalChar+ { return { type:"text", content: c.join('') }; }
relationshipId
= c:normalChar+ { return c.join('').trim(); }
slotDef
= _ si:slotId _ ":" _ fi:slotValue _ ni:nextSlotValue* _ ";" {
return { slot:si, value:[fi].concat(ni) };
}
behaviorContent
= itemValue / itemId
nextBehaviorContent
= _ "," _ b:behaviorContent { return b; }
slotId
= c:normalChar+ { return c.join('').trim(); }
slotValue
= itemId / itemValue
nextSlotValue
= _ "," _ v:slotValue { return v; }
normalChar
= c:[^\-\<\>\{\}\[\]\(\)\:\/\,\;\|\\] { return c; }
/ "-" c:[^>] { return "-"+c; }
/ "\\" c:. { return c; }
Back in black.