git @ Cat's Eye Technologies Tamsin / 41129b4
Well, that passes a surprising number of tests. However... Cat's Eye Technologies 11 years ago
4 changed file(s) with 100 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
1616 return scanner;
1717 }
1818
19 void scanner_char_engine(void) {
20 }
21
1922 struct term *scan(struct scanner *s) {
20 char c = s->buffer[s->position];
21 if (c == '\0') {
22 return &tamsin_EOF;
23 if (s->engines == NULL || s->engines->production == &scanner_char_engine) {
24 char c = s->buffer[s->position];
25 if (c == '\0') {
26 return &tamsin_EOF;
27 } else {
28 s->position++;
29 return term_new_from_char(c);
30 }
2331 } else {
24 s->position++;
25 return term_new_from_char(c);
32 //fprintf(stderr, "calling s->engines here\n");
33 s->engines->production();
34 // XXX this can't be right. surely we need to save this?
35 return result;
2636 }
2737 };
2838
5464 s->engines = s->engines->next;
5565 /* engine_free(e); */
5666 }
57
58 void scanner_char_engine(void) {
59 }
1919 t->subterms = NULL;
2020 }
2121
22 struct term tamsin_EOF = {"\0", NULL, NULL};
22 struct term tamsin_EOF = {"EOF", NULL, NULL};
2323
2424 struct term *term_new_from_char(char c) {
2525 char s[2];
219219 + cat dog
220220 = woof
221221
222 We can also implement a production scanner with the ☆char scanner. This is
222 We can also implement a production scanner with the char scanner. This is
223223 more useful.
224224
225225 | main = program using scanner.
990990 | | "d" & "o" & "g" & return 'dog'.
991991 + catdog
992992 = dog
993
994 We can also implement a production scanner with the char scanner. This is
995 more useful.
996
997 | main = program using scanner.
998 | scanner = scan using $.char.
999 | scan = "a" | "b" | "@".
1000 | program = "a" & "@" & "b" & return ok.
1001 + a@b
1002 = ok
1003
1004 If the production scanner fails to match the input text, it will return an EOF.
1005 This is a little weird, but. Well. Watch this space.
1006
1007 | main = program using scanner.
1008 | scanner = scan using $.char.
1009 | scan = "a" | "b" | "@".
1010 | program = "a" & "@" & "b" & return ok.
1011 + x
1012 ? expected 'a' found 'EOF'
1013
1014 On the other hand, if the scanner understands all the tokens, but the parser
1015 doesn't see the tokens it expects, you get the usual error.
1016
1017 | main = program using scanner.
1018 | scanner = scan using $.char.
1019 | scan = "a" | "b" | "@".
1020 | program = "a" & "@" & "b" & return ok.
1021 + b@a
1022 ? expected 'a' found 'b'
1023
1024 We can write a slightly more realistic scanner, too.
1025
1026 | main = program using scanner.
1027 | scanner = scan using $.char.
1028 | scan = "c" & "a" & "t" & return cat
1029 | | "d" & "o" & "g" & return dog.
1030 | program = "cat" & "dog".
1031 + catdog
1032 = dog
1033
1034 Parsing using a production scanner ignores any extra text given to it,
1035 just like the built-in parser.
1036
1037 | main = program using scanner.
1038 | scanner = scan using $.char.
1039 | scan = (
1040 | "c" & "a" & "t" & return cat | "d" & "o" & "g" & return dog
1041 | ).
1042 | program = "cat" & "dog".
1043 + catdogfoobar
1044 = dog
1045
1046 Herein lie an excessive number of tests that I wrote while I was debugging.
1047 Some of them will be cleaned up at a future point.
1048
1049 | main = program using scanner.
1050 | scanner = scan using $.char.
1051 | scan = (
1052 | "c" & "a" & "t" & return cat | "d" & "o" & "g" & return dog
1053 | ).
1054 | program = "cat" & print 1 &
1055 | ("cat" & print 2 | "dog" & print 3) &
1056 | "dog" & print 4 & return ok.
1057 + catcatdog
1058 = 1
1059 = 2
1060 = 4
1061 = ok
1062
1063 | main = program using scanner.
1064 | scanner = scan using $.char.
1065 | scan = (
1066 | "c" & "a" & "t" & return cat | "d" & "o" & "g" & return dog
1067 | ).
1068 | program = "cat" & print 1 &
1069 | ("cat" & print 2 | "dog" & print 3) &
1070 | "dog" & print 4 & return ok.
1071 + catdogdog
1072 = 1
1073 = 3
1074 = 4
1075 = ok
9931076
9941077 Three good ways to shoot yourself in the foot
9951078 ---------------------------------------------