avoid using EOF in the expression parser

This commit is contained in:
krangelov
2021-10-12 18:47:04 +02:00
parent ead1160a75
commit a2e7d20b7a
2 changed files with 77 additions and 65 deletions

View File

@@ -239,13 +239,15 @@ PgfExprParser::~PgfExprParser()
free(token_value); free(token_value);
} }
uint32_t PgfExprParser::getc() bool PgfExprParser::getc()
{ {
uint32_t ch = pgf_utf8_decode((const uint8_t **) &pos); if (pos - ((const char*) &inp->text) >= inp->size) {
if (pos - ((const char*) &inp->text) > inp->size) { ch = ' ';
ch = EOF; return false;
} }
return ch;
ch = pgf_utf8_decode((const uint8_t **) &pos);
return true;
} }
void PgfExprParser::putc(uint32_t ucs) void PgfExprParser::putc(uint32_t ucs)
@@ -313,10 +315,12 @@ pgf_is_normal_ident(PgfText *id)
return true; return true;
} }
void PgfExprParser::str_char() bool PgfExprParser::str_char()
{ {
if (ch == '\\') { if (ch == '\\') {
ch = getc(); if (!getc())
return false;
switch (ch) { switch (ch) {
case '\\': case '\\':
putc('\\'); putc('\\');
@@ -340,14 +344,14 @@ void PgfExprParser::str_char()
putc('\t'); putc('\t');
break; break;
case '0': case '0':
puts("\0"); putc('\0');
default: default:
return; return false;
} }
} else { } else {
putc(ch); putc(ch);
} }
ch = getc(); return getc();
} }
void PgfExprParser::token() void PgfExprParser::token()
@@ -361,87 +365,91 @@ void PgfExprParser::token()
while (isspace(ch)) { while (isspace(ch)) {
token_pos = pos; token_pos = pos;
ch = getc(); if (!getc()) {
token_tag = PGF_TOKEN_EOF;
return;
}
} }
switch (ch) { switch (ch) {
// TODO
// case EOF:
// token_tag = PGF_TOKEN_EOF;
// break;
case '(': case '(':
ch = getc(); getc();
token_tag = PGF_TOKEN_LPAR; token_tag = PGF_TOKEN_LPAR;
break; break;
case ')': case ')':
ch = getc(); getc();
token_tag = PGF_TOKEN_RPAR; token_tag = PGF_TOKEN_RPAR;
break; break;
case '{': case '{':
ch = getc(); getc();
token_tag = PGF_TOKEN_LCURLY; token_tag = PGF_TOKEN_LCURLY;
break; break;
case '}': case '}':
ch = getc(); getc();
token_tag = PGF_TOKEN_RCURLY; token_tag = PGF_TOKEN_RCURLY;
break; break;
case '<': case '<':
ch = getc(); getc();
token_tag = PGF_TOKEN_LTRIANGLE; token_tag = PGF_TOKEN_LTRIANGLE;
break; break;
case '>': case '>':
ch = getc(); getc();
token_tag = PGF_TOKEN_RTRIANGLE; token_tag = PGF_TOKEN_RTRIANGLE;
break; break;
case '?': case '?':
ch = getc(); getc();
token_tag = PGF_TOKEN_QUESTION; token_tag = PGF_TOKEN_QUESTION;
break; break;
case '\\': case '\\':
ch = getc(); getc();
token_tag = PGF_TOKEN_LAMBDA; token_tag = PGF_TOKEN_LAMBDA;
break; break;
case '-': case '-':
ch = getc(); if (getc()) {
if (ch == '>') { if (ch == '>') {
ch = getc(); getc();
token_tag = PGF_TOKEN_RARROW; token_tag = PGF_TOKEN_RARROW;
} else if (isdigit(ch)) { } else if (isdigit(ch)) {
putc('-'); putc('-');
goto digit; goto digit;
}
} }
break; break;
case ',': case ',':
ch = getc(); getc();
token_tag = PGF_TOKEN_COMMA; token_tag = PGF_TOKEN_COMMA;
break; break;
case ':': case ':':
ch = getc(); getc();
token_tag = PGF_TOKEN_COLON; token_tag = PGF_TOKEN_COLON;
break; break;
case ';': case ';':
ch = getc(); getc();
token_tag = PGF_TOKEN_SEMI; token_tag = PGF_TOKEN_SEMI;
break; break;
case '\'': { case '\'': {
ch = getc(); if (getc()) {
while (ch != '\'' && ch != EOF) { while (ch != '\'') {
str_char(); if (!str_char())
} break;
if (ch == '\'') { }
ch = getc(); if (ch == '\'') {
token_tag = PGF_TOKEN_IDENT; getc();
} token_tag = PGF_TOKEN_IDENT;
}
}
break; break;
} }
case '"': { case '"': {
ch = getc(); if (getc()) {
while (ch != '"' && ch != EOF) { while (ch != '"') {
str_char(); if (!str_char())
} break;
if (ch == '"') { }
ch = getc(); if (ch == '"') {
token_tag = PGF_TOKEN_STR; getc();
token_tag = PGF_TOKEN_STR;
}
} }
break; break;
} }
@@ -449,28 +457,31 @@ void PgfExprParser::token()
if (pgf_is_ident_first(ch)) { if (pgf_is_ident_first(ch)) {
do { do {
putc(ch); putc(ch);
ch = getc(); if (!getc())
break;
} while (pgf_is_ident_rest(ch)); } while (pgf_is_ident_rest(ch));
token_tag = PGF_TOKEN_IDENT; token_tag = PGF_TOKEN_IDENT;
} else if (isdigit(ch)) { } else if (isdigit(ch)) {
digit: digit:
do { do {
putc(ch); putc(ch);
ch = getc(); if (!getc())
break;
} while (isdigit(ch)); } while (isdigit(ch));
if (ch == '.') { if (ch == '.') {
putc(ch); putc(ch);
ch = getc(); if (getc()) {
while (isdigit(ch)) {
while (isdigit(ch)) { putc(ch);
putc(ch); if (!getc())
ch = getc(); break;
} }
}
token_tag = PGF_TOKEN_FLT; token_tag = PGF_TOKEN_FLT;
} else { } else {
token_tag = PGF_TOKEN_INT; token_tag = PGF_TOKEN_INT;
} }
} }
break; break;
} }
@@ -480,7 +491,8 @@ digit:
bool PgfExprParser::lookahead(int ch) bool PgfExprParser::lookahead(int ch)
{ {
while (isspace(this->ch)) { while (isspace(this->ch)) {
this->ch = getc(); if (!getc())
break;
} }
return (this->ch == ch); return (this->ch == ch);

View File

@@ -210,14 +210,14 @@ class PGF_INTERNAL_DECL PgfExprParser {
const char *token_pos, *pos; const char *token_pos, *pos;
uint32_t ch; uint32_t ch;
uint32_t getc(); bool getc();
void putc(uint32_t ch); void putc(uint32_t ch);
public: public:
PgfExprParser(PgfText* input, PgfUnmarshaller *unmarshaller); PgfExprParser(PgfText* input, PgfUnmarshaller *unmarshaller);
~PgfExprParser(); ~PgfExprParser();
void str_char(); bool str_char();
void token(); void token();
bool lookahead(int ch); bool lookahead(int ch);