📄 wslexer.c
字号:
} gw_assert(p != NULL); yylval->identifier = (char *) p; return tIDENTIFIER; } if (WS_IS_NON_ZERO_DIGIT(ch)) { /* A decimal integer literal or a decimal float literal. */ ws_buffer_init(&buffer); if (!ws_buffer_append_space(&buffer, &p, 1)) {number_error_memory: ws_error_memory(compiler); ws_buffer_uninit(&buffer); return EOF; } p[0] = ch; while (ws_stream_getc(compiler->input, &ch)) { if (WS_IS_DECIMAL_DIGIT(ch)) { if (!ws_buffer_append_space(&buffer, &p, 1)) goto number_error_memory; p[0] = ch; } else if (ch == '.' || ch == 'e' || ch == 'E') { /* DecimalFloatLiteral. */ if (ch == '.') { if (!ws_buffer_append_space(&buffer, &p, 1)) goto number_error_memory; p[0] = '.'; success = read_float_from_point(compiler, &buffer, &yylval->vfloat); } else { ws_stream_ungetc(compiler->input, ch); success = read_float_from_exp(compiler, &buffer, &yylval->vfloat); } ws_buffer_uninit(&buffer); if (!success) return EOF; return tFLOAT; } else { ws_stream_ungetc(compiler->input, ch); break; } } /* Now the buffer contains an integer number as a string. Let's convert it to an integer number. */ yylval->integer = buffer_to_int(compiler, &buffer); ws_buffer_uninit(&buffer); /* Read a DecimalIntegerLiteral. */ return tINTEGER; } if (ch == '0') { /* The integer constant 0, an octal number or a HexIntegerLiteral. */ if (ws_stream_getc(compiler->input, &ch2)) { if (ch2 == 'x' || ch2 == 'X') { /* HexIntegerLiteral. */ ws_buffer_init(&buffer); if (!ws_buffer_append_space(&buffer, &p, 2)) goto number_error_memory; p[0] = '0'; p[1] = 'x'; while (ws_stream_getc(compiler->input, &ch)) { if (WS_IS_HEX_DIGIT(ch)) { if (!ws_buffer_append_space(&buffer, &p, 1)) goto number_error_memory; p[0] = ch; } else { ws_stream_ungetc(compiler->input, ch); break; } } if (ws_buffer_len(&buffer) == 2) { ws_buffer_uninit(&buffer); ws_src_error(compiler, 0, "numeric constant with no digits"); yylval->integer = 0; return tINTEGER; } /* Now the buffer contains an integer number as * a string. Let's convert it to an integer * number. */ yylval->integer = buffer_to_int(compiler, &buffer); ws_buffer_uninit(&buffer); /* Read a HexIntegerLiteral. */ return tINTEGER; } if (WS_IS_OCTAL_DIGIT(ch2)) { /* OctalIntegerLiteral. */ ws_buffer_init(&buffer); if (!ws_buffer_append_space(&buffer, &p, 2)) goto number_error_memory; p[0] = '0'; p[1] = ch2; while (ws_stream_getc(compiler->input, &ch)) { if (WS_IS_OCTAL_DIGIT(ch)) { if (!ws_buffer_append_space(&buffer, &p, 1)) goto number_error_memory; p[0] = ch; } else { ws_stream_ungetc(compiler->input, ch); break; } } /* Convert the buffer into an intger number. */ yylval->integer = buffer_to_int(compiler, &buffer); ws_buffer_uninit(&buffer); /* Read an OctalIntegerLiteral. */ return tINTEGER; } if (ch2 == '.' || ch2 == 'e' || ch2 == 'E') { /* DecimalFloatLiteral. */ ws_buffer_init(&buffer); if (ch2 == '.') { if (!ws_buffer_append_space(&buffer, &p, 1)) goto number_error_memory; p[0] = '.'; success = read_float_from_point(compiler, &buffer, &yylval->vfloat); } else { ws_stream_ungetc(compiler->input, ch); success = read_float_from_exp(compiler, &buffer, &yylval->vfloat); } ws_buffer_uninit(&buffer); if (!success) return EOF; return tFLOAT; } ws_stream_ungetc(compiler->input, ch2); } /* Integer literal 0. */ yylval->integer = 0; return tINTEGER; } /* Garbage found from the input stream. */ ws_src_error(compiler, 0, "garbage found from the input stream: character=0x%x", ch); return EOF; break; } } return EOF;}/********************* Static functions *********************************/static WsBool lookup_keyword(char *id, size_t len, int *token_return){ int left = 0, center, right = num_keywords; while (left < right) { size_t l; int result; center = left + (right - left) / 2; l = keywords[center].name_len; if (len < l) l = len; result = memcmp(id, keywords[center].name, l); if (result < 0 || (result == 0 && len < keywords[center].name_len)) /* The possible match is smaller. */ right = center; else if (result > 0 || (result == 0 && len > keywords[center].name_len)) /* The possible match is bigger. */ left = center + 1; else { /* Found a match. */ *token_return = keywords[center].token; return WS_TRUE; } } /* No match. */ return WS_FALSE;}static WsUInt32 buffer_to_int(WsCompilerPtr compiler, WsBuffer *buffer){ unsigned char *p; unsigned long value; /* Terminate the string. */ if (!ws_buffer_append_space(buffer, &p, 1)) { ws_error_memory(compiler); return 0; } p[0] = '\0'; /* Convert the buffer into an integer number. The base is taken from the bufer. */ errno = 0; value = strtoul((char *) ws_buffer_ptr(buffer), NULL, 0); /* Check for overflow. We accept WS_INT32_MAX + 1 because we might * be parsing the numeric part of '-2147483648'. */ if (errno == ERANGE || value > (WsUInt32) WS_INT32_MAX + 1) ws_src_error(compiler, 0, "integer literal too large"); /* All done. */ return (WsUInt32) value;}static WsBool read_float_from_point(WsCompiler *compiler, WsBuffer *buffer, WsFloat *result){ WsUInt32 ch; unsigned char *p; while (ws_stream_getc(compiler->input, &ch)) { if (WS_IS_DECIMAL_DIGIT(ch)) { if (!ws_buffer_append_space(buffer, &p, 1)) { ws_error_memory(compiler); return WS_FALSE; } p[0] = (unsigned char) ch; } else { ws_stream_ungetc(compiler->input, ch); break; } } return read_float_from_exp(compiler, buffer, result);}static WsBool read_float_from_exp(WsCompiler *compiler, WsBuffer *buffer, WsFloat *result){ WsUInt32 ch; unsigned char *p; int sign = '+'; unsigned char buf[4]; /* Do we have an exponent part. */ if (!ws_stream_getc(compiler->input, &ch)) goto done; if (ch != 'e' && ch != 'E') { /* No exponent part. */ ws_stream_ungetc(compiler->input, ch); goto done; } /* Sign. */ if (!ws_stream_getc(compiler->input, &ch)) { /* This is an error. */ ws_src_error(compiler, 0, "truncated float literal"); return WS_FALSE; } if (ch == '-') sign = '-'; else if (ch == '+') sign = '+'; else ws_stream_ungetc(compiler->input, ch); /* DecimalDigits. */ if (!ws_stream_getc(compiler->input, &ch)) { ws_src_error(compiler, 0, "truncated float literal"); return WS_FALSE; } if (!WS_IS_DECIMAL_DIGIT(ch)) { ws_src_error(compiler, 0, "no decimal digits in exponent part"); return WS_FALSE; } /* Append exponent part read so far. */ if (!ws_buffer_append_space(buffer, &p, 2)) { ws_error_memory(compiler); return WS_FALSE; } p[0] = 'e'; p[1] = sign; /* Read decimal digits. */ while (WS_IS_DECIMAL_DIGIT(ch)) { if (!ws_buffer_append_space(buffer, &p, 1)) { ws_error_memory(compiler); return WS_FALSE; } p[0] = (unsigned char) ch; if (!ws_stream_getc(compiler->input, &ch)) /* EOF. This is ok. */ goto done; } /* Unget the extra character. */ ws_stream_ungetc(compiler->input, ch); /* FALLTHROUGH */done: if (!ws_buffer_append_space(buffer, &p, 1)) { ws_error_memory(compiler); return WS_FALSE; } p[0] = 0; /* Now the buffer contains a valid floating point number. */ *result = (WsFloat) strtod((char *) ws_buffer_ptr(buffer), NULL); /* Check that the generated floating point number fits to `float32'. */ if (*result == HUGE_VAL || *result == -HUGE_VAL || ws_ieee754_encode_single(*result, buf) != WS_IEEE754_OK) ws_src_error(compiler, 0, "floating point literal too large"); return WS_TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -