📄 wslexer.c
字号:
/* ==================================================================== * The Kannel Software License, Version 1.0 * * Copyright (c) 2001-2004 Kannel Group * Copyright (c) 1998-2001 WapIT Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Kannel Group (http://www.kannel.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Kannel" and "Kannel Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please * contact org@kannel.org. * * 5. Products derived from this software may not be called "Kannel", * nor may "Kannel" appear in their name, without prior written * permission of the Kannel Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Kannel Group. For more information on * the Kannel Group, please see <http://www.kannel.org/>. * * Portions of this software are based upon software originally written at * WapIT Ltd., Helsinki, Finland for the Kannel project. */ /* * * wslexer.c * * Author: Markku Rossi <mtr@iki.fi> * * Copyright (c) 1999-2000 WAPIT OY LTD. * All rights reserved. * * Lexical analyzer. * */#include "wsint.h"#include "wsstree.h"#include "wsgram.h"/********************* Types and definitions ****************************//* A predicate to check whether the character `ch' is a decimal digit. */#define WS_IS_DECIMAL_DIGIT(ch) ('0' <= (ch) && (ch) <= '9')/* Convert the decimal digit `ch' to an integer number. */#define WS_DECIMAL_TO_INT(ch) ((ch) - '0')/* A predicate to check whether the character `ch' is a non-zero decimal digit. */#define WS_IS_NON_ZERO_DIGIT(ch) ('1' <= (ch) && (ch) <= '9')/* A predicate to check whether the character `ch' is an octal digit. */#define WS_IS_OCTAL_DIGIT(ch) ('0' <= (ch) && (ch) <= '7')/* Convert the octal digit `ch' to an integer number. */#define WS_OCTAL_TO_INT(ch) ((ch) - '0')/* A predicate to check whether the character `ch' is a hex digit. */#define WS_IS_HEX_DIGIT(ch) (('0' <= (ch) && (ch) <= '9') \ || ('a' <= (ch) && (ch) <= 'f') \ || ('A' <= (ch) && (ch) <= 'F'))/* Convert the hex digit `ch' to an integer number. */#define WS_HEX_TO_INT(ch) \ ('0' <= (ch) && (ch) <= '9' \ ? ((ch) - '0') \ : ('a' <= (ch) && (ch) <= 'f' \ ? ((ch) - 'a' + 10) \ : (ch) - 'A' + 10))/* A predicate to check whether the character `ch' is an identifier starter letter. */#define WS_IS_IDENTIFIER_LETTER(ch) \ (('a' <= (ch) && (ch) <= 'z') \ || ('A' <= (ch) && (ch) <= 'Z') \ || (ch) == '_')/********************* Prototypes for static functions ******************//* Check whether the identifier `id', `len' is a keyword. If the identifier is a keyword, the function returns WS_TRUE and sets the keywords token ID to `token_return'. Otherwise the function returns WS_FALSE. */static WsBool lookup_keyword(char *id, size_t len, int *token_return);/* Convert literal integer number, stored to the buffer `buffer', into a 32 bit integer number. The function will report possible integer overflows to the compiler `compiler'. The function modifies the contents of the buffer `buffer' but it does not free it. */static WsUInt32 buffer_to_int(WsCompilerPtr compiler, WsBuffer *buffer);/* Read a floating point number from the decimal point to the buffer `buffer'. The buffer `buffer' might already contain some leading digits of the number and it always contains the decimal point. If the operation is successful, the function returns WS_TRUE and it returns the resulting floating point number in `result'. Otherwise the function returns WS_FALSE. The buffer `buffer' must be initialized before this function is called and it must be uninitialized by the caller. */static WsBool read_float_from_point(WsCompiler *compiler, WsBuffer *buffer, WsFloat *result);/* Read a floating point number from the exponent part to the buffer `buffer'. The buffer might already contain some leading digits and fields of the floating poit number. Otherwise, the function works like read_float_from_point(). */static WsBool read_float_from_exp(WsCompiler *compiler, WsBuffer *buffer, WsFloat *result);/********************* Static variables *********************************//* A helper macro which expands to a strings and its length excluding the trailing '\0' character. */#define N(n) n, sizeof(n) - 1/* They keywords of the WMLScript language. This array must be sorted by the keyword names. */static struct{ char *name; size_t name_len; int token;} keywords[] = { {N("access"), tACCESS}, {N("agent"), tAGENT}, {N("break"), tBREAK}, {N("case"), tCASE}, {N("catch"), tCATCH}, {N("class"), tCLASS}, {N("const"), tCONST}, {N("continue"), tCONTINUE}, {N("debugger"), tDEBUGGER}, {N("default"), tDEFAULT}, {N("delete"), tDELETE}, {N("div"), tIDIV}, {N("do"), tDO}, {N("domain"), tDOMAIN}, {N("else"), tELSE}, {N("enum"), tENUM}, {N("equiv"), tEQUIV}, {N("export"), tEXPORT}, {N("extends"), tEXTENDS}, {N("extern"), tEXTERN}, {N("false"), tFALSE}, {N("finally"), tFINALLY}, {N("for"), tFOR}, {N("function"), tFUNCTION}, {N("header"), tHEADER}, {N("http"), tHTTP}, {N("if"), tIF}, {N("import"), tIMPORT}, {N("in"), tIN}, {N("invalid"), tINVALID}, {N("isvalid"), tISVALID}, {N("lib"), tLIB}, {N("meta"), tMETA}, {N("name"), tNAME}, {N("new"), tNEW}, {N("null"), tNULL}, {N("path"), tPATH}, {N("private"), tPRIVATE}, {N("public"), tPUBLIC}, {N("return"), tRETURN}, {N("sizeof"), tSIZEOF}, {N("struct"), tSTRUCT}, {N("super"), tSUPER}, {N("switch"), tSWITCH}, {N("this"), tTHIS}, {N("throw"), tTHROW}, {N("true"), tTRUE}, {N("try"), tTRY}, {N("typeof"), tTYPEOF}, {N("url"), tURL}, {N("use"), tUSE}, {N("user"), tUSER}, {N("var"), tVAR}, {N("void"), tVOID}, {N("while"), tWHILE}, {N("with"), tWITH},};static int num_keywords = sizeof(keywords) / sizeof(keywords[0]);/********************* Global functions *********************************/int ws_yy_lex(YYSTYPE *yylval, YYLTYPE *yylloc, void *context){ WsCompiler *compiler = (WsCompiler *) context; WsUInt32 ch, ch2; WsBuffer buffer; unsigned char *p; WsBool success; /* Just check that we get the correct amount of arguments. */ gw_assert(compiler->magic == COMPILER_MAGIC); while (ws_stream_getc(compiler->input, &ch)) { /* Save the token's line number. */ yylloc->first_line = compiler->linenum; switch (ch) { case '\t': /* Whitespace characters. */ case '\v': case '\f': case ' ': continue; case '\n': /* Line terminators. */ case '\r': if (ch == '\r' && ws_stream_getc(compiler->input, &ch2)) { if (ch2 != '\n') ws_stream_ungetc(compiler->input, ch2); } compiler->linenum++; continue; case '!': /* !, != */ if (ws_stream_getc(compiler->input, &ch2)) { if (ch2 == '=') return tNE; ws_stream_ungetc(compiler->input, ch2); } return '!'; case '%': /* %, %= */ if (ws_stream_getc(compiler->input, &ch2)) { if (ch2 == '=') return tREMA; ws_stream_ungetc(compiler->input, ch2); } return '%'; case '&': /* &, &&, &= */ if (ws_stream_getc(compiler->input, &ch2)) { if (ch2 == '&') return tAND; if (ch2 == '=') return tANDA; ws_stream_ungetc(compiler->input, ch2); } return '&'; case '*': /* *, *= */ if (ws_stream_getc(compiler->input, &ch2)) { if (ch2 == '=') return tMULA; ws_stream_ungetc(compiler->input, ch2); } return '*'; case '+': /* +, ++, += */ if (ws_stream_getc(compiler->input, &ch2)) { if (ch2 == '+') return tPLUSPLUS; if (ch2 == '=') return tADDA; ws_stream_ungetc(compiler->input, ch2); } return '+'; case '-': /* -, --, -= */ if (ws_stream_getc(compiler->input, &ch2)) { if (ch2 == '-') return tMINUSMINUS; if (ch2 == '=') return tSUBA; ws_stream_ungetc(compiler->input, ch2); } return '-'; case '.': if (ws_stream_getc(compiler->input, &ch2)) { if (WS_IS_DECIMAL_DIGIT(ch2)) { /* DecimalFloatLiteral. */ ws_buffer_init(&buffer); if (!ws_buffer_append_space(&buffer, &p, 2)) { ws_error_memory(compiler); ws_buffer_uninit(&buffer); return EOF; } p[0] = '.'; p[1] = (unsigned char) ch2; success = read_float_from_point(compiler, &buffer, &yylval->vfloat); ws_buffer_uninit(&buffer); if (!success) return EOF; return tFLOAT; } ws_stream_ungetc(compiler->input, ch2); } return '.'; case '/': /* /, /=, block or a single line comment */ if (ws_stream_getc(compiler->input, &ch2)) { if (ch2 == '*') { /* Block comment. */ while (1) { if (!ws_stream_getc(compiler->input, &ch)) { ws_src_error(compiler, 0, "EOF in comment"); return EOF;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -