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:- 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 
expr1and thenexpr2. If it fails, matchexpr3and thenexpr4! [ expr1 expr2 expr3 ... ]:- Group some clauses. Allow to inverse priority.
 expr*:- Match expr zero or more times.
 expr+:- Match expr one or more times.
 expr?:- Try to match expr.
 !expr:- Negative lookahead. Fails if the next item in the input matches expr. Consumes no input.
 !!expr:- Positive lookahead. Fails if the next item in the input does not matches expr. Consumes no input.
 ~expr:- Complement of expr. Consumes one character if the next item in the input matches does not matches expr.
 ->expr:- Read until expr. Consumes N character until the next item in the input matches expr.
 A:- Call the rule 
A. 'a':- Read the character 
ain the input. "foo":- Read the text 
fooin the input. 'a'..'z':- Read the next character if its value is between 
aandz. expr:node:- Fetch the result of expr, create the variable 
nodeand bind the result to it. __scope__:node:- Create the variable 
node. This variable is attach to the scope of the rule. expr:>node:- Bind the result of the expr to the existing variable 
node. #hook_without_parameter:- Call a hook without parameter.
 #hook(p1, "p2", 3):- Call a hook with 
p1aspyrser.parsing.node.Node,"p2"asstr,3asint. @foo expr:- Apply the directive 
footo the expressionexpr. @foo(p1, "p2", 3) expr:- Apply the directive 
footo the expressionexprwith 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.ParserBasic 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???
- 
rules¶ 
- 
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
-