DCFG
- class neologism.DCFG[source]
A class that represents dynamically modifiable context-free grammar.
The API uses
strfor symbols andRulefor rules.The grammar object. Build one from rules directly, or load one from a bison yacc file via
from_yacc_file(). Mutate it freely; thesentencesview always reflects the current state.Construction
- classmethod from_yacc_file(file_path: str | PathLike[str], bison_path: str | None = None) DCFG[source]
Construct a
DCFGby loading rules from a bison-style yacc file.Bison-specific cleanup is applied: the
$endterminal is removed andstart_symbolis set to$accept.Note
This function needs
bisonto be installed and onPATH(or located viabison_path).- Parameters:
file_path (str | os.PathLike[str]) – The path of the yacc file.
bison_path (str | None) – Optional
PATHoverride used to locatebison.
- Raises:
ChildProcessError – If
bisonis not available on the system.YaccDecodeError – If
bisonfails to parse the yacc file.
Rules
- property rules: Set[Rule]
-
See also
>>> dcfg = DCFG() >>> dcfg.add_rule(Rule("a", ("b", "c", "d"))) >>> dcfg.add_rule(Rule("c", ("x", "y", "z"))) >>> sorted(dcfg.rules, key=repr) [Rule('a' => 'b' 'c' 'd'), Rule('c' => 'x' 'y' 'z')]
- rules_containing(symbol: str) Set[Rule][source]
Can be used to filter rules, that contain the given symbol (terminal or nonterminal).
- Parameters:
symbol (str) – The symbol, which the rules are filtered by.
- Returns:
The rules, that define the grammar and contain the given symbol.
- Return type:
See also
>>> dcfg = DCFG() >>> dcfg.add_rule(Rule("a", ("b", "c", "d"))) >>> dcfg.add_rule(Rule("c", ("x", "y", "z"))) >>> sorted(dcfg.rules_containing("d"), key=repr) [Rule('a' => 'b' 'c' 'd')] >>> sorted(dcfg.rules_containing("c"), key=repr) [Rule('a' => 'b' 'c' 'd'), Rule('c' => 'x' 'y' 'z')]
- add_rule(rule: Rule) None[source]
Add a new rule to the grammar.
Note
The symbols in the rule will be automatically added if they are not already in the grammar.
- Parameters:
rule (Rule) – The new rule to add.
>>> dcfg = DCFG() >>> dcfg.add_rule(Rule("a", ("b", "c", "d"))) >>> dcfg.add_rule(Rule("c", ("x", "y", "z"))) >>> sorted(dcfg.rules, key=repr) [Rule('a' => 'b' 'c' 'd'), Rule('c' => 'x' 'y' 'z')]
- remove_rule(rule: Rule) None[source]
Remove a rule from the grammar.
Note
If there are symbols that are not used by any rule after the removal, they are removed.
- Parameters:
rule (Rule) – The rule to remove.
- Raises:
ValueError – If
ruleis not in the rules of the grammar.
>>> dcfg = DCFG() >>> dcfg.add_rule(Rule("a", ("b", "c", "d"))) >>> dcfg.add_rule(Rule("c", ("x", "y", "z"))) >>> sorted(dcfg.rules, key=repr) [Rule('a' => 'b' 'c' 'd'), Rule('c' => 'x' 'y' 'z')] >>> sorted(dcfg.symbols) ['a', 'b', 'c', 'd', 'x', 'y', 'z'] >>> dcfg.remove_rule(Rule("c", ("x", "y", "z"))) >>> sorted(dcfg.rules, key=repr) [Rule('a' => 'b' 'c' 'd')] >>> sorted(dcfg.symbols) ['a', 'b', 'c', 'd']
Symbols
- property symbols: Set[str]
-
See also
>>> dcfg = DCFG() >>> dcfg.add_rule(Rule("a", ("b", "c", "d"))) >>> dcfg.add_rule(Rule("c", ("x", "y", "z"))) >>> sorted(dcfg.symbols) ['a', 'b', 'c', 'd', 'x', 'y', 'z']
- property terminals: Set[str]
-
Note
It is possible for a terminal to not be used by any of the rules.
>>> dcfg = DCFG() >>> dcfg.add_rule(Rule("a", ("b", "c", "d"))) >>> dcfg.add_rule(Rule("c", ("x", "y", "z"))) >>> dcfg.add_rule(Rule("c", ("1", "2", "3"))) >>> sorted(dcfg.terminals) ['1', '2', '3', 'b', 'd', 'x', 'y', 'z']
- property nonterminals: Set[str]
-
Note
It is possible for a nonterminal to not be used by any of the rules.
See also
symbols,terminals,is_symbol_terminal(),make_symbol_terminal()>>> dcfg = DCFG() >>> dcfg.add_rule(Rule("a", ("b", "c", "d"))) >>> dcfg.add_rule(Rule("c", ("x", "y", "z"))) >>> dcfg.add_rule(Rule("c", ("1", "2", "3"))) >>> sorted(dcfg.nonterminals) ['a', 'c']
- is_symbol_terminal(symbol: str) bool[source]
Checks whether a symbol is terminal in the grammar.
- Parameters:
symbol (str) – The symbol to check.
- Raises:
ValueError – If
symbolwas not in the grammar.
See also
>>> dcfg = DCFG() >>> dcfg.add_rule(Rule("a", ("b", "c", "d"))) >>> dcfg.add_rule(Rule("c", ("x", "y", "z"))) >>> sorted(dcfg.terminals) ['b', 'd', 'x', 'y', 'z'] >>> sorted(dcfg.nonterminals) ['a', 'c'] >>> dcfg.is_symbol_terminal("a") False >>> dcfg.is_symbol_terminal("b") True
- make_symbol_terminal(symbol: str) None[source]
Make a symbol terminal in the grammar.
- Parameters:
symbol (str) – The symbol to be made terminal.
- Raises:
ValueError – If
symbolwas not in the grammar.
See also
>>> dcfg = DCFG() >>> dcfg.add_rule(Rule("a", ("b", "c", "d"))) >>> dcfg.add_rule(Rule("c", ("x", "y", "z"))) >>> sorted(dcfg.rules, key=repr) [Rule('a' => 'b' 'c' 'd'), Rule('c' => 'x' 'y' 'z')] >>> sorted(dcfg.symbols) ['a', 'b', 'c', 'd', 'x', 'y', 'z'] >>> dcfg.make_symbol_terminal("c") >>> sorted(dcfg.rules, key=repr) [Rule('a' => 'b' 'c' 'd')] >>> sorted(dcfg.symbols) ['a', 'b', 'c', 'd']
- remove_symbol(symbol: str) None[source]
Removes a symbol from the grammar.
- Parameters:
symbol (str) – Symbol to remove.
- Raises:
ValueError – If
symbolwas not in the grammar.
Note
If
symbolwas used by a rule in the grammar, it will be removed from the rule, too.Note
If
symbolwas a nonterminal, the rules which havesymbolas theirlhsare also removed.Note
If there are symbols that are not used by any rule after the removal, they are removed.
See also
>>> dcfg = DCFG() >>> dcfg.add_rule(Rule("a", ("b", "c", "d"))) >>> sorted(dcfg.rules, key=repr) [Rule('a' => 'b' 'c' 'd')] >>> sorted(dcfg.symbols) ['a', 'b', 'c', 'd'] >>> dcfg.remove_symbol("c") >>> sorted(dcfg.rules, key=repr) [Rule('a' => 'b' 'd')] >>> sorted(dcfg.symbols) ['a', 'b', 'd']
Start symbol
- property start_symbol: str
- Getter:
Returns the start symbol.
- Setter:
Sets the start symbol.
- Type:
Note
If it is not explicitly set, the first added rule’s
lhsis used.- Raises:
ValueError – (setter only) If the new start symbol is not in the grammar.
See also
>>> dcfg = DCFG() >>> dcfg.add_rule(Rule("a", ("b",))) >>> dcfg.add_rule(Rule("c", ("d",))) >>> dcfg.start_symbol 'a' >>> dcfg.start_symbol = "c" >>> dcfg.start_symbol 'c'
Sentence enumeration
- property sentences: Set[Tuple[str, ...]]
- Getter:
Returns all possible sentences of the grammar, starting with
start_symbol.- Type:
Note
If the grammar is not finite, sentences are generated from a copy of the grammar, which has been made finite.
See also
>>> dcfg = DCFG() >>> dcfg.add_rule(Rule("a", ("b", "c", "d"))) >>> dcfg.add_rule(Rule("c", ("x", "y", "z"))) >>> dcfg.add_rule(Rule("c", ("1", "2", "3"))) >>> sorted(dcfg.sentences) [('b', '1', '2', '3', 'd'), ('b', 'x', 'y', 'z', 'd')]
- iter_sentences() Iterator[Tuple[str, ...]][source]
Yields all possible sentences of the grammar one at a time, starting with
start_symbol.Note
If the grammar is not finite, sentences are generated from a copy of the grammar, which has been made finite.
Note
Unlike
sentences, the stream is not deduplicated. Ambiguous grammars may yield the same sentence more than once. Wrap insetif uniqueness matters.See also
>>> dcfg = DCFG() >>> dcfg.add_rule(Rule("a", ("b", "c", "d"))) >>> dcfg.add_rule(Rule("c", ("x", "y", "z"))) >>> dcfg.add_rule(Rule("c", ("1", "2", "3"))) >>> sorted(dcfg.iter_sentences()) [('b', '1', '2', '3', 'd'), ('b', 'x', 'y', 'z', 'd')]