]> ocean-lang.org Git - ocean/blobdiff - csrc/parsergen.mdc
parsergen: split out heart-of-the-parser code
[ocean] / csrc / parsergen.mdc
index 6eb43181006fca10c080b545a6f47b85173636ac..554e63c37c921faea604399f7a9dd1f968b7cc84 100644 (file)
@@ -2724,6 +2724,28 @@ Now we have the parser.  For each token we might shift it, trigger a
 reduction, or start error handling.  2D tokens (IN, OUT, EOL) also need
 to be handled.
 
+###### parser vars
+
+       struct parser p = { 0 };
+       struct token *tk = NULL;
+       int accepted = 0;
+
+###### heart of parser
+
+       shift(&p, TK_eof, NULL, states);
+       while (!accepted && p.tos > 0) {
+               struct frame *tos = &p.stack[p.tos-1];
+               if (!tk)
+                       tk = tok_copy(token_next(tokens));
+               parser_trace(trace, &p,
+                            tk, states, non_term, config->known_count);
+
+               ## try shift or ignore
+               ## try reduce
+               ## handle error
+       }
+
+
 We return whatever `asn` was returned by reducing production zero.
 
 When we find `TK_in` and `TK_out` tokens which report indents we need
@@ -2768,6 +2790,43 @@ in the thing that preceed:
 Here the NEWLINE will be shifted because nothing can be reduced until
 the `if` is seen.
 
+For other tokens, we shift the next token if that is possible, otherwise
+we try to reduce a production.
+
+###### try shift or ignore
+
+       if (tk->num == TK_in) {
+               free(tk);
+               tk = NULL;
+               parser_trace_action(trace, "Record");
+               continue;
+       }
+       if (tk->num == TK_out) {
+               if (1) {
+                       // OK to cancel
+                               free(tk);
+                       tk = NULL;
+                       parser_trace_action(trace, "Cancel");
+                       continue;
+               }
+               // fall through to error handling as both SHIFT and REDUCE
+               // will fail.
+       }
+       if (tk->num == TK_newline) {
+               if (1) {
+                       free(tk);
+                       tk = NULL;
+                       parser_trace_action(trace, "Discard");
+                       continue;
+               }
+       }
+       if (shift(&p, tk->num, tk, states)) {
+               tk = NULL;
+               parser_trace_action(trace, "Shift");
+               ## did shift
+               continue;
+       }
+
 We have already discussed the bulk of the handling of a "reduce" action,
 with the `pop()` and `shift()` functions doing much of the work.  There
 is a little more complexity needed to manage storage for the asn (Abstract
@@ -2862,55 +2921,10 @@ dropping tokens until either we manage to shift one, or reach end-of-file.
                         FILE *trace, const char *non_term[],
                         struct token_config *config)
        {
-               struct parser p = { 0 };
-               struct token *tk = NULL;
-               int accepted = 0;
                ## parser vars
 
-               shift(&p, TK_eof, NULL, states);
-               while (!accepted && p.tos > 0) {
-                       struct frame *tos = &p.stack[p.tos-1];
-                       if (!tk)
-                               tk = tok_copy(token_next(tokens));
-                       parser_trace(trace, &p,
-                                    tk, states, non_term, config->known_count);
+               ## heart of parser
 
-                       if (tk->num == TK_in) {
-                               free(tk);
-                               tk = NULL;
-                               parser_trace_action(trace, "Record");
-                               continue;
-                       }
-                       if (tk->num == TK_out) {
-                               if (1) {
-                                       // OK to cancel
-
-                                       free(tk);
-                                       tk = NULL;
-                                       parser_trace_action(trace, "Cancel");
-                                       continue;
-                               }
-                               // fall through to error handling as both SHIFT and REDUCE
-                               // will fail.
-                       }
-                       if (tk->num == TK_newline) {
-                               if (1) {
-                                       free(tk);
-                                       tk = NULL;
-                                       parser_trace_action(trace, "Discard");
-                                       continue;
-                               }
-                       }
-                       if (shift(&p, tk->num, tk, states)) {
-                               tk = NULL;
-                               parser_trace_action(trace, "Shift");
-                               ## did shift
-                               continue;
-                       }
-
-                       ## try reduce
-                       ## handle error
-               }
                free(tk);
                pop(&p, p.tos, do_free);
                free(p.asn_stack);