Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
lfa:2024:lab04 [2024/10/27 23:24] cata_chiru |
lfa:2024:lab04 [2024/10/29 09:27] (current) cata_chiru |
||
---|---|---|---|
Line 62: | Line 62: | ||
crt_lst = list(set(lst)) | crt_lst = list(set(lst)) | ||
return sorted(crt_lst, key = lambda x: (len(x), x)) | return sorted(crt_lst, key = lambda x: (len(x), x)) | ||
+ | |||
# Global variable used to threshold the number of Star items | # Global variable used to threshold the number of Star items | ||
INNER_STAR_NO_ITEMS = 3 | INNER_STAR_NO_ITEMS = 3 | ||
+ | |||
class Regex: | class Regex: | ||
'''Base class for Regex ADT''' | '''Base class for Regex ADT''' | ||
+ | |||
def __str__(self) -> str: | def __str__(self) -> str: | ||
'''Returns the string representation of the regular expression''' | '''Returns the string representation of the regular expression''' | ||
pass | pass | ||
+ | |||
def gen(self) -> [str]: | def gen(self) -> [str]: | ||
'''Return a representative set of strings that the regular expression can generate''' | '''Return a representative set of strings that the regular expression can generate''' | ||
pass | pass | ||
+ | |||
+ | def __len__(self) -> str: | ||
+ | '''Returns the length of the regular expression''' | ||
+ | pass | ||
def eval_gen(self): | def eval_gen(self): | ||
'''Prints the set of strings that the regular expression can generate''' | '''Prints the set of strings that the regular expression can generate''' | ||
pass | pass | ||
+ | |||
# TODO 0: Implementati Clasa Void dupa blueprint-ul de mai sus | # TODO 0: Implementati Clasa Void dupa blueprint-ul de mai sus | ||
class Void(Regex): | class Void(Regex): | ||
'''Represents the empty regular expression''' | '''Represents the empty regular expression''' | ||
+ | |||
# Va returna Void ca string | # Va returna Void ca string | ||
def __str__(self) -> str: | def __str__(self) -> str: | ||
pass | pass | ||
+ | |||
# Va genera un obiect din Python corespunzatoar clasei void | # Va genera un obiect din Python corespunzatoar clasei void | ||
def gen(self) -> [str]: | def gen(self) -> [str]: | ||
pass | pass | ||
- | | + | |
+ | def __len__(self): | ||
+ | return 0 | ||
def eval_gen(self): | def eval_gen(self): | ||
print("Void generates nothing") | print("Void generates nothing") | ||
- | + | ||
+ | |||
# TODO 1: Implementati Clasa Epsilon-String (Empty) dupa blueprint-ul de mai sus | # TODO 1: Implementati Clasa Epsilon-String (Empty) dupa blueprint-ul de mai sus | ||
class Empty(Regex): | class Empty(Regex): | ||
'''Represents the empty string regular expression''' | '''Represents the empty string regular expression''' | ||
+ | |||
# Va returna Empty ca string | # Va returna Empty ca string | ||
def __str__(self) -> str: | def __str__(self) -> str: | ||
pass | pass | ||
+ | |||
# Va returna o lista corespunzatoare a ce stringuri produce sirul vid | # Va returna o lista corespunzatoare a ce stringuri produce sirul vid | ||
def gen(self) -> [str]: | def gen(self) -> [str]: | ||
pass | pass | ||
- | | + | |
+ | # Va returna lungimea corespunzatoare sirului vid | ||
+ | def __len__(self) -> int: | ||
+ | pass | ||
+ | |||
def eval_gen(self): | def eval_gen(self): | ||
- | print("Empty string generates ''.") | + | print(f"Empty string has length {len(self)} generates ''.") |
+ | |||
# TODO 2: Implementati functionalitatile necesare pentru Clasa Symbol dupa blueprint-ul de mai sus | # TODO 2: Implementati functionalitatile necesare pentru Clasa Symbol dupa blueprint-ul de mai sus | ||
class Symbol(Regex): | class Symbol(Regex): | ||
'''Represents a symbol in the regular expression''' | '''Represents a symbol in the regular expression''' | ||
+ | |||
def __init__(self, char: str): | def __init__(self, char: str): | ||
self.char = char | self.char = char | ||
+ | |||
# TODO 2: Completati metodele __str__ si gen pentru clasa Symbol | # TODO 2: Completati metodele __str__ si gen pentru clasa Symbol | ||
def __str__(self) -> str: | def __str__(self) -> str: | ||
pass | pass | ||
+ | |||
def gen(self) -> [str]: | def gen(self) -> [str]: | ||
pass | pass | ||
- | | + | |
+ | def __len__(self) -> int: | ||
+ | return 1 | ||
def eval_gen(self): | def eval_gen(self): | ||
self.gen() | self.gen() | ||
+ | |||
# Dorim sa pastram in atributul words al clasei curente stringurile generate cu gen(self) | # Dorim sa pastram in atributul words al clasei curente stringurile generate cu gen(self) | ||
- | return "Symbol {self.char} generates {self.words}" | + | return f"Symbol {self.char} has length {len(self)} generates {self.words}" |
+ | |||
# TODO 3: Implementati functionalitatile necesare pentru Clasa Union dupa blueprint-ul de mai sus | # TODO 3: Implementati functionalitatile necesare pentru Clasa Union dupa blueprint-ul de mai sus | ||
class Union(Regex): | class Union(Regex): | ||
Line 137: | Line 151: | ||
def __init__(self, *arg: [Regex]): | def __init__(self, *arg: [Regex]): | ||
self.components = arg | self.components = arg | ||
+ | |||
+ | # TODO 3: Completati metodele __str__, gen, __len__ si eval_gen pentru clasa Union | ||
- | # TODO 3: Completati metodele __str__, gen si eval_gen pentru clasa Union | + | # Hint: Look at the str.join method to create (expr1|expr2|...) |
def __str__(self) -> str: | def __str__(self) -> str: | ||
pass | pass | ||
+ | |||
def gen(self) -> [str]: | def gen(self) -> [str]: | ||
- | pass | + | pass |
- | | + | |
+ | # We will consider the len of a Union as the max length of its components | ||
+ | def __len__(self) -> int: | ||
+ | pass | ||
# Dupa modelul de la Symbol, vom dori ca urmatoarele eval sa implementeze | # Dupa modelul de la Symbol, vom dori ca urmatoarele eval sa implementeze | ||
- | # return "Class {varianta toString() a clasei) generates {self.words}" | + | # return "Class {varianta toString() a clasei) has length {len(self)} and generates {self.words}" |
def eval_gen(self) -> str: | def eval_gen(self) -> str: | ||
- | pass | + | pass |
+ | |||
# TODO 4: Implementati functionalitatile necesare pentru Clasa Concat dupa blueprint-ul de mai sus | # TODO 4: Implementati functionalitatile necesare pentru Clasa Concat dupa blueprint-ul de mai sus | ||
class Concat(Regex): | class Concat(Regex): | ||
'''Represents the concatenation of two regular expressions''' | '''Represents the concatenation of two regular expressions''' | ||
+ | |||
def __init__(self, *arg : [Regex]): | def __init__(self, *arg : [Regex]): | ||
self.components = arg | self.components = arg | ||
- | + | ||
- | # TODO 4: Completati metodele __str__, gen si eval_gen pentru clasa Concat | + | # TODO 4: Completati metodele __str__, gen, __len__ si eval_gen pentru clasa Concat |
def __str__(self) -> str: | def __str__(self) -> str: | ||
pass | pass | ||
+ | |||
def gen(self) -> [str]: | def gen(self) -> [str]: | ||
- | pass | + | pass |
- | + | ||
- | def eval_gen(self) -> str: | + | |
- | pass | + | |
+ | def __len__(self) -> int: | ||
+ | pass | ||
+ | |||
+ | def eval_gen(self) -> str: | ||
+ | pass | ||
+ | |||
# TODO 5: Implementati functionalitatile necesare pentru Clasa Star dupa blueprint-ul de mai sus | # TODO 5: Implementati functionalitatile necesare pentru Clasa Star dupa blueprint-ul de mai sus | ||
class Star(Regex): | class Star(Regex): | ||
Line 172: | Line 195: | ||
def __init__(self, regex: Regex): | def __init__(self, regex: Regex): | ||
self.regex = regex | self.regex = regex | ||
+ | |||
+ | # To memorize the base words generated by the regex inside the star, we store them in a list | ||
self.base_words = [""] | self.base_words = [""] | ||
- | self.base_gen() | ||
self.words = [] | self.words = [] | ||
- | + | ||
- | + | # TODO 5: Completati metodele __str__, gen, __len__, eval_gen pentru clasa Star | |
- | # TODO 5: Completati metodele __str__, gen, eval_gen pentru clasa Star | + | def __str__(self) -> str: |
- | def __str__(self): | + | pass |
+ | |||
+ | def gen(self, no_items = 10) -> [str]: | ||
pass | pass | ||
- | def base_gen(self): | + | # To ease your implementation we will consider a big number e.g. 1000000 as Infinity |
- | '''To memorize the base words generated by the regex inside the star, we store them in a list''' | + | def __len__(self) -> int: |
- | if type(self.regex) == Star: | + | pass |
- | # Implement Star.gen with a limiting threshold | + | |
+ | def eval_gen(self, no_items = 10): | ||
pass | pass | ||
- | + | ||
- | # Implement Regex.gen for the rest | + | |
- | pass | + | |
- | + | ||
- | + | ||
- | def gen(self, no_items = 10): | + | |
- | pass | + | |
- | + | ||
- | def eval_gen(self, no_items = 10): | + | |
- | pass | + | |
- | + | ||
if __name__ == "__main__": | if __name__ == "__main__": | ||
r1 = Symbol('a') | r1 = Symbol('a') | ||
Line 203: | Line 220: | ||
regex_union = Union(r1, r2) | regex_union = Union(r1, r2) | ||
regex_union.eval_gen() | regex_union.eval_gen() | ||
+ | |||
e2 = Union(Symbol('a'),Symbol('b'), Symbol('c')) | e2 = Union(Symbol('a'),Symbol('b'), Symbol('c')) | ||
e4 = Concat(r1, e2) | e4 = Concat(r1, e2) | ||
e4.eval_gen() | e4.eval_gen() | ||
- | | + | |
e5 = Concat(e2, e2, r2) | e5 = Concat(e2, e2, r2) | ||
e5.eval_gen() | e5.eval_gen() | ||
+ | |||
star_ex = Star(r1) | star_ex = Star(r1) | ||
star_ex.eval_gen() | star_ex.eval_gen() | ||
+ | |||
regex_concat = Concat(regex_union, star_ex) | regex_concat = Concat(regex_union, star_ex) | ||
regex_concat.eval_gen() | regex_concat.eval_gen() | ||
+ | |||
last_expr = Concat(Star(Union(Symbol('a'), Symbol('b'))), Symbol('b'), Star(Symbol('c'))) | last_expr = Concat(Star(Union(Symbol('a'), Symbol('b'))), Symbol('b'), Star(Symbol('c'))) | ||
last_expr.eval_gen() | last_expr.eval_gen() | ||
- | </code> | + | </code> |
| | ||
The output should be similar to: | The output should be similar to: | ||
<code> | <code> | ||
- | Union (a | b) generates ['a', 'b']. | + | Union (a | b) has length 1 and generates ['a', 'b']. |
- | Concat (a(a | b | c)) generates ['aa', 'ab', 'ac']. | + | Concat (a(a | b | c)) has length 2 and generates ['aa', 'ab', 'ac']. |
- | Concat ((a | b | c)(a | b | c)b) generates ['aab', 'abb', 'acb', 'bab', 'bbb', 'bcb', 'cab', 'cbb', 'ccb']. | + | Concat ((a | b | c)(a | b | c)b) has length 3 and generates ['aab', 'abb', 'acb', 'bab', 'bbb', 'bcb', 'cab', 'cbb', 'ccb']. |
- | Star (a*) generates ['', 'a', 'aa', 'aaa', 'aaaa', 'aaaaa', 'aaaaaa', 'aaaaaaa', 'aaaaaaaa', 'aaaaaaaaa', 'aaaaaaaaaa', '...']. | + | Star (a*) has length 10000000 generates ['', 'a', 'aa', 'aaa', 'aaaa', 'aaaaa', 'aaaaaa', 'aaaaaaa', 'aaaaaaaa', 'aaaaaaaaa', 'aaaaaaaaaa', '...']. |
- | Concat ((a | b)(a*)) generates ['a', 'b', 'aa', 'ba', 'aaa', 'baa', 'aaaa', 'baaa']. | + | Concat ((a | b)(a*)) has length 10000001 and generates ['a', 'b', 'aa', 'ba', 'aaa', 'baa', 'aaaa', 'baaa', '...']. |
- | Concat (((a | b)*)b(c*)) generates ['b', 'ab', 'bb', 'bc', 'aab', 'abb', 'abc', 'bab', 'bbb', 'bbc', 'bcc', 'aaab', 'aabb', 'aabc', 'abab', 'abbb', 'abbc', 'abcc', 'baab', 'babb', 'babc', 'bbab', 'bbbb', 'bbbc', 'bbcc', 'bccc', 'aaaab', 'aaabb', '...']. | + | Concat (((a | b)*)b(c*)) has length 20000001 and generates ['b', 'ab', 'bb', 'bc', 'aab', 'abb', 'abc', 'bab', 'bbb', 'bbc', 'bcc', 'aaab', 'aabb', 'aabc', 'abab', 'abbb', 'abbc', 'abcc', 'baab', 'babb', 'babc', 'bbab', 'bbbb', 'bbbc', 'bbcc', 'bccc', '...']. |
</code> | </code> |