1
1
from tatsu .model import NodeWalker
2
- from typing import Iterable , Optional , Tuple
2
+ from typing import Iterable , Optional , Tuple , List
3
3
4
4
from textworld .textgen .model import TextGrammarModelBuilderSemantics
5
5
from textworld .textgen .parser import TextGrammarParser
@@ -18,32 +18,75 @@ def full_form(self, include_adj=True) -> str:
18
18
return adj + "|" + noun
19
19
20
20
21
- class LiteralAlternative ( Alternative ) :
21
+ class LiteralChunk :
22
22
"""
23
- An alternative from a literal string.
23
+ It creates an object with a [str] value for every single literal.
24
+ literal is defined as any string which is not a symbol, i.e. it is not bounded by hashtags.
24
25
"""
26
+ def __init__ (self , value : str ):
27
+ self ._value = value
28
+
25
29
26
- def __init__ (self , value : str ):
30
+ class SymbolChunk :
31
+ """
32
+ It creates an object with a [str] value for every single symbol.
33
+ symbol is defined as any string in between two consecutive hashtags, e.g. #it_is_a_symbol#.
34
+ """
35
+ def __init__ (self , value : str ):
27
36
self ._value = value
28
37
38
+
39
+ class LiteralAlternative (Alternative ):
40
+ """
41
+ An alternative from a literal string and represents it as a chunk of literal and symbol objects.
42
+ """
43
+ def __init__ (self , node : str ):
44
+ self ._node = node
45
+ # self._val_chunk contains the objects which make the string.
46
+ # It is equivalent to self._value in LiteralAlternative.
47
+ self ._val_chunk = self ._symbol_finder (self ._node )
48
+
49
+ def _symbol_finder (self , node ):
50
+ self .chunks = []
51
+ while node :
52
+ is_has_tag = [i for i , ltr in enumerate (node ) if ltr == '#' ]
53
+ if is_has_tag :
54
+ if node [:is_has_tag [0 ]]:
55
+ self .chunks .append (LiteralChunk (node [:is_has_tag [0 ]]))
56
+ self .chunks .append (SymbolChunk (node [is_has_tag [0 ]:is_has_tag [1 ] + 1 ]))
57
+ else :
58
+ self .chunks .append (SymbolChunk (node [is_has_tag [0 ]:is_has_tag [1 ] + 1 ]))
59
+
60
+ node = node [is_has_tag [1 ] + 1 :]
61
+ else :
62
+ if node :
63
+ self .chunks .append (LiteralChunk (node ))
64
+ break
65
+ return self .chunks
66
+
29
67
def split_form (self , include_adj = True ) -> Tuple [Optional [str ], str ]:
30
- return None , self ._value
68
+ return None , self ._node
31
69
32
70
33
- class AdjectiveNounAlternative (Alternative ):
71
+ class AdjectiveNounAlternative (LiteralAlternative ):
34
72
"""
35
73
An alternative that specifies an adjective and a noun.
36
74
"""
37
75
38
- def __init__ (self , adjective : str , noun : str ):
39
- self ._adjective = adjective
40
- self ._noun = noun
76
+ def __init__ (self , adj_node : str , n_node : str ):
77
+ self ._adj_node = adj_node
78
+ self ._n_node = n_node
79
+ # self._adj_chunk contains the objects which make the adjective string.
80
+ # self._noun_chunk contains the objects which make the noun string.
81
+ # These are equivalent to self._adjective and self._noun in AdjectiveNounAlternative.
82
+ self ._adj_chunk = self ._symbol_finder (self ._adj_node )
83
+ self ._noun_chunk = self ._symbol_finder (self ._n_node )
41
84
42
85
def split_form (self , include_adj = True ) -> Tuple [Optional [str ], str ]:
43
86
if include_adj :
44
- return self ._adjective , self ._noun
87
+ return self ._adj_node , self ._n_node
45
88
else :
46
- return None , self ._noun
89
+ return None , self ._n_node
47
90
48
91
49
92
class MatchAlternative (Alternative ):
@@ -70,6 +113,7 @@ def __init__(self, symbol: str, alternatives: Iterable[Alternative]):
70
113
71
114
72
115
class _Converter (NodeWalker ):
116
+
73
117
def walk_list (self , node ):
74
118
return [self .walk (child ) for child in node ]
75
119
0 commit comments