annotate interps/c-intercal/pit/tests/arrtest.doc @ 12320:9c7eb9899d95 draft

<fizzie> le/rn karma//All living beings have actions (karma) as their own, their inheritance, their congenital cause, their kinsman, their refuge. It is karma that differentiates beings into low and high states.
author HackEso <hackeso@esolangs.org>
date Fri, 06 Mar 2020 23:08:37 +0000
parents 859f9b4339e6
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
996
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
1 arrtest.i is a program I wrote to test my correction to a nasty
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
2 ambiguity in grammar that was rendering many programs incompilable.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
3
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
4 The problem is:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
5
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
6 sublist1 : unambig _
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
7 sublist : unambig _ sublist
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
8 sublist : unambig _ sublist1
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
9
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
10 Token received: SPARK or EARS.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
11
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
12 Shift/reduce conflict.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
13
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
14 This is an example from numio.i:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
15
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
16 DO .5 <- '?"'#65535~"'?.7$",2SUB.1"'~#21845"'~#1"$#1'~#3
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
17 ^
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
18 ambiguity
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
19
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
20 The problem is that it's unclear whether the spark/ears is the end of
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
21 an expression around the array reference (reduce), or whether it's the
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
22 start of a new subscript (shift).
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
23
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
24 In this case, the reduction is wanted. With the shift taking priority,
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
25 there seems to be no way to write this statement without splitting
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
26 it. The grammar as of INTERCAL 0.24 uses the shift by default. This is
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
27 because multidimensional arrays may do this sort of thing:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
28
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
29 DO .1 <- ',2SUB.1".2~.3"'~#1
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
30
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
31 where the shift is needed to parse the ".2~.3" construct. In the first
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
32 case, there is no information within the next two characters that
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
33 indicates that it was the shift that was wanted; in the second case,
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
34 the fact that it's an ears, not a spark, indicates to humans that the
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
35 reduce is needed, but yacc/bison cannot determine this as they don't
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
36 have information about whether the current spark/ears level was
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
37 introduced with sparks or ears.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
38
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
39 At first I thought that scanning past all spark/ears to find the first
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
40 non-sparkears character could solve the problem, even if it could not
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
41 be coded in yacc, but the following code shows the problem:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
42
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
43 DO .1 <- ,3SUB",2SUB.1".2 (reduce required)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
44
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
45 (It could be the start of this statement:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
46
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
47 DO .1 <- ,3SUB",2SUB.1".2~.3"".4 (shift required))
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
48
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
49 The two statements above are the same for several tokens after the
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
50 ambiguity, and are even the same for 2 tokens after the forward
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
51 scan. This sort of problem is probably why the original manual
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
52 suggested alternating sparks and ears in various levels of expression
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
53 grouping. The only solution I can think of is:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
54
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
55 Determine somehow whether we are on a spark level or an ears level
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
56
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
57 Force alternation of sparks and ears (constraint on the programmer)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
58 at different levels of expression grouping when dealing with
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
59 near-ambiguous expressions involving spark/ears and arrays, like the
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
60 ones above (so the fourth statement above would be illegal)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
61
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
62 Look at whether we see a spark or an ears to determine whether to
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
63 shift or reduce
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
64
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
65 In other words, reduce whenever it would be a legal way to close the
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
66 current spark/ears level, otherwise shift.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
67
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
68 So how to determine whether we're on a spark level or an ears level?
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
69 The solution is for the lexer to place all the sparks and ears it
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
70 encounters on a spark/ears stack, and for the parser to pop two
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
71 sparkears off the stack whenever it reduces a SPARK [unary] <expr>
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
72 SPARK or EARS [unary] <expr> EARS.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
73
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
74 Once the determination is in place, all that is required is a way of
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
75 determining whether to shift or reduce based on a variable in the
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
76 program, rather than just a priority (which wouldn't work). This
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
77 doesn't seem to fit into yacc's syntax, so it's possible that after
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
78 all, yacc can't work with the INTERCAL syntax. But there is a solution
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
79 (one that I used to determine COMPUCOME from COME_FROM): syntax
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
80 analysis in the lexer! The idea is that legal closing spark/ears have
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
81 different tokens from illegal closing spark/ears, so that the reduce
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
82 is impossible in situations where it would be illegal (the production
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
83 looks something like eitherspark <expr> CLOSESPARK), and the default
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
84 in all other situations (sort of like 'auto' in C, which noone ever
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
85 uses, because it's the default everywhere it isn't illegal).
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
86
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
87 The solution I've used places a limit on the maximum nesting depth of
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
88 an expression. Strangely, it also limits the number of sparks and ears
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
89 that can be written into a 'comment' to 256. As care has to be taken
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
90 anyway that malformed abstained statements don't look sufficiently
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
91 like real statements to cause errors, this should be a trivial extra
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
92 addition.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
93
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
94 (Incidentally, I strongly suspect this sort of fix was used in the
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
95 original INTERCAL-72 compiler, because there is a very similar
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
96 restriction documented in the manual. Besides, it's needed to make
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
97 INTERCAL into an LALR(1) language.)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
98
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
99 The program arrtest.i will not actually run, but it will compile as
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
100 far as degenerating C code. I don't believe every line would have come
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
101 out as a valid statement in any version of INTERCAL 0.24 or earlier
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
102 (except the one labeled as invalid, which would have come out as valid
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
103 but is really bad style anyway).
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
104