| 236 | |
| 237 | |
| 238 | def grammar(): |
| 239 | # terminals ---------------------------------- |
| 240 | colon = Literal(":") |
| 241 | equal = Suppress("=") |
| 242 | slash = Suppress("/") |
| 243 | open_paren = Suppress("(") |
| 244 | close_paren = Suppress(")") |
| 245 | open_brace = Suppress("{") |
| 246 | close_brace = Suppress("}") |
| 247 | |
| 248 | # np:tagName --------------------------------- |
| 249 | nspfx = Word(alphas) |
| 250 | local_name = Word(alphanums) |
| 251 | tagname = Combine(nspfx + colon + local_name) |
| 252 | |
| 253 | # np:attr_name=attr_val ---------------------- |
| 254 | attr_name = Word(alphas + ":") |
| 255 | attr_val = Word(alphanums + " %-./:_") |
| 256 | attr_def = Group(attr_name + equal + attr_val) |
| 257 | attr_list = open_brace + delimitedList(attr_def) + close_brace |
| 258 | |
| 259 | text = dblQuotedString.setParseAction(removeQuotes) |
| 260 | |
| 261 | # w:jc{val=right} ---------------------------- |
| 262 | element = ( |
| 263 | tagname("tagname") |
| 264 | + Group(Optional(attr_list))("attr_list") |
| 265 | + Optional(text, default="")("text") |
| 266 | ).setParseAction(Element.from_token) |
| 267 | |
| 268 | child_node_list = Forward() |
| 269 | |
| 270 | node = Group( |
| 271 | element("element") + Group(Optional(slash + child_node_list))("child_node_list") |
| 272 | ).setParseAction(connect_node_children) |
| 273 | |
| 274 | child_node_list << (open_paren + delimitedList(node) + close_paren | node) |
| 275 | |
| 276 | root_node = ( |
| 277 | element("element") + Group(Optional(slash + child_node_list))("child_node_list") + stringEnd |
| 278 | ).setParseAction(connect_root_node_children) |
| 279 | |
| 280 | return root_node |
| 281 | |
| 282 | |
| 283 | root_node = grammar() |