Writing a BNF grammar

BNF Syntax

Pyrser use the following DSL to describe a grammar.

R = [ expr1 expr2 ... ]:
Define a rule named R as a sequence of clauses defined by expr. [] are mandatory at this level.
expr is one of the following statements.
expr1 expr2:
Match expr1, and then match expr2 if it succeeds. Like python’s and.
expr1 | expr2:
Try to match expr1. If it fails, match expr2 instead. Like python’s or.
expr1 expr2 | expr3 expr4 :
Try to match expr1 and then expr2. If it fails, match expr3 and then expr4!
[ expr1 expr2 expr3 ... ]:
Group some clauses. Allow to inverse priority.
Match expr zero or more times.
Match expr one or more times.
Try to match expr.
Negative lookahead. Fails if the next item in the input matches expr. Consumes no input.
Positive lookahead. Fails if the next item in the input does not matches expr. Consumes no input.
Complement of expr. Consumes one character if the next item in the input matches does not matches expr.
Read until expr. Consumes N character until the next item in the input matches expr.
Call the rule A.
Read the character a in the input.
Read the text foo in the input.
Read the next character if its value is between a and z.
Fetch the result of expr, create the variable node and bind the result to it.
Create the variable node. This variable is attach to the scope of the rule.
Bind the result of the expr to the existing variable node.
Call a hook without parameter.
#hook(p1, "p2", 3):
Call a hook with p1 as pyrser.parsing.node.Node, "p2" as str, 3 as int.
@foo expr:
Apply the directive foo to the expression expr.
@foo(p1, "p2", 3) expr:
Apply the directive foo to the expression expr with parameter to the directive (as hooks).

Note: expr is compose of all basics expression except for pipe (|) operator.

Python API: class EBNF

class pyrser.dsl.EBNF(content='', sname=None)[source]

Bases: pyrser.parsing.base.Parser

Basic class for BNF DSL PARSING.

A full parser for the BNF is provided by this class. We construct a tree to represents, thru functors, BNF semantics.

get_rules(self) → Node[source]

Parse the DSL and provide a dictionnaries of all resulting rules. Call by the MetaGrammar class.

TODO: could be done in the rules property of parsing.BasicParser???

__init__(self, content= '', sname= None)[source]

Define the DSL parser.

add_0N(self, repeat)

Create a tree.Rep0N

add_1N(self, repeat)

Create a tree.Rep1N

add_alt(self, alternatives, alt) → bool

Create a tree.Alt

add_bind(self, sequence, cpt)

Create a tree.Bind

add_capture(self, sequence, cpt)

Create a tree.Capture

add_char(self, sequence, c)

Add a read_char primitive

add_directive(self, sequence, d, s)

Add a directive in the sequence

add_directive2(self, sequence, d, s)

Add a directive in the sequence

add_hook(self, sequence, h)

Create a tree.Hook

add_mod(self, seq, mod)

Create a tree.{Complement, LookAhead, Neg, Until}

add_optional(self, repeat)

Create a tree.RepOptional

add_range(self, sequence, begin, end)

Add a read_range primitive

add_rpt(self, sequence, mod, pt)

Add a repeater to the previous sequence

add_rule(self, rule, rn, alts) → bool

Add the rule name

add_ruleclause_name(self, ns_name, rid) → bool

Create a tree.Rule

add_rules(self, bnf, r) → bool

Attach a parser tree to the dict of rules

add_sequences(self, sequences, cla) → bool

Create a tree.Seq

add_subsequence(self, sequence, subsequence)

Add a subsequence into a sequence

add_text(self, sequence, txt)

Add a read_text primitive

hook_name(self, hook, n)

Parse a hook name

hook_param(self, hook, p)

Parse a hook parameter

param_char(self, param, c)

Parse a char in parameter list

param_id(self, param, i)

Parse a node name in parameter list

param_num(self, param, n)

Parse a int in parameter list

param_str(self, param, s)

Parse a str in parameter list