From 9f0634e98902ca79188940bb0cfaddfad31d6660 Mon Sep 17 00:00:00 2001 From: ketmar Date: Mon, 16 Sep 2013 05:52:49 +0300 Subject: [PATCH] more fixes to scanner --- src/scan.c | 56 +++++++++++++++++++++++++++++++++++++++++++------------- src/scan.h | 3 ++- 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/src/scan.c b/src/scan.c index 7a52e3f..35f8310 100644 --- a/src/scan.c +++ b/src/scan.c @@ -24,6 +24,7 @@ #include "jamgram.h" #include "jambase.h" #include "newstr.h" +#include "kstrings.h" const struct keyword { @@ -55,21 +56,26 @@ static char *symdump (YYSTYPE *s); #define BIGGEST_TOKEN (10240) -#ifndef NDEBUG +/*#ifndef NDEBUG*/ static const char *mnames[] = { "SCAN_NORMAL", "SCAN_BEFORE_STRING", "SCAN_STRING", "SCAN_PUNCT", + "SCAN_PUNCT_BS", }; -#endif +/*#endif*/ /* * Set parser mode: normal, string, or keyword */ void yymode (int n) { + if (n == SCAN_PUNCT && scan_mode == SCAN_BEFORE_STRING) n = SCAN_PUNCT_BS; + else if (n == SCAN_NORMAL && scan_mode == SCAN_PUNCT_BS) n = SCAN_BEFORE_STRING; #ifndef NDEBUG - if (scan_mode != n) fprintf(stderr, "**MODE TRANSITION: %s --> %s\n", mnames[scan_mode], mnames[n]); + if (DEBUG_SCAN) { + if (scan_mode != n) printf("**MODE TRANSITION: %s --> %s\n", mnames[scan_mode], mnames[n]); + } #endif scan_mode = n; } @@ -196,23 +202,42 @@ int yylex (void) { /* get first character (whitespace or of token) */ c = yychar(); if (scan_mode == SCAN_STRING) { + tKString s; /* if scanning for a string (action's {}'s), look for the closing brace */ /* we handle matching braces, if they match! */ int nest = 1; + /* skip spaces and newline */ + /* + while (c != EOF && c != '\n' && isspace(c)) c = yychar(); + if (c == '\n') c = yychar(); + */ + /*while (c != EOF && isspace(c)) c = yychar();*/ + kStringNew(&s); + /* collect string */ while (c != EOF && b < buf+sizeof(buf)) { if (c == '{') ++nest; if (c == '}' && !--nest) break; - *b++ = c; + /* *b++ = c; */ + kStringPushBack(&s, c); c = yychar(); } /* we ate the ending brace -- regurgitate it */ if (c != EOF) yyprev(); /* check obvious errors */ - if (b == buf+sizeof(buf)) { yyerror("action block too big"); goto eof; } - if (nest) { yyerror("unmatched {} in action block"); goto eof; } - *b = 0; + /* if (b == buf+sizeof(buf)) { yyerror("action block too big"); goto eof; } */ + if (nest) { kStringFree(&s); yyerror("unmatched {} in action block"); goto eof; } + /* *b = 0; */ + /* remove trailing newlines and spaces, add one newline */ + /*strcpy(buf+nest, "\n");*/ + /* + nest = kStringLen(&s); + while (nest > 0 && isspace(kStringCStr(&s)[nest-1])) kStringPopBack(&s); + kStringAppendCStr(&s, "\n"); + */ yylval.type = T_STRING; - yylval.string = newstr(buf); + yylval.string = newstr(kStringCStr(&s)); + kStringFree(&s); + /*fprintf(stderr, "::: [%s]\n", yylval.string);*/ yymode(SCAN_NORMAL); } else { int in_quote = 0, not_keyword = 0, was_not_alnum = 0; @@ -303,7 +328,7 @@ lexdone: /* don't scan if it's obviously not a keyword or if its */ /* an alphabetic when we were looking for punctuation */ yylval.type = T_ARG; - if (!not_keyword && !(scan_mode == SCAN_PUNCT && isalnum(*buf))) { + if (!not_keyword && !((scan_mode == SCAN_PUNCT || scan_mode == SCAN_PUNCT_BS) && isalnum(*buf))) { /* find token */ for (k = keywords; k->word; ++k) { if (strcmp(k->word, buf) == 0) { @@ -342,9 +367,14 @@ static char *symdump (YYSTYPE *s) { void yystatetrans (int tk) { - switch (tk) { - case T_ACTIONS_t: yymode(SCAN_BEFORE_STRING); break; - case T_LBRACKET_t: yymode(SCAN_NORMAL); break; - case T_LBRACE_t: if (scan_mode == SCAN_BEFORE_STRING) yymode(SCAN_STRING); break; + if (scan_mode == SCAN_BEFORE_STRING) { + switch (tk) { + case T_LBRACE_t: yymode(SCAN_STRING); break; + } + } else { + switch (tk) { + case T_ACTIONS_t: yymode(SCAN_BEFORE_STRING); break; + case T_LBRACKET_t: yymode(SCAN_NORMAL); break; + } } } diff --git a/src/scan.h b/src/scan.h index 27078dd..5ddb86c 100644 --- a/src/scan.h +++ b/src/scan.h @@ -54,7 +54,8 @@ enum { SCAN_NORMAL, /* normal parsing */ SCAN_BEFORE_STRING, /* after 'actions', but before '{' */ SCAN_STRING, /* look only for matching '}' */ - SCAN_PUNCT /* only punctuation keywords */ + SCAN_PUNCT, /* only punctuation keywords */ + SCAN_PUNCT_BS /* after 'actions', but before '{', previous was SCAN_BEFORE_STRING */ }; extern void yymode (int n); -- 2.11.4.GIT