Skip to content

Instantly share code, notes, and snippets.

@okayurisotto
Created February 2, 2024 11:47
Show Gist options
  • Save okayurisotto/af52789ce2abcbb2132b8bcfd7fd5e3f to your computer and use it in GitHub Desktop.
Save okayurisotto/af52789ce2abcbb2132b8bcfd7fd5e3f to your computer and use it in GitHub Desktop.
XML Peg (wip)
Document
= meta:XMLDecl? elements:Element* {
return { meta, elements }
}
XMLDecl
= tag:DeclarationTag Whitespace {
return tag;
}
DeclarationTag
= '<?xml' attributes:Attribute* Whitespace '?>' {
return attributes;
}
Element
= EmptyElemTag / NonEmptyElem
NonEmptyElem
= (startTag:STag contents:Content endTag:ETag {
if (startTag.name !== endTag.name) error();
if (startTag.namespace !== endTag.namespace) error();
return { type: "element", ...startTag, contents };
})
EmptyElemTag
= '<' namespace:NsPrefix? name:Name attributes:Attribute* Whitespace '/>' Whitespace {
return { type: "element", name, namespace, attributes, content: null };
}
STag
= '<' namespace:NsPrefix? name:Name attributes:Attribute* Whitespace '>' Whitespace {
return { name, namespace, attributes };
}
Content
= (Comment / CDSect / value:$[^<]+ { return { type: "text", value }; } / Element)*
ETag
= '</' namespace:NsPrefix? name:Name Whitespace '>' Whitespace {
return { name, namespace };
}
Attribute
= Whitespace namespace:NsPrefix? name:Name '=' value:AttValue {
return { name, namespace, value };
}
AttValue
= '"' value:$[^"]* '"' {
return value;
}
CDSect
= '<![CDATA[' value:$(!']]>' char:. { return char })* ']]>' Whitespace {
return { type: "cdata", value };
}
Comment
= '<!--' value:$(!'-->' char:. { return char })* '-->' Whitespace {
return { type: "comment", value };
}
Name
= $Letter+
NsPrefix
= namespace:$Letter+ ':' {
return namespace;
}
Letter
= [a-zA-Z]
Whitespace
= [ \t\r\n]*
@okayurisotto
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment