Update README.
Chris Pressey
2 years ago
5 | 5 | efficient parsing _and_ efficient generation of strings conforming to those |
6 | 6 | languages. |
7 | 7 | |
8 | It does this by allowing semantic actions to be inserted between the | |
9 | elements of a production rule. Unlike the imperative semantic actions in a | |
10 | typical parser-generator (such as `yacc`) however, these actions are | |
11 | _relational_, and are also called _constraints_. This situates Fountain | |
12 | closer to the Definite Clause Grammars (DCGs) or Attribute Grammars (AGs). | |
13 | ||
14 | To support efficient generation, the interspersed semantic actions | |
15 | are analyzed to determine a plausible deterministic strategy for generation. | |
8 | It does this by allowing semantic constraints to be inserted between the | |
9 | elements of a production rule. To support efficient generation, these | |
10 | interspersed semantic constraints can be analyzed to determine a usable | |
11 | deterministic strategy for generation. | |
16 | 12 | |
17 | 13 | Here is an example Fountain grammar which expresses the classic CSL |
18 | 14 | `a`^_n_ `b`^_n_ `c`^_n_: |
34 | 30 | Success |
35 | 31 | |
36 | 32 | In comparison, during generation, we assume the variable `n` has |
37 | already been assigned a value, as part of the input to the generation | |
38 | process (which may be externally supplied, and generated randomly). | |
33 | already been assigned a value, as part of the (externally supplied) | |
34 | input to the generation process. | |
39 | 35 | In addition, the repetition construct `{ "a" <. a += 1 .> }` can "see" |
40 | 36 | the `a = n` constraint that follows it; it will be checked on each |
41 | 37 | iteration, and the repetition will terminate when it is true. |
44 | 40 | aaaaabbbbbccccc |
45 | 41 | |
46 | 42 | Neither of the above processes involve backtracking; the string |
47 | is parsed or generated in linear time. However, it is important to note | |
48 | that, while Fountain supports deterministic operation, it does not enforce it. | |
43 | is parsed and generated in linear time. Note, however, that while | |
44 | Fountain supports deterministic operation, it does not enforce it. | |
49 | 45 | It is possible to write Fountain grammars that lead to backtracking |
50 | 46 | search, or even infinite loops during generation. How best to handle |
51 | 47 | these cases remains an open line of inquiry. |
92 | 88 | ### To think about |
93 | 89 | |
94 | 90 | * When parameters are declared, do we also want to declare their types? |
95 | * Will we want productions to have arguments and how would that work? | |
96 | 91 | * Will we want variables of string type? |
97 | 92 | * Will we want variables of "string produced by a certain production" type? |
98 | 93 | * What other types might we want? Lists and maps and sets seem likely. |
106 | 101 | The key here is that we must also be able to parse what we've |
107 | 102 | pseudo-randomly generated. But, another major consideration is that |
108 | 103 | we don't _really_ want to thread this state through explicitly. We'd |
109 | like it to be a bit tidier than that. | |
104 | like it to be a bit tidier than that. Actually, this is a significant | |
105 | design space unto itself (e.g. can we use alternation to perform | |
106 | random choice without compromising efficiency?) so it probably | |
107 | deserves an writeup in the design document. | |
110 | 108 | * Write the "kennel story" generator in Fountain. Show that |
111 | 109 | it can parse the same story it generated, in a reasonable |
112 | 110 | time, even up to 50,000 words. |