Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

10 parser design a context free grammar for boolean expressions #31

Merged
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
6d85633
Create parser/README.md
timoslater Jul 12, 2024
9a1ad12
Add parsing table and grammar to parser/README.md
timoslater Jul 12, 2024
218af0d
feat: add abstract syntax tree nodes
timoslater Jul 13, 2024
c90ff87
docs: add first and follow function table to README.md
timoslater Jul 13, 2024
f692a51
docs: add docstrings to AST node classes
timoslater Jul 14, 2024
f3c9773
style: rename term and Expr for clarity
timoslater Jul 14, 2024
54244fb
docs: change term and Expr names for clarity in README.md
timoslater Jul 14, 2024
8ae91fb
feat!: revise ast node classes
timoslater Jul 15, 2024
70c82d8
feat!: condense AndExpr, OrExpr, NotExpr, and ParenExpr, to terminal …
timoslater Jul 15, 2024
6520d6a
docs: replace AND, OR, and NOT, with &, | and !
timoslater Jul 15, 2024
5f9ab2f
docs: replace AND, OR, and NOT, with &, | and !
timoslater Jul 15, 2024
bb0994d
docs: convert Var to non-terminal
timoslater Jul 16, 2024
7750573
refactor: allow Expr to accept None for nullable ExprPrime
timoslater Jul 16, 2024
1e7972b
refactor: restore ParenExpr and remove parenthesis operators
timoslater Jul 16, 2024
b2fe0f7
refactor: restore AndExpr, OrExpr, NotExpr; inherit from Expr and/or …
timoslater Jul 16, 2024
60cee7d
docs: fix incorrect table and inaccurate EBNF title
timoslater Jul 16, 2024
91711f6
docs: fix table centering
timoslater Jul 16, 2024
b324dc4
refactor: add VarExpr, convert Expr and ExprPrime to parent classes/i…
timoslater Jul 17, 2024
9761b61
fix(nit): add small nit fixes
bliutech Jul 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions parser/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
### LL(1) Parsing Table

| | var | ( | ) | ! | & | \| | $ |
|-------|:-----------------:|:-------------:|:-:|:---------------:|:----------------:|:---------------:|:---------:|
| Expr | Expr → var Expr' | Expr → (Expr) | | Expr → NOT Expr | | | |
| Expr' | | | | | Expr' → & Expr | Expr' → \| Expr | Expr' → ϵ |

var = Variable \
Expr = Expression

### Backus-Naur Form
timoslater marked this conversation as resolved.
Show resolved Hide resolved
```
Expr ::= var Expr'
| ! Expr
| ( Expr )

Expr' ::= & Expr
| \| Expr
| ε

var ::= [A-Z]+
timoslater marked this conversation as resolved.
Show resolved Hide resolved
```

### First and Follow Function Table
| | FIRST | FOLLOW |
|-------|:------------:|:------:|
| Expr | var, !, ( | $, ) |
| Expr' | &, \|, ε | $ |
158 changes: 158 additions & 0 deletions parser/ast.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
from __future__ import annotations
from enum import Enum


class Operator(Enum):
"""
An enumeration class to represent each operation in a boolean expression.

Attributes
----------
value: str
the string value of each operator. The characters "&", "|", "!", "(", and ")" are allowed.
"""

def __str__(self) -> str:
return str(self.value)

And = "&"
Or = "|"
Not = "!"
ParenOpen = "("
ParenClose = ")"


class Var:
"""
A class to represent the terminal value labeled by the encoder.

...

Attributes
----------
name : str
the name given to the boolean variable by the encoder. name ::= [A-Z]+

"""

def __init__(self, name: str) -> None:
"""
Constructs all the necessary attributes for the Var object.

Parameters
----------
name : str
the name given to the boolean variable by the encoder. name ::= [A-Z]+
"""

self.name = name

def __str__(self) -> str:
return self.name


class Expr:
"""
A class to represent a boolean expression. Can contain up to 3 terminals or non-terminals.

...

Attributes
----------
first : Var | Operator
the first term of the expression. Can be a Var or Operator.

second: Expr | ExprPrime
the second term of the expression. Can be an Expr or ExprPrime.

third: Operator
the third term of the expression. Can only be the ParenClose Operator (default is None)
"""

def __init__(
self, first: Var | Operator, second: Expr | ExprPrime, third: Operator = None
timoslater marked this conversation as resolved.
Show resolved Hide resolved
) -> None:
timoslater marked this conversation as resolved.
Show resolved Hide resolved
"""
Constructs all the necessary attributes for the Expr object.

Parameters
----------
first : Var | Operator
the first term of the expression. Can be a Var or Operator.

second: Expr | ExprPrime
the second term of the expression. Can be an Expr or ExprPrime.

third: Operator
the third term of the expression. Can only be the ParenClose Operator (default is None).
"""
self.first = first
timoslater marked this conversation as resolved.
Show resolved Hide resolved
self.second = second
self.third = third

def __str__(self) -> str:
"""
The string format of the Expr class.

Returns in the format matching the number of terms of an expression.

Returns
-------
str
"""

if self.first == Operator.Not:
timoslater marked this conversation as resolved.
Show resolved Hide resolved
return f"{self.first}{self.second}"

if self.first == Operator.ParenOpen:
return f"{self.first}{self.second}{self.third}"

return f"{self.first} {self.second}"


class ExprPrime:
"""
An intermediary class for Expr to maintain LL(1) grammar

Both attributes support None to allow for node to empty as per the LL(1) grammar.

...

Attributes
----------
first : Operator | None
the first term of the expression. Can be Operator or None (default is None).

second: Expr | None
the second term of the expression. Can be an Expr or None (default is None).
"""

def __init__(self, first: Operator | None, second: Expr | None = None) -> None:
"""
Parameters
----------
first : Operator | None
timoslater marked this conversation as resolved.
Show resolved Hide resolved
the first term of the expression. Can be Operator or None (default is None).

second: Expr | None
the second term of the expression. Can be an Expr or None (default is None).
"""
self.first = first
self.second = second

def __str__(self) -> str:
"""
The string format of the Expr class.

Returns in the format matching the number of terms of an expression'.

Returns an empty string when both attributes are equal to None (ε/"").

Returns
-------
str
"""
if self.first is None:
return ""

return f"{self.first} {self.second}"
Loading