Revision | f4b3918f3419cf36e1627d4212ca3d1cc96d64bf (tree) |
---|---|
Time | 2023-05-23 04:19:49 |
Author | Albert Mietus < albert AT mietus DOT nl > |
Commiter | Albert Mietus < albert AT mietus DOT nl > |
Grammerly
@@ -11,8 +11,8 @@ | ||
11 | 11 | :category: Castle, Usage |
12 | 12 | :tags: Castle, Grammar |
13 | 13 | |
14 | - In Castle, you can define *grammar*(s) directly in your code. The compiler will *translate* them into functions, using | |
15 | - the build-in (PEG) **compiler-compiler** -- at least that was it called back in the days of *YACC*. | |
14 | + In Castle, you can define *grammar(s)* directly in your code. A Castle compiler will **translate** them into | |
15 | + functions, using the build-in (PEG) *compiler-compiler* -- at least that was it called back in the days of *YACC*. | |
16 | 16 | |
17 | 17 | How does one *use* that? And *why* should you? |
18 | 18 |
@@ -20,8 +20,8 @@ | ||
20 | 20 | Grammars, a short intro |
21 | 21 | ======================= |
22 | 22 | |
23 | -A grammar is a collection of (parsing)-**rules** and optionally some *settings*. Rules are written in a mixture of EBNF | |
24 | -and PEG meta-syntax. Let’s start with a simple example: | |
23 | +A grammar is a collection of (parsing)-**rules** and some optional *settings*. Let us start with a simple example with | |
24 | +some rules written in a mixture of EBNF and PEG meta-syntax. | |
25 | 25 | |
26 | 26 | .. code-block:: PEG |
27 | 27 |
@@ -42,7 +42,7 @@ | ||
42 | 42 | programming. Some terminals are like constants like the semicolon at the end of ``import_line``, therefore they are |
43 | 43 | quoted in the grammar (Notice, the is also a non-quoted semicolon on each line, which is part of the syntax of grammar.) |
44 | 44 | |BR| |
45 | -Other terminals are more like valuables, they have a value. The ``STRING_literal`` is a good example. Its value is the | |
45 | +Other terminals are more like variables, they have a value. The ``STRING_literal`` is a good example. Its value is the | |
46 | 46 | string itself. Similar for numbers and variable names. |
47 | 47 | |
48 | 48 | In this (example) grammar, a ``qualID`` is a ``nameID`` *(a name that is used as ID, like in any programming language)*, |
@@ -52,7 +52,7 @@ | ||
52 | 52 | |
53 | 53 | A grammar defines how one (aka the compiler) should read the input --a text--, or more formally: how to parse it. The |
54 | 54 | result of this parsing is twofold. It will check whether the input conforms to the grammar; resulting in a boolean, for |
55 | -the mathematics under us. And it will translate a sequential (flat) text into a tree-structure; which is typically much | |
55 | +the mathematics under us. And it will translate a sequential (flat) text into a tree structure; which is typically much | |
56 | 56 | more useful for a software engineer. |
57 | 57 | |BR| |
58 | 58 |
@@ -80,25 +80,25 @@ | ||
80 | 80 | Non-parsing |
81 | 81 | ----------- |
82 | 82 | |
83 | -As writing a proper-passer used to be (too) hard, other similar (but simpler) techniques are often used, like `globing | |
83 | +As writing a proper parser used to be (too) hard, other similar (but more simple) techniques are often used, like `globing | |
84 | 84 | <https://en.wikipedia.org/wiki/Glob_(programming)>`__ *(``\*.Castle`` on the bash-prompt will result in all |
85 | -Castle-files)*. This is simple and will do in very simple cases. | |
85 | +Castle-files)*. It is elementary and will do in simple cases. | |
86 | 86 | |BR| |
87 | 87 | Others try to use `regular expressions <https://en.wikipedia.org/wiki/Regular_expression>`__ for parsing. RegExps are |
88 | -indeed more powerful than globing and are often used to highlight code. A pattern as ``//.*$`` can be used to highlight | |
88 | +indeed more powerful than globing. They are often used to highlight code. A pattern as ``//.*$`` can be used to highlight | |
89 | 89 | (single-line) comments. It often works, but this simple pattern might match a piece of text *inside* a |
90 | 90 | multi-line-(doc)string -- which is wrong. |
91 | 91 | |
92 | 92 | Those *tricks* aren’t a sound solution to parse generic input/text; although I have seen cunning RegExps that almost |
93 | 93 | (always) work. *Regular expressions* do have not the same power as grammars; that is already proven half a century |
94 | -ago and not repeated here. | |
94 | +ago and is not repeated here. | |
95 | 95 | |
96 | 96 | Grammars are more powerful |
97 | 97 | ========================== |
98 | 98 | |
99 | -A grammar (even a simple one) is more powerful. You can define the overall structure of the input and the sub-structure | |
100 | -of each *lump*. When a multi-line-string has no sub-structure, the parser will never find comments inside it. Nor the other | |
101 | -way around; it simply is not hunting for it. | |
99 | +A grammar (even a simple one) is more powerful. You can define the (input) structure hierarchically. And specify the | |
100 | +sub-structure of each *lump*. For example: when a multi-line-string has no sub-structure, the parser will never find | |
101 | +a statement inside it; it simply is not hunting for it. | |
102 | 102 | |
103 | 103 | As most programming languages do not have built-in support for grammars, one has to resort to external tools. Like the |
104 | 104 | famous `YACC <https://en.wikipedia.org/wiki/Yacc>`__; developed in 197X. YACC will read a grammar-file and generates |
@@ -150,7 +150,7 @@ | ||
150 | 150 | parsing strategy; it should support PEG. But it is free to support others as well (with user-selectable |
151 | 151 | compiler-plugins). |
152 | 152 | |BR| |
153 | - This is not unlike other compiler-options. | |
153 | + This is not unlike other compiler options. | |
154 | 154 | |
155 | 155 | To use the grammar, you simply call one of those rules as a function: pass the input (string) and it will return a |
156 | 156 | (generic) tree structure. |
@@ -11,7 +11,7 @@ | ||
11 | 11 | :tags: Castle, DRAFT |
12 | 12 | |
13 | 13 | In Castle, one can dynamically connect components and send “events” over those connections. Typically this is done as |
14 | - an action on an incoming message (see: :ref:`CCC-Actors`). And, depending on ‘:ref:`TheMachinery`’ those events can be | |
14 | + an action on an incoming message (see: :ref:`CCC-Actors`). And depending on ‘:ref:`TheMachinery`’, those events can be | |
15 | 15 | queued. It is this combination that *can result* in a **beautiful Heisenbug**. |
16 | 16 | |
17 | 17 | First, let’s explain the Heisenbug, before we give an example. Then we analyze it, show how to improve the code, and |
@@ -34,14 +34,14 @@ | ||
34 | 34 | My standard example, :ref:`Castle-TheSieve`, suffered from this issue. The initial version did work for years |
35 | 35 | but failed horribly when another “machinery” was used. After studying this, the bug is simple and easy to fix. |
36 | 36 | |
37 | -There are two related timing issues that together result in the Heisenbug. First, we introduce them, and then | |
37 | +There are two related timing issues that together result in the Heisenbug. First, we introduce them and then | |
38 | 38 | show how the combination may fail. |
39 | 39 | |
40 | 40 | |
41 | 41 | Event-order |
42 | 42 | ----------- |
43 | 43 | |
44 | -Conceptually, the `Generator` sends (events with) integers to `Sieve(2)`, which may forwarded them to `Sieve(3)`, then | |
44 | +Conceptually, the `Generator` sends (events with) integers to `Sieve(2)`, which may forward them to `Sieve(3)`, then | |
45 | 45 | to `Sieve(5)`, etc. As shown in the **Conceptual sidebar**, we probably like to assume that each integer is sieved |
46 | 46 | before the next *’int’* *starts*: the classic “sequential view” we are used to. |
47 | 47 |
@@ -203,7 +203,7 @@ | ||
203 | 203 | Remember, this queue exists as a *model* **only** (like everything in Castle-code)! |
204 | 204 | |BR| |
205 | 205 | Depending on ‘:ref:`TheMachinery`, there may be no need to implement the queue (e.g.with DirectCall) at all; or they may |
206 | - only be a queue-length and -maximum, or ... | |
206 | + only be a queue length and -maximum, or ... | |
207 | 207 | |
208 | 208 | |
209 | 209 |