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 14 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
30 changes: 30 additions & 0 deletions parser/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
### LL(1) Parsing Table

| | [A-Z] | ( | ) | ! | & | \| | $ |
|-------|:-----------------:|:-------------:|:-:|:---------------:|:----------------:|:---------------:|:---------:|
| Expr | Expr → Var Expr' | Expr → (Expr) | | Expr → ! Expr | | | |
| Expr' | | | | | Expr' → & Expr | Expr' → \| Expr | Expr' → ϵ |
| Var | Var → [A-Z]+ | | | | | | |

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]+
```

### First and Follow Function Table
| | FIRST | FOLLOW |
|-------|:------------:|:------:|
| Expr | [A-Z]+, !, ( | $, ) |
| Expr' | &, \|, ε | $ |
timoslater marked this conversation as resolved.
Show resolved Hide resolved
| Var | [A-Z]+ | $, &, \||
171 changes: 171 additions & 0 deletions parser/ast.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
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 = "!"


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):
"""
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 | None
the second term of the expression. Can be an Expr, ExprPrime, or None. Can only be None when ExprPrime is nullable.
"""

def __init__(
self, first: Var | Operator, second: Expr | ExprPrime, third: Operator = 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.
"""
self.first = first
timoslater marked this conversation as resolved.
Show resolved Hide resolved
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
-------
str
"""

if self.second is None:
timoslater marked this conversation as resolved.
Show resolved Hide resolved
return str(self.first) # when ExprPrime is nullable

if self.first == Operator.Not:
return str(self.first) + str(self.second)

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
the operator for the expression'.

second: Expr
the expression that will have the operator applied to it.
"""

def __init__(self, first: Operator, second: Expr):
timoslater marked this conversation as resolved.
Show resolved Hide resolved
"""
Parameters
----------
first : Operator
the operator for the expression'.

second: Expr
the expression that will have the operator applied to it.
"""
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}"


class ParenExpr:
timoslater marked this conversation as resolved.
Show resolved Hide resolved
"""
A class to represent a parenthesized expression.
Attributes
----------
first : Expr
The inner expression within the parentheses
"""

def __init__(self, first: Expr):
"""
Parameters
----------
first : Expr
The inner expression within the parentheses
"""
self.first = first

def __str__(self) -> str:
return f"({self.first})"