|
1 |
| -ECPG modifies and extends the core grammar in a way that |
2 |
| -1) every token in ECPG is <str> type. New tokens are |
3 |
| - defined in ecpg.tokens, types are defined in ecpg.type |
4 |
| -2) most tokens from the core grammar are simply converted |
5 |
| - to literals concatenated together to form the SQL string |
6 |
| - passed to the server, this is done by parse.pl. |
7 |
| -3) some rules need side-effects, actions are either added |
8 |
| - or completely overridden (compared to the basic token |
9 |
| - concatenation) for them, these are defined in ecpg.addons, |
10 |
| - the rules for ecpg.addons are explained below. |
11 |
| -4) new grammar rules are needed for ECPG metacommands. |
12 |
| - These are in ecpg.trailer. |
13 |
| -5) ecpg.header contains common functions, etc. used by |
14 |
| - actions for grammar rules. |
15 |
| - |
16 |
| -In "ecpg.addons", every modified rule follows this pattern: |
17 |
| - ECPG: dumpedtokens postfix |
18 |
| -where "dumpedtokens" is simply tokens from core gram.y's |
19 |
| -rules concatenated together. e.g. if gram.y has this: |
20 |
| - ruleA: tokenA tokenB tokenC {...} |
21 |
| -then "dumpedtokens" is "ruleAtokenAtokenBtokenC". |
22 |
| -"postfix" above can be: |
23 |
| -a) "block" - the automatic rule created by parse.pl is completely |
24 |
| - overridden, the code block has to be written completely as |
25 |
| - it were in a plain bison grammar |
26 |
| -b) "rule" - the automatic rule is extended on, so new syntaxes |
27 |
| - are accepted for "ruleA". E.g.: |
28 |
| - ECPG: ruleAtokenAtokenBtokenC rule |
29 |
| - | tokenD tokenE { action_code; } |
30 |
| - ... |
31 |
| - It will be substituted with: |
32 |
| - ruleA: <original syntax forms and actions up to and including |
33 |
| - "tokenA tokenB tokenC"> |
34 |
| - | tokenD tokenE { action_code; } |
35 |
| - ... |
36 |
| -c) "addon" - the automatic action for the rule (SQL syntax constructed |
37 |
| - from the tokens concatenated together) is prepended with a new |
38 |
| - action code part. This code part is written as is's already inside |
39 |
| - the { ... } |
40 |
| - |
41 |
| -Multiple "addon" or "block" lines may appear together with the |
42 |
| -new code block if the code block is common for those rules. |
| 1 | +ECPG's grammar (preproc.y) is built by parse.pl from the |
| 2 | +backend's grammar (gram.y) plus various add-on rules. |
| 3 | +Some notes: |
| 4 | + |
| 5 | +1) Most input matching core grammar productions is simply converted |
| 6 | + to strings and concatenated together to form the SQL string |
| 7 | + passed to the server. parse.pl can automatically build the |
| 8 | + grammar actions needed to do this. |
| 9 | +2) Some grammar rules need special actions that are added to or |
| 10 | + completely override the default token-concatenation behavior. |
| 11 | + This is controlled by ecpg.addons as explained below. |
| 12 | +3) Additional grammar rules are needed for ECPG's own commands. |
| 13 | + These are in ecpg.trailer, as is the "epilogue" part of preproc.y. |
| 14 | +4) ecpg.header contains the "prologue" part of preproc.y, including |
| 15 | + support functions, Bison options, etc. |
| 16 | +5) Additional terminals added by ECPG must be defined in ecpg.tokens. |
| 17 | + Additional nonterminals added by ECPG must be defined in ecpg.type. |
| 18 | + |
| 19 | +ecpg.header, ecpg.tokens, ecpg.type, and ecpg.trailer are just |
| 20 | +copied verbatim into preproc.y at appropriate points. |
| 21 | + |
| 22 | +ecpg.addons contains entries that begin with a line like |
| 23 | + ECPG: concattokens ruletype |
| 24 | +and typically have one or more following lines that are the code |
| 25 | +for a grammar action. Any line not starting with "ECPG:" is taken |
| 26 | +to be part of the code block for the preceding "ECPG:" line. |
| 27 | + |
| 28 | +"concattokens" identifies which gram.y production this entry affects. |
| 29 | +It is simply the target nonterminal and the tokens from the gram.y rule |
| 30 | +concatenated together. For example, to modify the action for a gram.y |
| 31 | +rule like this: |
| 32 | + target: tokenA tokenB tokenC {...} |
| 33 | +"concattokens" would be "targettokenAtokenBtokenC". If we want to |
| 34 | +modify a non-first alternative for a nonterminal, we still write the |
| 35 | +nonterminal. For example, "concattokens" should be "targettokenDtokenE" |
| 36 | +to affect the second alternative in: |
| 37 | + target: tokenA tokenB tokenC {...} |
| 38 | + | tokenD tokenE {...} |
| 39 | + |
| 40 | +"ruletype" is one of: |
| 41 | + |
| 42 | +a) "block" - the automatic action that parse.pl would create is |
| 43 | + completely overridden. Instead the entry's code block is emitted. |
| 44 | + The code block must include the braces ({}) needed for a Bison action. |
| 45 | + |
| 46 | +b) "addon" - the entry's code block is inserted into the generated |
| 47 | + action, ahead of the automatic token-concatenation code. |
| 48 | + In this case the code block need not contain braces, since |
| 49 | + it will be inserted within braces. |
| 50 | + |
| 51 | +c) "rule" - the automatic action is emitted, but then the entry's |
| 52 | + code block is added verbatim afterwards. This typically is |
| 53 | + used to add new alternatives to a nonterminal of the core grammar. |
| 54 | + For example, given the entry: |
| 55 | + ECPG: targettokenAtokenBtokenC rule |
| 56 | + | tokenD tokenE { custom_action; } |
| 57 | + what will be emitted is |
| 58 | + target: tokenA tokenB tokenC { automatic_action; } |
| 59 | + | tokenD tokenE { custom_action; } |
| 60 | + |
| 61 | +Multiple "ECPG:" entries can share the same code block, if the |
| 62 | +same action is needed for all. When an "ECPG:" line is immediately |
| 63 | +followed by another one, it is not assigned an empty code block; |
| 64 | +rather the next nonempty code block is assumed to apply to all |
| 65 | +immediately preceding "ECPG:" entries. |
| 66 | + |
| 67 | +In addition to the modifications specified by ecpg.addons, |
| 68 | +parse.pl contains some tables that list backend grammar |
| 69 | +productions to be ignored or modified. |
| 70 | + |
| 71 | +Nonterminals that construct strings (as described above) should be |
| 72 | +given <str> type, which is parse.pl's default assumption for |
| 73 | +nonterminals found in gram.y. That can be overridden at need by |
| 74 | +making an entry in parse.pl's %replace_types table. %replace_types |
| 75 | +can also be used to suppress output of a nonterminal's rules |
| 76 | +altogether (in which case ecpg.trailer had better provide replacement |
| 77 | +rules, since the nonterminal will still be referred to elsewhere). |
0 commit comments