diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 227baabebb..4955cbc285 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -4,7 +4,9 @@ if( COMPILER_SUPPORTS_WARNINGS ) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARN_FLAGS_C}") endif() -add_subdirectory( libeval libeval_compiler ) +add_subdirectory( libeval ) +add_subdirectory( libeval_compiler ) + include_directories( BEFORE ${INC_BEFORE} ) include_directories( @@ -91,7 +93,7 @@ endif() # a single_top link image. By not linking to common, we control what does # statically go into single_top link images. My current thinking is that only # wxWidgets should be a shared link from single top, everything else should be -# statically bound into it. Otherwise you will have DSO loading problems. After it +# statically bound into it. Otherwise you will have DSO loading probs. After it # sets the LIB PATHS however, we want the *.kiface modules to use shared linking. add_library( singletop STATIC EXCLUDE_FROM_ALL confirm.cpp @@ -423,6 +425,8 @@ target_include_directories( common PRIVATE add_dependencies( common libcontext ) add_dependencies( common version_header ) +add_dependencies( common libeval_grammar ) +add_dependencies( common libeval_grammar2 ) target_link_libraries( common kimath @@ -557,6 +561,7 @@ make_lexer( DRCRULE_T ) + # auto-generate pcbnew_sexpr.h and pcbnew_sexpr.cpp make_lexer( pcbcommon diff --git a/common/drc_rules.keywords b/common/drc_rules.keywords index 9ff5b10de3..8075c026c1 100644 --- a/common/drc_rules.keywords +++ b/common/drc_rules.keywords @@ -1,29 +1,17 @@ -annulus_width -board_edge -buried_via -clearance condition -constraint -disallow -footprint -graphic -hole -match_area -match_layer -match_netclass -match_type max -micro_via min -npth opt -pad -pth +allow rule -selector -text -track -track_width version -via -zone +name +priority +expression +enable +severity +type +error +warning +info +ignore \ No newline at end of file diff --git a/common/libeval/grammar.c b/common/libeval/grammar.c index 3a74c3e28d..c7ca7bbd4e 100644 --- a/common/libeval/grammar.c +++ b/common/libeval/grammar.c @@ -1,65 +1,99 @@ -/* Driver template for the LEMON parser generator. -** The author disclaims copyright to this source code. +/* +** 2000-05-29 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** Driver template for the LEMON parser generator. +** +** The "lemon" program processes an LALR(1) input grammar file, then uses +** this template to construct a parser. The "lemon" program inserts text +** at each "%%" line. Also, any "P-a-r-s-e" identifer prefix (without the +** interstitial "-" characters) contained in this template is changed into +** the value of the %name directive from the grammar. Otherwise, the content +** of this template is copied straight through into the generate parser +** source file. +** +** The following is the concatenation of all %include directives from the +** input grammar file: */ -/* First off, code is included that follows the "include" declaration -** in the input grammar file. */ -#include +#include +#include +/************ Begin %include sections from the grammar ************************/ #line 28 "grammar.lemon" -#include +#include #include -#line 12 "grammar.c" -/* Next is all token values, in a form suitable for use by makeheaders. -** This section will be null unless lemon is run with the -m switch. -*/ -/* -** These constants (all generated automatically by the parser generator) -** specify the various kinds of tokens (terminals) that the parser -** understands. -** -** Each symbol here is a terminal symbol in the grammar. -*/ -/* Make sure the INTERFACE macro is defined. -*/ -#ifndef INTERFACE -# define INTERFACE 1 -#endif -/* The next thing included is series of defines which control +#line 33 "grammar.c" +/**************** End of %include directives **********************************/ +/* These constants specify the various numeric values for terminal symbols +** in a format understandable to "makeheaders". This section is blank unless +** "lemon" is run with the "-m" command-line option. +***************** Begin makeheaders token definitions *************************/ +/**************** End makeheaders token definitions ***************************/ + +/* The next sections is a series of control #defines. ** various aspects of the generated parser. -** YYCODETYPE is the data type used for storing terminal -** and nonterminal numbers. "unsigned char" is -** used if there are fewer than 250 terminals -** and nonterminals. "int" is used otherwise. -** YYNOCODE is a number of type YYCODETYPE which corresponds -** to no legal terminal or nonterminal number. This -** number is used to fill in empty slots of the hash -** table. +** YYCODETYPE is the data type used to store the integer codes +** that represent terminal and non-terminal symbols. +** "unsigned char" is used if there are fewer than +** 256 symbols. Larger types otherwise. +** YYNOCODE is a number of type YYCODETYPE that is not used for +** any terminal or nonterminal symbol. ** YYFALLBACK If defined, this indicates that one or more tokens -** have fall-back values which should be used if the -** original value of the token will not parse. -** YYACTIONTYPE is the data type used for storing terminal -** and nonterminal numbers. "unsigned char" is -** used if there are fewer than 250 rules and -** states combined. "int" is used otherwise. -** ParseTOKENTYPE is the data type used for minor tokens given -** directly to the parser from the tokenizer. -** YYMINORTYPE is the data type used for all minor tokens. +** (also known as: "terminal symbols") have fall-back +** values which should be used if the original symbol +** would not parse. This permits keywords to sometimes +** be used as identifiers, for example. +** YYACTIONTYPE is the data type used for "action codes" - numbers +** that indicate what to do in response to the next +** token. +** ParseTOKENTYPE is the data type used for minor type for terminal +** symbols. Background: A "minor type" is a semantic +** value associated with a terminal or non-terminal +** symbols. For example, for an "ID" terminal symbol, +** the minor type might be the name of the identifier. +** Each non-terminal can have a different minor type. +** Terminal symbols all have the same minor type, though. +** This macros defines the minor type for terminal +** symbols. +** YYMINORTYPE is the data type used for all minor types. ** This is typically a union of many types, one of ** which is ParseTOKENTYPE. The entry in the union -** for base tokens is called "yy0". +** for terminal symbols is called "yy0". ** YYSTACKDEPTH is the maximum depth of the parser's stack. If ** zero the stack is dynamically sized using realloc() ** ParseARG_SDECL A static variable declaration for the %extra_argument ** ParseARG_PDECL A parameter declaration for the %extra_argument +** ParseARG_PARAM Code to pass %extra_argument as a subroutine parameter ** ParseARG_STORE Code to store %extra_argument into yypParser ** ParseARG_FETCH Code to extract %extra_argument from yypParser -** YYNSTATE the combined number of states. -** YYNRULE the number of rules in the grammar +** ParseCTX_* As ParseARG_ except for %extra_context ** YYERRORSYMBOL is the code number of the error symbol. If not ** defined, then do no error processing. +** YYNSTATE the combined number of states. +** YYNRULE the number of rules in the grammar +** YYNTOKEN Number of terminal symbols +** YY_MAX_SHIFT Maximum value for shift actions +** YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions +** YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions +** YY_ERROR_ACTION The yy_action[] code for syntax error +** YY_ACCEPT_ACTION The yy_action[] code for accept +** YY_NO_ACTION The yy_action[] code for no-op +** YY_MIN_REDUCE Minimum value for reduce actions +** YY_MAX_REDUCE Maximum value for reduce actions */ +#ifndef INTERFACE +# define INTERFACE 1 +#endif +/************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned char -#define YYNOCODE 19 +#define YYNOCODE 17 #define YYACTIONTYPE unsigned char #define ParseTOKENTYPE numEval::TokenType typedef union { @@ -71,17 +105,27 @@ typedef union { #endif #define ParseARG_SDECL NUMERIC_EVALUATOR* pEval ; #define ParseARG_PDECL , NUMERIC_EVALUATOR* pEval -#define ParseARG_FETCH NUMERIC_EVALUATOR* pEval = yypParser->pEval -#define ParseARG_STORE yypParser->pEval = pEval -#define YYNSTATE 28 -#define YYNRULE 17 -#define YY_NO_ACTION (YYNSTATE+YYNRULE+2) -#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) -#define YY_ERROR_ACTION (YYNSTATE+YYNRULE) - -/* The yyzerominor constant is used to initialize instances of -** YYMINORTYPE objects to zero. */ -static const YYMINORTYPE yyzerominor = { 0 }; +#define ParseARG_PARAM ,pEval +#define ParseARG_FETCH NUMERIC_EVALUATOR* pEval =yypParser->pEval ; +#define ParseARG_STORE yypParser->pEval =pEval ; +#define ParseCTX_SDECL +#define ParseCTX_PDECL +#define ParseCTX_PARAM +#define ParseCTX_FETCH +#define ParseCTX_STORE +#define YYNSTATE 18 +#define YYNRULE 17 +#define YYNTOKEN 13 +#define YY_MAX_SHIFT 17 +#define YY_MIN_SHIFTREDUCE 28 +#define YY_MAX_SHIFTREDUCE 44 +#define YY_ERROR_ACTION 45 +#define YY_ACCEPT_ACTION 46 +#define YY_NO_ACTION 47 +#define YY_MIN_REDUCE 48 +#define YY_MAX_REDUCE 64 +/************* End control #defines *******************************************/ +#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) /* Define the yytestcase() macro to be a no-op if is not already defined ** otherwise. @@ -104,33 +148,35 @@ static const YYMINORTYPE yyzerominor = { 0 }; ** Suppose the action integer is N. Then the action is determined as ** follows ** -** 0 <= N < YYNSTATE Shift N. That is, push the lookahead +** 0 <= N <= YY_MAX_SHIFT Shift N. That is, push the lookahead ** token onto the stack and goto state N. ** -** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE. +** N between YY_MIN_SHIFTREDUCE Shift to an arbitrary state then +** and YY_MAX_SHIFTREDUCE reduce by rule N-YY_MIN_SHIFTREDUCE. ** -** N == YYNSTATE+YYNRULE A syntax error has occurred. +** N == YY_ERROR_ACTION A syntax error has occurred. ** -** N == YYNSTATE+YYNRULE+1 The parser accepts its input. +** N == YY_ACCEPT_ACTION The parser accepts its input. ** -** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused +** N == YY_NO_ACTION No such action. Denotes unused ** slots in the yy_action[] table. ** +** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE +** and YY_MAX_REDUCE +** ** The action table is constructed as a single large table named yy_action[]. -** Given state S and lookahead X, the action is computed as +** Given state S and lookahead X, the action is computed as either: ** -** yy_action[ yy_shift_ofst[S] + X ] +** (A) N = yy_action[ yy_shift_ofst[S] + X ] +** (B) N = yy_default[S] ** -** If the index value yy_shift_ofst[S]+X is out of range or if the value -** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] -** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table -** and that yy_default[S] should be used instead. +** The (A) formula is preferred. The B formula is used instead if +** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X. ** -** The formula above is for computing the action when the lookahead is +** The formulas above are for computing the action when the lookahead is ** a terminal symbol. If the lookahead is a non-terminal (as occurs after ** a reduce action) then the yy_reduce_ofst[] array is used in place of -** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of -** YY_SHIFT_USE_DFLT. +** the yy_shift_ofst[] array. ** ** The following are the tables generated in this section: ** @@ -142,47 +188,47 @@ static const YYMINORTYPE yyzerominor = { 0 }; ** yy_reduce_ofst[] For each state, the offset into yy_action for ** shifting non-terminals after a reduce. ** yy_default[] Default action for each state. -*/ -#define YY_ACTTAB_COUNT (58) +** +*********** Begin parsing tables **********************************************/ +#define YY_ACTTAB_COUNT (54) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 24, 9, 8, 23, 6, 7, 25, 28, 17, 16, - /* 10 */ 17, 4, 5, 4, 5, 3, 26, 22, 2, 22, - /* 20 */ 2, 9, 8, 23, 6, 7, 47, 17, 15, 19, - /* 30 */ 4, 5, 21, 20, 47, 26, 22, 2, 27, 10, - /* 40 */ 9, 8, 23, 6, 7, 46, 1, 18, 10, 23, - /* 50 */ 6, 7, 47, 47, 14, 13, 12, 11, + /* 0 */ 61, 17, 63, 10, 4, 5, 11, 12, 13, 44, + /* 10 */ 30, 2, 14, 29, 9, 8, 31, 6, 7, 28, + /* 20 */ 17, 59, 17, 4, 5, 4, 5, 58, 44, 30, + /* 30 */ 2, 30, 2, 9, 8, 31, 6, 7, 31, 6, + /* 40 */ 7, 40, 9, 8, 31, 6, 7, 46, 1, 1, + /* 50 */ 10, 15, 16, 3, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 3, 4, 5, 6, 7, 8, 9, 0, 1, 17, - /* 10 */ 1, 4, 5, 4, 5, 2, 9, 10, 11, 10, - /* 20 */ 11, 4, 5, 6, 7, 8, 18, 1, 17, 12, - /* 30 */ 4, 5, 17, 17, 18, 9, 10, 11, 16, 17, - /* 40 */ 4, 5, 6, 7, 8, 14, 15, 16, 17, 6, - /* 50 */ 7, 8, 18, 18, 17, 17, 17, 17, + /* 0 */ 0, 1, 15, 16, 4, 5, 16, 16, 16, 9, + /* 10 */ 10, 11, 16, 3, 4, 5, 6, 7, 8, 9, + /* 20 */ 1, 16, 1, 4, 5, 4, 5, 16, 9, 10, + /* 30 */ 11, 10, 11, 4, 5, 6, 7, 8, 6, 7, + /* 40 */ 8, 12, 4, 5, 6, 7, 8, 13, 14, 15, + /* 50 */ 16, 16, 16, 2, 17, 17, 17, 17, 17, 17, + /* 60 */ 17, 17, 17, 17, 17, 17, 17, }; -#define YY_SHIFT_USE_DFLT (-4) -#define YY_SHIFT_COUNT (17) -#define YY_SHIFT_MIN (-3) -#define YY_SHIFT_MAX (43) -static const signed char yy_shift_ofst[] = { - /* 0 */ 26, 7, 9, 9, 9, 9, 9, 9, 9, 9, - /* 10 */ -3, 17, 36, 43, 43, 43, 43, 13, +#define YY_SHIFT_COUNT (17) +#define YY_SHIFT_MIN (0) +#define YY_SHIFT_MAX (51) +static const unsigned char yy_shift_ofst[] = { + /* 0 */ 19, 0, 21, 21, 21, 21, 21, 21, 21, 21, + /* 10 */ 10, 29, 38, 32, 32, 32, 32, 51, }; -#define YY_REDUCE_USE_DFLT (-9) #define YY_REDUCE_COUNT (9) -#define YY_REDUCE_MIN (-8) -#define YY_REDUCE_MAX (40) +#define YY_REDUCE_MIN (-13) +#define YY_REDUCE_MAX (36) static const signed char yy_reduce_ofst[] = { - /* 0 */ 31, 22, 40, 39, 38, 37, 16, 15, 11, -8, + /* 0 */ 34, -13, -10, -9, -8, -4, 5, 11, 35, 36, }; static const YYACTIONTYPE yy_default[] = { /* 0 */ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - /* 10 */ 45, 45, 39, 37, 36, 41, 40, 38, 29, 44, - /* 20 */ 43, 42, 34, 35, 33, 32, 31, 30, + /* 10 */ 45, 45, 55, 53, 52, 57, 56, 54, }; +/********** End of lemon-generated parsing tables *****************************/ -/* The next table maps tokens into fallback tokens. If a construct -** like the following: +/* The next table maps tokens (terminal symbols) into fallback tokens. +** If a construct like the following: ** ** %fallback ID X Y Z. ** @@ -190,6 +236,10 @@ static const YYACTIONTYPE yy_default[] = { ** and Z. Whenever one of the tokens X, Y, or Z is input to the parser ** but it does not parse, the type of the token is changed to ID and ** the parse is retried before an error is thrown. +** +** This feature can be used, for example, to cause some keywords in a language +** to revert to identifiers if they keyword does not apply in the context where +** it appears. */ #ifdef YYFALLBACK static const YYCODETYPE yyFallback[] = { @@ -207,9 +257,13 @@ static const YYCODETYPE yyFallback[] = { ** + The semantic value stored at this level of the stack. This is ** the information used by the action routines in the grammar. ** It is sometimes called the "minor" token. +** +** After the "shift" half of a SHIFTREDUCE action, the stateno field +** actually contains the reduce action for the second half of the +** SHIFTREDUCE. */ struct yyStackEntry { - YYACTIONTYPE stateno; /* The state-number */ + YYACTIONTYPE stateno; /* The state-number, or reduce action in SHIFTREDUCE */ YYCODETYPE major; /* The major token value. This is the code ** number for the token at this stack level */ YYMINORTYPE minor; /* The user-supplied minor token value. This @@ -220,23 +274,28 @@ typedef struct yyStackEntry yyStackEntry; /* The state of the parser is completely contained in an instance of ** the following structure */ struct yyParser { - int yyidx; /* Index of top element in stack */ + yyStackEntry *yytos; /* Pointer to top element of the stack */ #ifdef YYTRACKMAXSTACKDEPTH - int yyidxMax; /* Maximum value of yyidx */ + int yyhwm; /* High-water mark of the stack */ #endif +#ifndef YYNOERRORRECOVERY int yyerrcnt; /* Shifts left before out of the error */ +#endif ParseARG_SDECL /* A place to hold %extra_argument */ + ParseCTX_SDECL /* A place to hold %extra_context */ #if YYSTACKDEPTH<=0 int yystksz; /* Current side of the stack */ yyStackEntry *yystack; /* The parser's stack */ + yyStackEntry yystk0; /* First stack entry */ #else yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ + yyStackEntry *yystackEnd; /* Last entry in the stack */ #endif }; typedef struct yyParser yyParser; #ifndef NDEBUG -#include +#include static FILE *yyTraceFILE = 0; static char *yyTracePrompt = 0; #endif /* NDEBUG */ @@ -267,66 +326,126 @@ void ParseTrace(FILE *TraceFILE, char *zTracePrompt){ } #endif /* NDEBUG */ -#ifndef NDEBUG +#if defined(YYCOVERAGE) || !defined(NDEBUG) /* For tracing shifts, the names of all terminals and nonterminals ** are required. The following table supplies these names */ static const char *const yyTokenName[] = { - "$", "VAR", "ASSIGN", "SEMCOL", - "PLUS", "MINUS", "UNIT", "DIVIDE", - "MULT", "ENDS", "VALUE", "PARENL", - "PARENR", "error", "main", "in", - "stmt", "expr", + /* 0 */ "$", + /* 1 */ "VAR", + /* 2 */ "ASSIGN", + /* 3 */ "SEMCOL", + /* 4 */ "PLUS", + /* 5 */ "MINUS", + /* 6 */ "UNIT", + /* 7 */ "DIVIDE", + /* 8 */ "MULT", + /* 9 */ "ENDS", + /* 10 */ "VALUE", + /* 11 */ "PARENL", + /* 12 */ "PARENR", + /* 13 */ "main", + /* 14 */ "in", + /* 15 */ "stmt", + /* 16 */ "expr", }; -#endif /* NDEBUG */ +#endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ #ifndef NDEBUG /* For tracing reduce actions, the names of all rules are required. */ static const char *const yyRuleName[] = { - /* 0 */ "main ::= in", - /* 1 */ "in ::= stmt", - /* 2 */ "in ::= in stmt", - /* 3 */ "stmt ::= ENDS", - /* 4 */ "stmt ::= expr ENDS", - /* 5 */ "stmt ::= expr SEMCOL", - /* 6 */ "expr ::= VALUE", - /* 7 */ "expr ::= expr UNIT", - /* 8 */ "expr ::= MINUS expr", - /* 9 */ "expr ::= PLUS expr", - /* 10 */ "expr ::= VAR", - /* 11 */ "expr ::= VAR ASSIGN expr", - /* 12 */ "expr ::= expr PLUS expr", - /* 13 */ "expr ::= expr MINUS expr", - /* 14 */ "expr ::= expr MULT expr", - /* 15 */ "expr ::= expr DIVIDE expr", - /* 16 */ "expr ::= PARENL expr PARENR", + /* 0 */ "stmt ::= expr ENDS", + /* 1 */ "stmt ::= expr SEMCOL", + /* 2 */ "expr ::= VALUE", + /* 3 */ "expr ::= expr UNIT", + /* 4 */ "expr ::= MINUS expr", + /* 5 */ "expr ::= PLUS expr", + /* 6 */ "expr ::= VAR", + /* 7 */ "expr ::= VAR ASSIGN expr", + /* 8 */ "expr ::= expr PLUS expr", + /* 9 */ "expr ::= expr MINUS expr", + /* 10 */ "expr ::= expr MULT expr", + /* 11 */ "expr ::= expr DIVIDE expr", + /* 12 */ "expr ::= PARENL expr PARENR", + /* 13 */ "main ::= in", + /* 14 */ "in ::= stmt", + /* 15 */ "in ::= in stmt", + /* 16 */ "stmt ::= ENDS", }; #endif /* NDEBUG */ #if YYSTACKDEPTH<=0 /* -** Try to increase the size of the parser stack. +** Try to increase the size of the parser stack. Return the number +** of errors. Return 0 on success. */ -static void yyGrowStack(yyParser *p){ +static int yyGrowStack(yyParser *p){ int newSize; + int idx; yyStackEntry *pNew; newSize = p->yystksz*2 + 100; - pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); + idx = p->yytos ? (int)(p->yytos - p->yystack) : 0; + if( p->yystack==&p->yystk0 ){ + pNew = malloc(newSize*sizeof(pNew[0])); + if( pNew ) pNew[0] = p->yystk0; + }else{ + pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); + } if( pNew ){ p->yystack = pNew; - p->yystksz = newSize; + p->yytos = &p->yystack[idx]; #ifndef NDEBUG if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack grows to %d entries!\n", - yyTracePrompt, p->yystksz); + fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n", + yyTracePrompt, p->yystksz, newSize); } #endif + p->yystksz = newSize; } + return pNew==0; } #endif +/* Datatype of the argument to the memory allocated passed as the +** second argument to ParseAlloc() below. This can be changed by +** putting an appropriate #define in the %include section of the input +** grammar. +*/ +#ifndef YYMALLOCARGTYPE +# define YYMALLOCARGTYPE size_t +#endif + +/* Initialize a new parser that has already been allocated. +*/ +void ParseInit(void *yypRawParser ParseCTX_PDECL){ + yyParser *yypParser = (yyParser*)yypRawParser; + ParseCTX_STORE +#ifdef YYTRACKMAXSTACKDEPTH + yypParser->yyhwm = 0; +#endif +#if YYSTACKDEPTH<=0 + yypParser->yytos = NULL; + yypParser->yystack = NULL; + yypParser->yystksz = 0; + if( yyGrowStack(yypParser) ){ + yypParser->yystack = &yypParser->yystk0; + yypParser->yystksz = 1; + } +#endif +#ifndef YYNOERRORRECOVERY + yypParser->yyerrcnt = -1; +#endif + yypParser->yytos = yypParser->yystack; + yypParser->yystack[0].stateno = 0; + yypParser->yystack[0].major = 0; +#if YYSTACKDEPTH>0 + yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1]; +#endif +} + +#ifndef Parse_ENGINEALWAYSONSTACK /* ** This function allocates a new parser. ** The only argument is a pointer to a function which works like @@ -339,34 +458,32 @@ static void yyGrowStack(yyParser *p){ ** A pointer to a parser. This pointer is used in subsequent calls ** to Parse and ParseFree. */ -void *ParseAlloc(void *(*mallocProc)(size_t)){ - yyParser *pParser; - pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) ); - if( pParser ){ - pParser->yyidx = -1; -#ifdef YYTRACKMAXSTACKDEPTH - pParser->yyidxMax = 0; -#endif -#if YYSTACKDEPTH<=0 - pParser->yystack = NULL; - pParser->yystksz = 0; - yyGrowStack(pParser); -#endif +void *ParseAlloc(void *(*mallocProc)(YYMALLOCARGTYPE) ParseCTX_PDECL){ + yyParser *yypParser; + yypParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) ); + if( yypParser ){ + ParseCTX_STORE + ParseInit(yypParser ParseCTX_PARAM); } - return pParser; + return (void*)yypParser; } +#endif /* Parse_ENGINEALWAYSONSTACK */ -/* The following function deletes the value associated with a -** symbol. The symbol can be either a terminal or nonterminal. -** "yymajor" is the symbol code, and "yypminor" is a pointer to -** the value. + +/* The following function deletes the "minor type" or semantic value +** associated with a symbol. The symbol can be either a terminal +** or nonterminal. "yymajor" is the symbol code, and "yypminor" is +** a pointer to the value to be deleted. The code used to do the +** deletions is derived from the %destructor and/or %token_destructor +** directives of the input grammar. */ static void yy_destructor( yyParser *yypParser, /* The parser */ YYCODETYPE yymajor, /* Type code for object to destroy */ YYMINORTYPE *yypminor /* The object to be destroyed */ ){ - ParseARG_FETCH; + ParseARG_FETCH + ParseCTX_FETCH switch( yymajor ){ /* Here is inserted the actions which take place when a ** terminal or non-terminal is destroyed. This can happen @@ -375,9 +492,11 @@ static void yy_destructor( ** being destroyed before it is finished parsing. ** ** Note: during a reduce, the only symbols destroyed are those - ** which appear on the RHS of the rule, but which are not used + ** which appear on the RHS of the rule, but which are *not* used ** inside the C code. */ +/********* Begin destructor definitions ***************************************/ +/********* End destructor definitions *****************************************/ default: break; /* If no destructor action specified: do nothing */ } } @@ -387,51 +506,53 @@ static void yy_destructor( ** ** If there is a destructor routine associated with the token which ** is popped from the stack, then call it. -** -** Return the major token number for the symbol popped. */ -static int yy_pop_parser_stack(yyParser *pParser){ - YYCODETYPE yymajor; - yyStackEntry *yytos = &pParser->yystack[pParser->yyidx]; - - if( pParser->yyidx<0 ) return 0; +static void yy_pop_parser_stack(yyParser *pParser){ + yyStackEntry *yytos; + assert( pParser->yytos!=0 ); + assert( pParser->yytos > pParser->yystack ); + yytos = pParser->yytos--; #ifndef NDEBUG - if( yyTraceFILE && pParser->yyidx>=0 ){ + if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sPopping %s\n", yyTracePrompt, yyTokenName[yytos->major]); } #endif - yymajor = yytos->major; - yy_destructor(pParser, yymajor, &yytos->minor); - pParser->yyidx--; - return yymajor; + yy_destructor(pParser, yytos->major, &yytos->minor); } +/* +** Clear all secondary memory allocations from the parser +*/ +void ParseFinalize(void *p){ + yyParser *pParser = (yyParser*)p; + while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser); +#if YYSTACKDEPTH<=0 + if( pParser->yystack!=&pParser->yystk0 ) free(pParser->yystack); +#endif +} + +#ifndef Parse_ENGINEALWAYSONSTACK /* -** Deallocate and destroy a parser. Destructors are all called for +** Deallocate and destroy a parser. Destructors are called for ** all stack elements before shutting the parser down. ** -** Inputs: -**
    -**
  • A pointer to the parser. This should be a pointer -** obtained from ParseAlloc. -**
  • A pointer to a function used to reclaim memory obtained -** from malloc. -**
+** If the YYPARSEFREENEVERNULL macro exists (for example because it +** is defined in a %include section of the input grammar) then it is +** assumed that the input pointer is never NULL. */ void ParseFree( void *p, /* The parser to be deleted */ void (*freeProc)(void*) /* Function used to reclaim memory */ ){ - yyParser *pParser = (yyParser*)p; - if( pParser==0 ) return; - while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); -#if YYSTACKDEPTH<=0 - free(pParser->yystack); +#ifndef YYPARSEFREENEVERNULL + if( p==0 ) return; #endif - (*freeProc)((void*)pParser); + ParseFinalize(p); + (*freeProc)(p); } +#endif /* Parse_ENGINEALWAYSONSTACK */ /* ** Return the peak depth of the stack for a parser. @@ -439,33 +560,70 @@ void ParseFree( #ifdef YYTRACKMAXSTACKDEPTH int ParseStackPeak(void *p){ yyParser *pParser = (yyParser*)p; - return pParser->yyidxMax; + return pParser->yyhwm; +} +#endif + +/* This array of booleans keeps track of the parser statement +** coverage. The element yycoverage[X][Y] is set when the parser +** is in state X and has a lookahead token Y. In a well-tested +** systems, every element of this matrix should end up being set. +*/ +#if defined(YYCOVERAGE) +static unsigned char yycoverage[YYNSTATE][YYNTOKEN]; +#endif + +/* +** Write into out a description of every state/lookahead combination that +** +** (1) has not been used by the parser, and +** (2) is not a syntax error. +** +** Return the number of missed state/lookahead combinations. +*/ +#if defined(YYCOVERAGE) +int ParseCoverage(FILE *out){ + int stateno, iLookAhead, i; + int nMissed = 0; + for(stateno=0; statenoyystack[pParser->yyidx].stateno; - - if( stateno>YY_SHIFT_COUNT - || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ - return yy_default[stateno]; - } - assert( iLookAhead!=YYNOCODE ); - i += iLookAhead; - if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){ - if( iLookAhead>0 ){ + + if( stateno>YY_MAX_SHIFT ) return stateno; + assert( stateno <= YY_SHIFT_COUNT ); +#if defined(YYCOVERAGE) + yycoverage[stateno][iLookAhead] = 1; +#endif + do{ + i = yy_shift_ofst[stateno]; + assert( i>=0 ); + /* assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD ); */ + assert( iLookAhead!=YYNOCODE ); + assert( iLookAhead < YYNTOKEN ); + i += iLookAhead; + if( i>=YY_NLOOKAHEAD || yy_lookahead[i]!=iLookAhead ){ #ifdef YYFALLBACK YYCODETYPE iFallback; /* Fallback token */ if( iLookAhead=YY_ACTTAB_COUNT j0 ){ #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]); + yyTracePrompt, yyTokenName[iLookAhead], + yyTokenName[YYWILDCARD]); } #endif /* NDEBUG */ return yy_action[j]; } } #endif /* YYWILDCARD */ + return yy_default[stateno]; + }else{ + return yy_action[i]; } - return yy_default[stateno]; - }else{ - return yy_action[i]; - } + }while(1); } /* ** Find the appropriate action for a parser given the non-terminal ** look-ahead token iLookAhead. -** -** If the look-ahead token is YYNOCODE, then check to see if the action is -** independent of the look-ahead. If it is, return the action, otherwise -** return YY_NO_ACTION. */ -static int yy_find_reduce_action( - int stateno, /* Current state number */ +static YYACTIONTYPE yy_find_reduce_action( + YYACTIONTYPE stateno, /* Current state number */ YYCODETYPE iLookAhead /* The look-ahead token */ ){ int i; @@ -529,7 +687,6 @@ static int yy_find_reduce_action( assert( stateno<=YY_REDUCE_COUNT ); #endif i = yy_reduce_ofst[stateno]; - assert( i!=YY_REDUCE_USE_DFLT ); assert( iLookAhead!=YYNOCODE ); i += iLookAhead; #ifdef YYERRORSYMBOL @@ -546,90 +703,128 @@ static int yy_find_reduce_action( /* ** The following routine is called if the stack overflows. */ -static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){ - ParseARG_FETCH; - yypParser->yyidx--; +static void yyStackOverflow(yyParser *yypParser){ + ParseARG_FETCH + ParseCTX_FETCH #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); } #endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser); /* Here code is inserted which will execute if the parser ** stack every overflows */ - ParseARG_STORE; /* Suppress warning about unused %extra_argument var */ +/******** Begin %stack_overflow code ******************************************/ +/******** End %stack_overflow code ********************************************/ + ParseARG_STORE /* Suppress warning about unused %extra_argument var */ + ParseCTX_STORE } +/* +** Print tracing information for a SHIFT action +*/ +#ifndef NDEBUG +static void yyTraceShift(yyParser *yypParser, int yyNewState, const char *zTag){ + if( yyTraceFILE ){ + if( yyNewStateyytos->major], + yyNewState); + }else{ + fprintf(yyTraceFILE,"%s%s '%s', pending reduce %d\n", + yyTracePrompt, zTag, yyTokenName[yypParser->yytos->major], + yyNewState - YY_MIN_REDUCE); + } + } +} +#else +# define yyTraceShift(X,Y,Z) +#endif + /* ** Perform a shift action. */ static void yy_shift( yyParser *yypParser, /* The parser to be shifted */ - int yyNewState, /* The new state to shift in */ - int yyMajor, /* The major token to shift in */ - YYMINORTYPE *yypMinor /* Pointer to the minor token to shift in */ + YYACTIONTYPE yyNewState, /* The new state to shift in */ + YYCODETYPE yyMajor, /* The major token to shift in */ + ParseTOKENTYPE yyMinor /* The minor token to shift in */ ){ yyStackEntry *yytos; - yypParser->yyidx++; + yypParser->yytos++; #ifdef YYTRACKMAXSTACKDEPTH - if( yypParser->yyidx>yypParser->yyidxMax ){ - yypParser->yyidxMax = yypParser->yyidx; + if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){ + yypParser->yyhwm++; + assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack) ); } #endif #if YYSTACKDEPTH>0 - if( yypParser->yyidx>=YYSTACKDEPTH ){ - yyStackOverflow(yypParser, yypMinor); + if( yypParser->yytos>yypParser->yystackEnd ){ + yypParser->yytos--; + yyStackOverflow(yypParser); return; } #else - if( yypParser->yyidx>=yypParser->yystksz ){ - yyGrowStack(yypParser); - if( yypParser->yyidx>=yypParser->yystksz ){ - yyStackOverflow(yypParser, yypMinor); + if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){ + if( yyGrowStack(yypParser) ){ + yypParser->yytos--; + yyStackOverflow(yypParser); return; } } #endif - yytos = &yypParser->yystack[yypParser->yyidx]; - yytos->stateno = (YYACTIONTYPE)yyNewState; - yytos->major = (YYCODETYPE)yyMajor; - yytos->minor = *yypMinor; -#ifndef NDEBUG - if( yyTraceFILE && yypParser->yyidx>0 ){ - int i; - fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState); - fprintf(yyTraceFILE,"%sStack:",yyTracePrompt); - for(i=1; i<=yypParser->yyidx; i++) - fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]); - fprintf(yyTraceFILE,"\n"); + if( yyNewState > YY_MAX_SHIFT ){ + yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE; } -#endif + yytos = yypParser->yytos; + yytos->stateno = yyNewState; + yytos->major = yyMajor; + yytos->minor.yy0 = yyMinor; + yyTraceShift(yypParser, yyNewState, "Shift"); } -/* The following table contains information about every rule that -** is used during the reduce. -*/ -static const struct { - YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ - unsigned char nrhs; /* Number of right-hand side symbols in the rule */ -} yyRuleInfo[] = { - { 14, 1 }, - { 15, 1 }, - { 15, 2 }, - { 16, 1 }, - { 16, 2 }, - { 16, 2 }, - { 17, 1 }, - { 17, 2 }, - { 17, 2 }, - { 17, 2 }, - { 17, 1 }, - { 17, 3 }, - { 17, 3 }, - { 17, 3 }, - { 17, 3 }, - { 17, 3 }, - { 17, 3 }, +/* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side +** of that rule */ +static const YYCODETYPE yyRuleInfoLhs[] = { + 15, /* (0) stmt ::= expr ENDS */ + 15, /* (1) stmt ::= expr SEMCOL */ + 16, /* (2) expr ::= VALUE */ + 16, /* (3) expr ::= expr UNIT */ + 16, /* (4) expr ::= MINUS expr */ + 16, /* (5) expr ::= PLUS expr */ + 16, /* (6) expr ::= VAR */ + 16, /* (7) expr ::= VAR ASSIGN expr */ + 16, /* (8) expr ::= expr PLUS expr */ + 16, /* (9) expr ::= expr MINUS expr */ + 16, /* (10) expr ::= expr MULT expr */ + 16, /* (11) expr ::= expr DIVIDE expr */ + 16, /* (12) expr ::= PARENL expr PARENR */ + 13, /* (13) main ::= in */ + 14, /* (14) in ::= stmt */ + 14, /* (15) in ::= in stmt */ + 15, /* (16) stmt ::= ENDS */ +}; + +/* For rule J, yyRuleInfoNRhs[J] contains the negative of the number +** of symbols on the right-hand side of that rule. */ +static const signed char yyRuleInfoNRhs[] = { + -2, /* (0) stmt ::= expr ENDS */ + -2, /* (1) stmt ::= expr SEMCOL */ + -1, /* (2) expr ::= VALUE */ + -2, /* (3) expr ::= expr UNIT */ + -2, /* (4) expr ::= MINUS expr */ + -2, /* (5) expr ::= PLUS expr */ + -1, /* (6) expr ::= VAR */ + -3, /* (7) expr ::= VAR ASSIGN expr */ + -3, /* (8) expr ::= expr PLUS expr */ + -3, /* (9) expr ::= expr MINUS expr */ + -3, /* (10) expr ::= expr MULT expr */ + -3, /* (11) expr ::= expr DIVIDE expr */ + -3, /* (12) expr ::= PARENL expr PARENR */ + -1, /* (13) main ::= in */ + -1, /* (14) in ::= stmt */ + -2, /* (15) in ::= in stmt */ + -1, /* (16) stmt ::= ENDS */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -637,43 +832,73 @@ static void yy_accept(yyParser*); /* Forward Declaration */ /* ** Perform a reduce action and the shift that must immediately ** follow the reduce. +** +** The yyLookahead and yyLookaheadToken parameters provide reduce actions +** access to the lookahead token (if any). The yyLookahead will be YYNOCODE +** if the lookahead token has already been consumed. As this procedure is +** only called from one place, optimizing compilers will in-line it, which +** means that the extra parameters have no performance impact. */ -static void yy_reduce( +static YYACTIONTYPE yy_reduce( yyParser *yypParser, /* The parser */ - int yyruleno /* Number of the rule by which to reduce */ + unsigned int yyruleno, /* Number of the rule by which to reduce */ + int yyLookahead, /* Lookahead token, or YYNOCODE if none */ + ParseTOKENTYPE yyLookaheadToken /* Value of the lookahead token */ + ParseCTX_PDECL /* %extra_context */ ){ int yygoto; /* The next state */ - int yyact; /* The next action */ - YYMINORTYPE yygotominor; /* The LHS of the rule reduced */ + YYACTIONTYPE yyact; /* The next action */ yyStackEntry *yymsp; /* The top of the parser's stack */ int yysize; /* Amount to pop the stack */ - ParseARG_FETCH; - yymsp = &yypParser->yystack[yypParser->yyidx]; + ParseARG_FETCH + (void)yyLookahead; + (void)yyLookaheadToken; + yymsp = yypParser->yytos; #ifndef NDEBUG - if( yyTraceFILE && yyruleno>=0 - && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ - fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, - yyRuleName[yyruleno]); + if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ + yysize = yyRuleInfoNRhs[yyruleno]; + if( yysize ){ + fprintf(yyTraceFILE, "%sReduce %d [%s], go to state %d.\n", + yyTracePrompt, + yyruleno, yyRuleName[yyruleno], yymsp[yysize].stateno); + }else{ + fprintf(yyTraceFILE, "%sReduce %d [%s].\n", + yyTracePrompt, yyruleno, yyRuleName[yyruleno]); + } } #endif /* NDEBUG */ - /* Silence complaints from purify about yygotominor being uninitialized - ** in some cases when it is copied into the stack after the following - ** switch. yygotominor is uninitialized when a rule reduces that does - ** not set the value of its left-hand side nonterminal. Leaving the - ** value of the nonterminal uninitialized is utterly harmless as long - ** as the value is never used. So really the only thing this code - ** accomplishes is to quieten purify. - ** - ** 2007-01-16: The wireshark project (www.wireshark.org) reports that - ** without this code, their parser segfaults. I'm not sure what there - ** parser is doing to make this happen. This is the second bug report - ** from wireshark this week. Clearly they are stressing Lemon in ways - ** that it has not been previously stressed... (SQLite ticket #2172) - */ - /*memset(&yygotominor, 0, sizeof(yygotominor));*/ - yygotominor = yyzerominor; - + /* Check that the stack is large enough to grow by a single entry + ** if the RHS of the rule is empty. This ensures that there is room + ** enough on the stack to push the LHS value */ + if( yyRuleInfoNRhs[yyruleno]==0 ){ +#ifdef YYTRACKMAXSTACKDEPTH + if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){ + yypParser->yyhwm++; + assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack)); + } +#endif +#if YYSTACKDEPTH>0 + if( yypParser->yytos>=yypParser->yystackEnd ){ + yyStackOverflow(yypParser); + /* The call to yyStackOverflow() above pops the stack until it is + ** empty, causing the main parser loop to exit. So the return value + ** is never used and does not matter. */ + return 0; + } +#else + if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ + if( yyGrowStack(yypParser) ){ + yyStackOverflow(yypParser); + /* The call to yyStackOverflow() above pops the stack until it is + ** empty, causing the main parser loop to exit. So the return value + ** is never used and does not matter. */ + return 0; + } + yymsp = yypParser->yytos; + } +#endif + } switch( yyruleno ){ /* Beginning here are the reduction cases. A typical example @@ -684,109 +909,113 @@ static void yy_reduce( ** #line ** break; */ - case 4: /* stmt ::= expr ENDS */ +/********** Begin reduce actions **********************************************/ + YYMINORTYPE yylhsminor; + case 0: /* stmt ::= expr ENDS */ #line 49 "grammar.lemon" { pEval->parseSetResult(yymsp[-1].minor.yy0.valid ? yymsp[-1].minor.yy0.dValue : NAN); } -#line 691 "grammar.c" +#line 918 "grammar.c" break; - case 5: /* stmt ::= expr SEMCOL */ + case 1: /* stmt ::= expr SEMCOL */ #line 50 "grammar.lemon" { pEval->parseSetResult(NAN); } -#line 696 "grammar.c" +#line 923 "grammar.c" break; - case 6: /* expr ::= VALUE */ + case 2: /* expr ::= VALUE */ #line 52 "grammar.lemon" -{ yygotominor.yy0.dValue = yymsp[0].minor.yy0.dValue; yygotominor.yy0.valid=true; } -#line 701 "grammar.c" +{ yylhsminor.yy0.dValue = yymsp[0].minor.yy0.dValue; yylhsminor.yy0.valid=true; } +#line 928 "grammar.c" + yymsp[0].minor.yy0 = yylhsminor.yy0; break; - case 7: /* expr ::= expr UNIT */ + case 3: /* expr ::= expr UNIT */ #line 53 "grammar.lemon" -{ yygotominor.yy0.dValue = yymsp[-1].minor.yy0.dValue * yymsp[0].minor.yy0.dValue; yygotominor.yy0.valid=yymsp[-1].minor.yy0.valid; } -#line 706 "grammar.c" +{ yylhsminor.yy0.dValue = yymsp[-1].minor.yy0.dValue * yymsp[0].minor.yy0.dValue; yylhsminor.yy0.valid=yymsp[-1].minor.yy0.valid; } +#line 934 "grammar.c" + yymsp[-1].minor.yy0 = yylhsminor.yy0; break; - case 8: /* expr ::= MINUS expr */ + case 4: /* expr ::= MINUS expr */ #line 54 "grammar.lemon" -{ yygotominor.yy0.dValue = -yymsp[0].minor.yy0.dValue; yygotominor.yy0.valid=yymsp[0].minor.yy0.valid; } -#line 711 "grammar.c" +{ yymsp[-1].minor.yy0.dValue = -yymsp[0].minor.yy0.dValue; yymsp[-1].minor.yy0.valid=yymsp[0].minor.yy0.valid; } +#line 940 "grammar.c" break; - case 9: /* expr ::= PLUS expr */ + case 5: /* expr ::= PLUS expr */ #line 55 "grammar.lemon" -{ yygotominor.yy0.dValue = yymsp[0].minor.yy0.dValue; yygotominor.yy0.valid=yymsp[0].minor.yy0.valid; } -#line 716 "grammar.c" +{ yymsp[-1].minor.yy0.dValue = yymsp[0].minor.yy0.dValue; yymsp[-1].minor.yy0.valid=yymsp[0].minor.yy0.valid; } +#line 945 "grammar.c" break; - case 10: /* expr ::= VAR */ + case 6: /* expr ::= VAR */ #line 56 "grammar.lemon" -{ yygotominor.yy0.dValue = pEval->GetVar(yymsp[0].minor.yy0.text); yygotominor.yy0.valid=true; } -#line 721 "grammar.c" +{ yylhsminor.yy0.dValue = pEval->GetVar(yymsp[0].minor.yy0.text); yylhsminor.yy0.valid=true; } +#line 950 "grammar.c" + yymsp[0].minor.yy0 = yylhsminor.yy0; break; - case 11: /* expr ::= VAR ASSIGN expr */ + case 7: /* expr ::= VAR ASSIGN expr */ #line 57 "grammar.lemon" -{ pEval->SetVar(yymsp[-2].minor.yy0.text, yymsp[0].minor.yy0.dValue); yygotominor.yy0.dValue = yymsp[0].minor.yy0.dValue; yygotominor.yy0.valid=false; } -#line 726 "grammar.c" +{ pEval->SetVar(yymsp[-2].minor.yy0.text, yymsp[0].minor.yy0.dValue); yylhsminor.yy0.dValue = yymsp[0].minor.yy0.dValue; yylhsminor.yy0.valid=false; } +#line 956 "grammar.c" + yymsp[-2].minor.yy0 = yylhsminor.yy0; break; - case 12: /* expr ::= expr PLUS expr */ + case 8: /* expr ::= expr PLUS expr */ #line 58 "grammar.lemon" -{ yygotominor.yy0.dValue = yymsp[-2].minor.yy0.dValue + yymsp[0].minor.yy0.dValue; yygotominor.yy0.valid=yymsp[0].minor.yy0.valid; } -#line 731 "grammar.c" +{ yylhsminor.yy0.dValue = yymsp[-2].minor.yy0.dValue + yymsp[0].minor.yy0.dValue; yylhsminor.yy0.valid=yymsp[0].minor.yy0.valid; } +#line 962 "grammar.c" + yymsp[-2].minor.yy0 = yylhsminor.yy0; break; - case 13: /* expr ::= expr MINUS expr */ + case 9: /* expr ::= expr MINUS expr */ #line 59 "grammar.lemon" -{ yygotominor.yy0.dValue = yymsp[-2].minor.yy0.dValue - yymsp[0].minor.yy0.dValue; yygotominor.yy0.valid=yymsp[0].minor.yy0.valid; } -#line 736 "grammar.c" +{ yylhsminor.yy0.dValue = yymsp[-2].minor.yy0.dValue - yymsp[0].minor.yy0.dValue; yylhsminor.yy0.valid=yymsp[0].minor.yy0.valid; } +#line 968 "grammar.c" + yymsp[-2].minor.yy0 = yylhsminor.yy0; break; - case 14: /* expr ::= expr MULT expr */ + case 10: /* expr ::= expr MULT expr */ #line 60 "grammar.lemon" -{ yygotominor.yy0.dValue = yymsp[-2].minor.yy0.dValue * yymsp[0].minor.yy0.dValue; yygotominor.yy0.valid=yymsp[0].minor.yy0.valid; } -#line 741 "grammar.c" +{ yylhsminor.yy0.dValue = yymsp[-2].minor.yy0.dValue * yymsp[0].minor.yy0.dValue; yylhsminor.yy0.valid=yymsp[0].minor.yy0.valid; } +#line 974 "grammar.c" + yymsp[-2].minor.yy0 = yylhsminor.yy0; break; - case 15: /* expr ::= expr DIVIDE expr */ + case 11: /* expr ::= expr DIVIDE expr */ #line 61 "grammar.lemon" { if (yymsp[0].minor.yy0.dValue != 0.0) { - yygotominor.yy0.dValue = yymsp[-2].minor.yy0.dValue / yymsp[0].minor.yy0.dValue; + yylhsminor.yy0.dValue = yymsp[-2].minor.yy0.dValue / yymsp[0].minor.yy0.dValue; } else pEval->parseError("Div by zero"); - yygotominor.yy0.valid=yymsp[0].minor.yy0.valid; + yylhsminor.yy0.valid=yymsp[0].minor.yy0.valid; } -#line 752 "grammar.c" +#line 986 "grammar.c" + yymsp[-2].minor.yy0 = yylhsminor.yy0; break; - case 16: /* expr ::= PARENL expr PARENR */ + case 12: /* expr ::= PARENL expr PARENR */ #line 68 "grammar.lemon" -{ yygotominor.yy0.dValue = yymsp[-1].minor.yy0.dValue; yygotominor.yy0.valid=yymsp[-1].minor.yy0.valid; } -#line 757 "grammar.c" +{ yymsp[-2].minor.yy0.dValue = yymsp[-1].minor.yy0.dValue; yymsp[-2].minor.yy0.valid=yymsp[-1].minor.yy0.valid; } +#line 992 "grammar.c" break; default: - /* (0) main ::= in */ yytestcase(yyruleno==0); - /* (1) in ::= stmt */ yytestcase(yyruleno==1); - /* (2) in ::= in stmt */ yytestcase(yyruleno==2); - /* (3) stmt ::= ENDS */ yytestcase(yyruleno==3); + /* (13) main ::= in */ yytestcase(yyruleno==13); + /* (14) in ::= stmt (OPTIMIZED OUT) */ assert(yyruleno!=14); + /* (15) in ::= in stmt */ yytestcase(yyruleno==15); + /* (16) stmt ::= ENDS */ yytestcase(yyruleno==16); break; +/********** End reduce actions ************************************************/ }; - yygoto = yyRuleInfo[yyruleno].lhs; - yysize = yyRuleInfo[yyruleno].nrhs; - yypParser->yyidx -= yysize; - yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto); - if( yyact < YYNSTATE ){ -#ifdef NDEBUG - /* If we are not debugging and the reduce action popped at least - ** one element off the stack, then we can push the new element back - ** onto the stack here, and skip the stack overflow test in yy_shift(). - ** That gives a significant speed improvement. */ - if( yysize ){ - yypParser->yyidx++; - yymsp -= yysize-1; - yymsp->stateno = (YYACTIONTYPE)yyact; - yymsp->major = (YYCODETYPE)yygoto; - yymsp->minor = yygotominor; - }else -#endif - { - yy_shift(yypParser,yyact,yygoto,&yygotominor); - } - }else{ - assert( yyact == YYNSTATE + YYNRULE + 1 ); - yy_accept(yypParser); - } + assert( yyrulenoYY_MAX_SHIFT && yyact<=YY_MAX_SHIFTREDUCE) ); + + /* It is not possible for a REDUCE to be followed by an error */ + assert( yyact!=YY_ERROR_ACTION ); + + yymsp += yysize+1; + yypParser->yytos = yymsp; + yymsp->stateno = (YYACTIONTYPE)yyact; + yymsp->major = (YYCODETYPE)yygoto; + yyTraceShift(yypParser, yyact, "... then shift"); + return yyact; } /* @@ -796,16 +1025,20 @@ static void yy_reduce( static void yy_parse_failed( yyParser *yypParser /* The parser */ ){ - ParseARG_FETCH; + ParseARG_FETCH + ParseCTX_FETCH #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); } #endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser); /* Here code is inserted which will be executed whenever the ** parser fails */ - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ +/************ Begin %parse_failure code ***************************************/ +/************ End %parse_failure code *****************************************/ + ParseARG_STORE /* Suppress warning about unused %extra_argument variable */ + ParseCTX_STORE } #endif /* YYNOERRORRECOVERY */ @@ -815,15 +1048,19 @@ static void yy_parse_failed( static void yy_syntax_error( yyParser *yypParser, /* The parser */ int yymajor, /* The major type of the error token */ - YYMINORTYPE yyminor /* The minor type of the error token */ + ParseTOKENTYPE yyminor /* The minor type of the error token */ ){ - ParseARG_FETCH; -#define TOKEN (yyminor.yy0) + ParseARG_FETCH + ParseCTX_FETCH +#define TOKEN yyminor +/************ Begin %syntax_error code ****************************************/ #line 33 "grammar.lemon" pEval->parseError("Syntax error"); -#line 826 "grammar.c" - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ +#line 1061 "grammar.c" +/************ End %syntax_error code ******************************************/ + ParseARG_STORE /* Suppress warning about unused %extra_argument variable */ + ParseCTX_STORE } /* @@ -832,20 +1069,27 @@ static void yy_syntax_error( static void yy_accept( yyParser *yypParser /* The parser */ ){ - ParseARG_FETCH; + ParseARG_FETCH + ParseCTX_FETCH #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); } #endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); +#ifndef YYNOERRORRECOVERY + yypParser->yyerrcnt = -1; +#endif + assert( yypParser->yytos==yypParser->yystack ); /* Here code is inserted which will be executed whenever the ** parser accepts */ +/*********** Begin %parse_accept code *****************************************/ #line 37 "grammar.lemon" pEval->parseOk(); -#line 848 "grammar.c" - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ +#line 1090 "grammar.c" +/*********** End %parse_accept code *******************************************/ + ParseARG_STORE /* Suppress warning about unused %extra_argument variable */ + ParseCTX_STORE } /* The main parser program. @@ -874,50 +1118,54 @@ void Parse( ParseARG_PDECL /* Optional %extra_argument parameter */ ){ YYMINORTYPE yyminorunion; - int yyact; /* The parser action. */ + YYACTIONTYPE yyact; /* The parser action. */ +#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) int yyendofinput; /* True if we are at the end of input */ +#endif #ifdef YYERRORSYMBOL int yyerrorhit = 0; /* True if yymajor has invoked an error */ #endif - yyParser *yypParser; /* The parser */ + yyParser *yypParser = (yyParser*)yyp; /* The parser */ + ParseCTX_FETCH + ParseARG_STORE - /* (re)initialize the parser, if necessary */ - yypParser = (yyParser*)yyp; - if( yypParser->yyidx<0 ){ -#if YYSTACKDEPTH<=0 - if( yypParser->yystksz <=0 ){ - /*memset(&yyminorunion, 0, sizeof(yyminorunion));*/ - yyminorunion = yyzerominor; - yyStackOverflow(yypParser, &yyminorunion); - return; - } -#endif - yypParser->yyidx = 0; - yypParser->yyerrcnt = -1; - yypParser->yystack[0].stateno = 0; - yypParser->yystack[0].major = 0; - } - yyminorunion.yy0 = yyminor; + assert( yypParser->yytos!=0 ); +#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) yyendofinput = (yymajor==0); - ParseARG_STORE; +#endif + yyact = yypParser->yytos->stateno; #ifndef NDEBUG if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]); + if( yyact < YY_MIN_REDUCE ){ + fprintf(yyTraceFILE,"%sInput '%s' in state %d\n", + yyTracePrompt,yyTokenName[yymajor],yyact); + }else{ + fprintf(yyTraceFILE,"%sInput '%s' with pending reduce %d\n", + yyTracePrompt,yyTokenName[yymajor],yyact-YY_MIN_REDUCE); + } } #endif do{ - yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor); - if( yyactyytos->stateno ); + yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact); + if( yyact >= YY_MIN_REDUCE ){ + yyact = yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor, + yyminor ParseCTX_PARAM); + }else if( yyact <= YY_MAX_SHIFTREDUCE ){ + yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor); +#ifndef YYNOERRORRECOVERY yypParser->yyerrcnt--; - yymajor = YYNOCODE; - }else if( yyact < YYNSTATE + YYNRULE ){ - yy_reduce(yypParser,yyact-YYNSTATE); +#endif + break; + }else if( yyact==YY_ACCEPT_ACTION ){ + yypParser->yytos--; + yy_accept(yypParser); + return; }else{ assert( yyact == YY_ERROR_ACTION ); + yyminorunion.yy0 = yyminor; #ifdef YYERRORSYMBOL int yymx; #endif @@ -947,9 +1195,9 @@ void Parse( ** */ if( yypParser->yyerrcnt<0 ){ - yy_syntax_error(yypParser,yymajor,yyminorunion); + yy_syntax_error(yypParser,yymajor,yyminor); } - yymx = yypParser->yystack[yypParser->yyidx].major; + yymx = yypParser->yytos->major; if( yymx==YYERRORSYMBOL || yyerrorhit ){ #ifndef NDEBUG if( yyTraceFILE ){ @@ -957,30 +1205,31 @@ void Parse( yyTracePrompt,yyTokenName[yymajor]); } #endif - yy_destructor(yypParser, (YYCODETYPE)yymajor,&yyminorunion); + yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion); yymajor = YYNOCODE; }else{ - while( - yypParser->yyidx >= 0 && - yymx != YYERRORSYMBOL && - (yyact = yy_find_reduce_action( - yypParser->yystack[yypParser->yyidx].stateno, - YYERRORSYMBOL)) >= YYNSTATE + while( yypParser->yytos >= yypParser->yystack + && (yyact = yy_find_reduce_action( + yypParser->yytos->stateno, + YYERRORSYMBOL)) > YY_MAX_SHIFTREDUCE ){ yy_pop_parser_stack(yypParser); } - if( yypParser->yyidx < 0 || yymajor==0 ){ + if( yypParser->yytos < yypParser->yystack || yymajor==0 ){ yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); yy_parse_failed(yypParser); +#ifndef YYNOERRORRECOVERY + yypParser->yyerrcnt = -1; +#endif yymajor = YYNOCODE; }else if( yymx!=YYERRORSYMBOL ){ - YYMINORTYPE u2; - u2.YYERRSYMDT = 0; - yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2); + yy_shift(yypParser,yyact,YYERRORSYMBOL,yyminor); } } yypParser->yyerrcnt = 3; yyerrorhit = 1; + if( yymajor==YYNOCODE ) break; + yyact = yypParser->yytos->stateno; #elif defined(YYNOERRORRECOVERY) /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to ** do any kind of error recovery. Instead, simply invoke the syntax @@ -989,10 +1238,9 @@ void Parse( ** Applications can set this macro (for example inside %include) if ** they intend to abandon the parse upon the first syntax error seen. */ - yy_syntax_error(yypParser,yymajor,yyminorunion); + yy_syntax_error(yypParser,yymajor, yyminor); yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - yymajor = YYNOCODE; - + break; #else /* YYERRORSYMBOL is not defined */ /* This is what we do if the grammar does not define ERROR: ** @@ -1004,16 +1252,46 @@ void Parse( ** three input tokens have been successfully shifted. */ if( yypParser->yyerrcnt<=0 ){ - yy_syntax_error(yypParser,yymajor,yyminorunion); + yy_syntax_error(yypParser,yymajor, yyminor); } yypParser->yyerrcnt = 3; yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); if( yyendofinput ){ yy_parse_failed(yypParser); +#ifndef YYNOERRORRECOVERY + yypParser->yyerrcnt = -1; +#endif } - yymajor = YYNOCODE; + break; #endif } - }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 ); + }while( yypParser->yytos>yypParser->yystack ); +#ifndef NDEBUG + if( yyTraceFILE ){ + yyStackEntry *i; + char cDiv = '['; + fprintf(yyTraceFILE,"%sReturn. Stack=",yyTracePrompt); + for(i=&yypParser->yystack[1]; i<=yypParser->yytos; i++){ + fprintf(yyTraceFILE,"%c%s", cDiv, yyTokenName[i->major]); + cDiv = ' '; + } + fprintf(yyTraceFILE,"]\n"); + } +#endif return; } + +/* +** Return the fallback token corresponding to canonical token iToken, or +** 0 if iToken has no fallback. +*/ +int ParseFallback(int iToken){ +#ifdef YYFALLBACK + if( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) ){ + return yyFallback[iToken]; + } +#else + (void)iToken; +#endif + return 0; +} diff --git a/common/libeval/grammar.h b/common/libeval/grammar.h index 593f3cdd4c..0017248244 100644 --- a/common/libeval/grammar.h +++ b/common/libeval/grammar.h @@ -1,12 +1,12 @@ -#define VAR 1 -#define ASSIGN 2 -#define SEMCOL 3 -#define PLUS 4 -#define MINUS 5 -#define UNIT 6 -#define DIVIDE 7 -#define MULT 8 -#define ENDS 9 -#define VALUE 10 -#define PARENL 11 -#define PARENR 12 +#define VAR 1 +#define ASSIGN 2 +#define SEMCOL 3 +#define PLUS 4 +#define MINUS 5 +#define UNIT 6 +#define DIVIDE 7 +#define MULT 8 +#define ENDS 9 +#define VALUE 10 +#define PARENL 11 +#define PARENR 12 diff --git a/common/libeval_compiler/grammar.c b/common/libeval_compiler/grammar.c index 106fff6697..ed5c46e052 100644 --- a/common/libeval_compiler/grammar.c +++ b/common/libeval_compiler/grammar.c @@ -25,7 +25,7 @@ #include #include /************ Begin %include sections from the grammar ************************/ -#line 33 "grammar.lemon" +#line 34 "grammar.lemon" #include #include @@ -190,57 +190,59 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (118) +#define YY_ACTTAB_COUNT (135) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 68, 1, 1, 19, 9, 10, 17, 16, 14, 13, - /* 10 */ 12, 4, 11, 92, 19, 8, 7, 5, 6, 3, - /* 20 */ 87, 26, 9, 10, 61, 16, 14, 13, 12, 4, - /* 30 */ 11, 31, 32, 8, 7, 5, 6, 3, 28, 29, - /* 40 */ 9, 10, 62, 16, 14, 13, 12, 4, 11, 20, - /* 50 */ 21, 8, 7, 5, 6, 3, 43, 67, 67, 27, - /* 60 */ 16, 14, 13, 12, 4, 11, 23, 24, 8, 7, - /* 70 */ 5, 6, 3, 67, 67, 67, 67, 4, 11, 90, - /* 80 */ 33, 8, 7, 5, 6, 3, 67, 67, 33, 25, - /* 90 */ 8, 7, 5, 6, 3, 33, 18, 22, 45, 66, - /* 100 */ 34, 46, 2, 5, 6, 3, 15, 66, 34, 46, - /* 110 */ 2, 67, 3, 69, 69, 34, 46, 2, + /* 0 */ 68, 1, 1, 19, 10, 9, 17, 16, 14, 13, + /* 10 */ 12, 4, 11, 87, 8, 7, 5, 6, 3, 5, + /* 20 */ 6, 3, 10, 9, 61, 16, 14, 13, 12, 4, + /* 30 */ 11, 67, 8, 7, 5, 6, 3, 92, 19, 22, + /* 40 */ 10, 9, 62, 16, 14, 13, 12, 4, 11, 31, + /* 50 */ 8, 7, 5, 6, 3, 32, 43, 9, 28, 16, + /* 60 */ 14, 13, 12, 4, 11, 29, 8, 7, 5, 6, + /* 70 */ 3, 67, 67, 67, 67, 67, 67, 23, 8, 7, + /* 80 */ 5, 6, 3, 16, 14, 13, 12, 4, 11, 33, + /* 90 */ 8, 7, 5, 6, 3, 90, 33, 20, 24, 25, + /* 100 */ 26, 27, 18, 21, 3, 15, 45, 69, 66, 34, + /* 110 */ 46, 2, 33, 69, 69, 66, 34, 46, 2, 69, + /* 120 */ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + /* 130 */ 69, 69, 34, 46, 2, }; static const YYCODETYPE yy_lookahead[] = { /* 0 */ 25, 26, 27, 28, 4, 5, 28, 7, 8, 9, - /* 10 */ 10, 11, 12, 27, 28, 15, 16, 17, 18, 19, - /* 20 */ 28, 28, 4, 5, 24, 7, 8, 9, 10, 11, - /* 30 */ 12, 28, 28, 15, 16, 17, 18, 19, 28, 28, + /* 10 */ 10, 11, 12, 28, 14, 15, 16, 17, 18, 16, + /* 20 */ 17, 18, 4, 5, 24, 7, 8, 9, 10, 11, + /* 30 */ 12, 18, 14, 15, 16, 17, 18, 27, 28, 28, /* 40 */ 4, 5, 24, 7, 8, 9, 10, 11, 12, 28, - /* 50 */ 28, 15, 16, 17, 18, 19, 20, 4, 5, 28, - /* 60 */ 7, 8, 9, 10, 11, 12, 28, 28, 15, 16, - /* 70 */ 17, 18, 19, 7, 8, 9, 10, 11, 12, 0, - /* 80 */ 1, 15, 16, 17, 18, 19, 11, 12, 1, 28, - /* 90 */ 15, 16, 17, 18, 19, 1, 28, 28, 13, 20, - /* 100 */ 21, 22, 23, 17, 18, 19, 23, 20, 21, 22, - /* 110 */ 23, 19, 19, 29, 29, 21, 22, 23, 29, 29, + /* 50 */ 14, 15, 16, 17, 18, 28, 20, 5, 28, 7, + /* 60 */ 8, 9, 10, 11, 12, 28, 14, 15, 16, 17, + /* 70 */ 18, 7, 8, 9, 10, 11, 12, 28, 14, 15, + /* 80 */ 16, 17, 18, 7, 8, 9, 10, 11, 12, 1, + /* 90 */ 14, 15, 16, 17, 18, 0, 1, 28, 28, 28, + /* 100 */ 28, 28, 28, 28, 18, 23, 19, 29, 20, 21, + /* 110 */ 22, 23, 1, 29, 29, 20, 21, 22, 23, 29, /* 120 */ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - /* 130 */ 29, 29, 29, 29, 29, 29, 29, 29, + /* 130 */ 29, 29, 21, 22, 23, 29, 29, 29, }; #define YY_SHIFT_COUNT (34) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (94) +#define YY_SHIFT_MAX (111) static const unsigned char yy_shift_ofst[] = { - /* 0 */ 87, 79, 94, 94, 94, 94, 94, 94, 94, 94, - /* 10 */ 94, 94, 94, 94, 94, 94, 94, 0, 18, 36, - /* 20 */ 53, 53, 66, 66, 66, 66, 75, 75, 86, 86, - /* 30 */ 92, 93, 93, 83, 85, + /* 0 */ 88, 95, 111, 111, 111, 111, 111, 111, 111, 111, + /* 10 */ 111, 111, 111, 111, 111, 111, 111, 0, 18, 36, + /* 20 */ 52, 64, 64, 76, 64, 64, 64, 64, 3, 3, + /* 30 */ 13, 86, 86, 82, 87, }; #define YY_REDUCE_COUNT (16) #define YY_REDUCE_MIN (-25) -#define YY_REDUCE_MAX (69) +#define YY_REDUCE_MAX (75) static const signed char yy_reduce_ofst[] = { - /* 0 */ -25, -14, -22, -8, -7, 3, 4, 10, 11, 21, - /* 10 */ 22, 31, 38, 39, 61, 68, 69, + /* 0 */ -25, 10, -22, -15, 11, 21, 27, 30, 37, 49, + /* 10 */ 69, 70, 71, 72, 73, 74, 75, }; static const YYACTIONTYPE yy_default[] = { /* 0 */ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, /* 10 */ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - /* 20 */ 81, 80, 75, 78, 77, 76, 86, 79, 83, 82, + /* 20 */ 80, 75, 86, 81, 79, 78, 77, 76, 83, 82, /* 30 */ 87, 85, 84, 74, 71, }; /********** End of lemon-generated parsing tables *****************************/ @@ -352,8 +354,8 @@ static const char *const yyTokenName[] = { /* 1 */ "G_IDENTIFIER", /* 2 */ "G_ASSIGN", /* 3 */ "G_SEMCOL", - /* 4 */ "G_BOOL_OR", - /* 5 */ "G_BOOL_AND", + /* 4 */ "G_BOOL_AND", + /* 5 */ "G_BOOL_OR", /* 6 */ "G_BOOL_XOR", /* 7 */ "G_LESS_THAN", /* 8 */ "G_GREATER_THAN", @@ -361,13 +363,13 @@ static const char *const yyTokenName[] = { /* 10 */ "G_GREATER_EQUAL_THAN", /* 11 */ "G_EQUAL", /* 12 */ "G_NOT_EQUAL", - /* 13 */ "G_UNIT", - /* 14 */ "G_BOOL_NOT", - /* 15 */ "G_PLUS", - /* 16 */ "G_MINUS", - /* 17 */ "G_DIVIDE", - /* 18 */ "G_MULT", - /* 19 */ "G_STRUCT_REF", + /* 13 */ "G_BOOL_NOT", + /* 14 */ "G_PLUS", + /* 15 */ "G_MINUS", + /* 16 */ "G_DIVIDE", + /* 17 */ "G_MULT", + /* 18 */ "G_STRUCT_REF", + /* 19 */ "G_UNIT", /* 20 */ "G_ENDS", /* 21 */ "G_VALUE", /* 22 */ "G_STRING", @@ -963,121 +965,121 @@ static YYACTIONTYPE yy_reduce( /********** Begin reduce actions **********************************************/ YYMINORTYPE yylhsminor; case 0: /* stmt ::= expr G_ENDS */ -#line 54 "grammar.lemon" +#line 55 "grammar.lemon" { pEval->setRoot(yymsp[-1].minor.yy0); } -#line 969 "grammar.c" +#line 971 "grammar.c" break; case 1: /* expr ::= G_VALUE */ -#line 57 "grammar.lemon" +#line 58 "grammar.lemon" { yylhsminor.yy0.op = TR_NUMBER; yylhsminor.yy0.value = yymsp[0].minor.yy0.value; yylhsminor.yy0.leaf[0] = yylhsminor.yy0.leaf[1] = NULL; yylhsminor.yy0.valid = true; } -#line 974 "grammar.c" +#line 976 "grammar.c" yymsp[0].minor.yy0 = yylhsminor.yy0; break; case 2: /* expr ::= G_VALUE G_UNIT */ -#line 58 "grammar.lemon" +#line 59 "grammar.lemon" { yylhsminor.yy0.op = TR_NUMBER; yylhsminor.yy0.value = yymsp[-1].minor.yy0.value; yylhsminor.yy0.leaf[0] = newNode( TR_UNIT, yymsp[0].minor.yy0.value.type, ""); yylhsminor.yy0.leaf[1] = NULL; yylhsminor.yy0.valid = true; } -#line 980 "grammar.c" +#line 982 "grammar.c" yymsp[-1].minor.yy0 = yylhsminor.yy0; break; case 3: /* expr ::= G_STRING */ -#line 59 "grammar.lemon" +#line 60 "grammar.lemon" { yylhsminor.yy0.op = TR_STRING; yylhsminor.yy0.value = yymsp[0].minor.yy0.value; yylhsminor.yy0.leaf[0] = yylhsminor.yy0.leaf[1] = NULL; yylhsminor.yy0.valid = true; } -#line 986 "grammar.c" +#line 988 "grammar.c" yymsp[0].minor.yy0 = yylhsminor.yy0; break; case 4: /* expr ::= G_IDENTIFIER */ -#line 60 "grammar.lemon" +#line 61 "grammar.lemon" { yylhsminor.yy0.op = TR_IDENTIFIER; yylhsminor.yy0.value = yymsp[0].minor.yy0.value; yylhsminor.yy0.leaf[0] = yylhsminor.yy0.leaf[1] = NULL; yylhsminor.yy0.valid = true; } -#line 992 "grammar.c" +#line 994 "grammar.c" yymsp[0].minor.yy0 = yylhsminor.yy0; break; case 5: /* expr ::= expr G_LESS_THAN expr */ -#line 61 "grammar.lemon" +#line 62 "grammar.lemon" { yylhsminor.yy0.op = TR_OP_LESS; yylhsminor.yy0.leaf[0] = copyNode(yymsp[-2].minor.yy0); yylhsminor.yy0.leaf[1] = copyNode(yymsp[0].minor.yy0); yylhsminor.yy0.valid=yymsp[-2].minor.yy0.valid && yymsp[0].minor.yy0.valid; } -#line 998 "grammar.c" +#line 1000 "grammar.c" yymsp[-2].minor.yy0 = yylhsminor.yy0; break; case 6: /* expr ::= expr G_GREATER_THAN expr */ -#line 62 "grammar.lemon" +#line 63 "grammar.lemon" { yylhsminor.yy0.op = TR_OP_GREATER; yylhsminor.yy0.leaf[0] = copyNode(yymsp[-2].minor.yy0); yylhsminor.yy0.leaf[1] = copyNode(yymsp[0].minor.yy0); yylhsminor.yy0.valid=yymsp[-2].minor.yy0.valid && yymsp[0].minor.yy0.valid; } -#line 1004 "grammar.c" +#line 1006 "grammar.c" yymsp[-2].minor.yy0 = yylhsminor.yy0; break; case 7: /* expr ::= expr G_LESS_EQUAL_THAN expr */ -#line 63 "grammar.lemon" +#line 64 "grammar.lemon" { yylhsminor.yy0.op = TR_OP_LESS_EQUAL; yylhsminor.yy0.leaf[0] = copyNode(yymsp[-2].minor.yy0); yylhsminor.yy0.leaf[1] = copyNode(yymsp[0].minor.yy0); yylhsminor.yy0.valid=yymsp[-2].minor.yy0.valid && yymsp[0].minor.yy0.valid; } -#line 1010 "grammar.c" +#line 1012 "grammar.c" yymsp[-2].minor.yy0 = yylhsminor.yy0; break; case 8: /* expr ::= expr G_GREATER_EQUAL_THAN expr */ -#line 64 "grammar.lemon" +#line 65 "grammar.lemon" { yylhsminor.yy0.op = TR_OP_GREATER_EQUAL; yylhsminor.yy0.leaf[0] = copyNode(yymsp[-2].minor.yy0); yylhsminor.yy0.leaf[1] = copyNode(yymsp[0].minor.yy0); yylhsminor.yy0.valid=yymsp[-2].minor.yy0.valid && yymsp[0].minor.yy0.valid; } -#line 1016 "grammar.c" +#line 1018 "grammar.c" yymsp[-2].minor.yy0 = yylhsminor.yy0; break; case 9: /* expr ::= expr G_NOT_EQUAL expr */ -#line 65 "grammar.lemon" +#line 66 "grammar.lemon" { yylhsminor.yy0.op = TR_OP_NOT_EQUAL; yylhsminor.yy0.leaf[0] = copyNode(yymsp[-2].minor.yy0); yylhsminor.yy0.leaf[1] = copyNode(yymsp[0].minor.yy0); yylhsminor.yy0.valid=yymsp[-2].minor.yy0.valid && yymsp[0].minor.yy0.valid; } -#line 1022 "grammar.c" +#line 1024 "grammar.c" yymsp[-2].minor.yy0 = yylhsminor.yy0; break; case 10: /* expr ::= expr G_BOOL_AND expr */ -#line 66 "grammar.lemon" +#line 67 "grammar.lemon" { yylhsminor.yy0.op = TR_OP_BOOL_AND; yylhsminor.yy0.leaf[0] = copyNode(yymsp[-2].minor.yy0); yylhsminor.yy0.leaf[1] = copyNode(yymsp[0].minor.yy0); yylhsminor.yy0.valid=yymsp[-2].minor.yy0.valid && yymsp[0].minor.yy0.valid; } -#line 1028 "grammar.c" +#line 1030 "grammar.c" yymsp[-2].minor.yy0 = yylhsminor.yy0; break; case 11: /* expr ::= expr G_BOOL_OR expr */ -#line 67 "grammar.lemon" +#line 68 "grammar.lemon" { yylhsminor.yy0.op = TR_OP_BOOL_OR; yylhsminor.yy0.leaf[0] = copyNode(yymsp[-2].minor.yy0); yylhsminor.yy0.leaf[1] = copyNode(yymsp[0].minor.yy0); yylhsminor.yy0.valid=yymsp[-2].minor.yy0.valid && yymsp[0].minor.yy0.valid; } -#line 1034 "grammar.c" +#line 1036 "grammar.c" yymsp[-2].minor.yy0 = yylhsminor.yy0; break; case 12: /* expr ::= expr G_PLUS expr */ -#line 68 "grammar.lemon" +#line 69 "grammar.lemon" { yylhsminor.yy0.op = TR_OP_ADD; yylhsminor.yy0.leaf[0] = copyNode(yymsp[-2].minor.yy0); yylhsminor.yy0.leaf[1] = copyNode(yymsp[0].minor.yy0); yylhsminor.yy0.valid=yymsp[-2].minor.yy0.valid && yymsp[0].minor.yy0.valid; } -#line 1040 "grammar.c" +#line 1042 "grammar.c" yymsp[-2].minor.yy0 = yylhsminor.yy0; break; case 13: /* expr ::= expr G_MINUS expr */ -#line 69 "grammar.lemon" +#line 70 "grammar.lemon" { yylhsminor.yy0.op = TR_OP_SUB; yylhsminor.yy0.leaf[0] = copyNode(yymsp[-2].minor.yy0); yylhsminor.yy0.leaf[1] = copyNode(yymsp[0].minor.yy0); yylhsminor.yy0.valid=yymsp[-2].minor.yy0.valid && yymsp[0].minor.yy0.valid; } -#line 1046 "grammar.c" +#line 1048 "grammar.c" yymsp[-2].minor.yy0 = yylhsminor.yy0; break; case 14: /* expr ::= expr G_MULT expr */ -#line 70 "grammar.lemon" +#line 71 "grammar.lemon" { yylhsminor.yy0.op = TR_OP_MUL; yylhsminor.yy0.leaf[0] = copyNode(yymsp[-2].minor.yy0); yylhsminor.yy0.leaf[1] = copyNode(yymsp[0].minor.yy0); yylhsminor.yy0.valid=yymsp[-2].minor.yy0.valid && yymsp[0].minor.yy0.valid; } -#line 1052 "grammar.c" +#line 1054 "grammar.c" yymsp[-2].minor.yy0 = yylhsminor.yy0; break; case 15: /* expr ::= expr G_DIVIDE expr */ -#line 71 "grammar.lemon" +#line 72 "grammar.lemon" { yylhsminor.yy0.op = TR_OP_DIV; yylhsminor.yy0.leaf[0] = copyNode(yymsp[-2].minor.yy0); yylhsminor.yy0.leaf[1] = copyNode(yymsp[0].minor.yy0); yylhsminor.yy0.valid=yymsp[-2].minor.yy0.valid && yymsp[0].minor.yy0.valid; } -#line 1058 "grammar.c" +#line 1060 "grammar.c" yymsp[-2].minor.yy0 = yylhsminor.yy0; break; case 16: /* expr ::= expr G_EQUAL expr */ -#line 72 "grammar.lemon" +#line 73 "grammar.lemon" { yylhsminor.yy0.op = TR_OP_EQUAL; yylhsminor.yy0.leaf[0] = copyNode(yymsp[-2].minor.yy0); yylhsminor.yy0.leaf[1] = copyNode(yymsp[0].minor.yy0); yylhsminor.yy0.valid=yymsp[-2].minor.yy0.valid && yymsp[0].minor.yy0.valid; } -#line 1064 "grammar.c" +#line 1066 "grammar.c" yymsp[-2].minor.yy0 = yylhsminor.yy0; break; case 17: /* expr ::= expr G_STRUCT_REF expr */ -#line 74 "grammar.lemon" +#line 75 "grammar.lemon" { yylhsminor.yy0.op = TR_STRUCT_REF; yylhsminor.yy0.leaf[0] = copyNode(yymsp[-2].minor.yy0); yylhsminor.yy0.leaf[1] = copyNode(yymsp[0].minor.yy0); yylhsminor.yy0.valid=yymsp[-2].minor.yy0.valid && yymsp[0].minor.yy0.valid; } -#line 1070 "grammar.c" +#line 1072 "grammar.c" yymsp[-2].minor.yy0 = yylhsminor.yy0; break; case 18: /* expr ::= G_PARENL expr G_PARENR */ -#line 76 "grammar.lemon" +#line 77 "grammar.lemon" { yymsp[-2].minor.yy0.op = yymsp[-1].minor.yy0.op; yymsp[-2].minor.yy0.value = yymsp[-1].minor.yy0.value; yymsp[-2].minor.yy0.valid=yymsp[-1].minor.yy0.valid; yymsp[-2].minor.yy0.leaf[0] = yymsp[-1].minor.yy0.leaf[0]; yymsp[-2].minor.yy0.leaf[1] = yymsp[-1].minor.yy0.leaf[1]; } -#line 1076 "grammar.c" +#line 1078 "grammar.c" break; case 19: /* expr ::= G_IDENTIFIER G_PARENL expr G_PARENR */ -#line 77 "grammar.lemon" +#line 78 "grammar.lemon" { yylhsminor.yy0.op = TR_OP_FUNC_CALL; yylhsminor.yy0.leaf[0] = copyNode(yymsp[-3].minor.yy0); yylhsminor.yy0.leaf[1] = copyNode(yymsp[-1].minor.yy0); yylhsminor.yy0.valid=1; } -#line 1081 "grammar.c" +#line 1083 "grammar.c" yymsp[-3].minor.yy0 = yylhsminor.yy0; break; default: @@ -1144,10 +1146,10 @@ static void yy_syntax_error( ParseCTX_FETCH #define TOKEN yyminor /************ Begin %syntax_error code ****************************************/ -#line 38 "grammar.lemon" +#line 39 "grammar.lemon" pEval->parseError("Syntax error"); -#line 1151 "grammar.c" +#line 1153 "grammar.c" /************ End %syntax_error code ******************************************/ ParseARG_STORE /* Suppress warning about unused %extra_argument variable */ ParseCTX_STORE @@ -1173,10 +1175,10 @@ static void yy_accept( /* Here code is inserted which will be executed whenever the ** parser accepts */ /*********** Begin %parse_accept code *****************************************/ -#line 42 "grammar.lemon" +#line 43 "grammar.lemon" pEval->parseOk(); -#line 1180 "grammar.c" +#line 1182 "grammar.c" /*********** End %parse_accept code *******************************************/ ParseARG_STORE /* Suppress warning about unused %extra_argument variable */ ParseCTX_STORE diff --git a/common/libeval_compiler/grammar.h b/common/libeval_compiler/grammar.h index 30e62c7ba7..1e0e74b20d 100644 --- a/common/libeval_compiler/grammar.h +++ b/common/libeval_compiler/grammar.h @@ -1,8 +1,8 @@ #define G_IDENTIFIER 1 #define G_ASSIGN 2 #define G_SEMCOL 3 -#define G_BOOL_OR 4 -#define G_BOOL_AND 5 +#define G_BOOL_AND 4 +#define G_BOOL_OR 5 #define G_BOOL_XOR 6 #define G_LESS_THAN 7 #define G_GREATER_THAN 8 @@ -10,13 +10,13 @@ #define G_GREATER_EQUAL_THAN 10 #define G_EQUAL 11 #define G_NOT_EQUAL 12 -#define G_UNIT 13 -#define G_BOOL_NOT 14 -#define G_PLUS 15 -#define G_MINUS 16 -#define G_DIVIDE 17 -#define G_MULT 18 -#define G_STRUCT_REF 19 +#define G_BOOL_NOT 13 +#define G_PLUS 14 +#define G_MINUS 15 +#define G_DIVIDE 16 +#define G_MULT 17 +#define G_STRUCT_REF 18 +#define G_UNIT 19 #define G_ENDS 20 #define G_VALUE 21 #define G_STRING 22 diff --git a/common/libeval_compiler/grammar.lemon b/common/libeval_compiler/grammar.lemon index 7f2d0f0d6e..24731814bf 100644 --- a/common/libeval_compiler/grammar.lemon +++ b/common/libeval_compiler/grammar.lemon @@ -21,14 +21,15 @@ %extra_argument { LIBEVAL::COMPILER* pEval } %nonassoc G_IDENTIFIER G_ASSIGN G_SEMCOL. -%nonassoc G_BOOL_OR G_BOOL_AND G_BOOL_XOR. -%nonassoc G_LESS_THAN G_GREATER_THAN G_LESS_EQUAL_THAN G_GREATER_EQUAL_THAN. -%nonassoc G_EQUAL G_NOT_EQUAL. -%right G_UNIT. -%left G_BOOL_NOT. +%left G_BOOL_AND. +%left G_BOOL_OR. +%left G_BOOL_XOR. +%nonassoc G_LESS_THAN G_GREATER_THAN G_LESS_EQUAL_THAN G_GREATER_EQUAL_THAN G_EQUAL G_NOT_EQUAL. +%right G_BOOL_NOT. %left G_PLUS G_MINUS. %left G_DIVIDE G_MULT. %nonassoc G_STRUCT_REF. +%nonassoc G_UNIT. %include { #include diff --git a/common/libeval_compiler/libeval_compiler.cpp b/common/libeval_compiler/libeval_compiler.cpp index 32ebc12b8b..61db4fd79c 100644 --- a/common/libeval_compiler/libeval_compiler.cpp +++ b/common/libeval_compiler/libeval_compiler.cpp @@ -49,7 +49,7 @@ namespace LIBEVAL static void libeval_dbg( int level, const char* fmt, ... ) { #ifdef DEBUG - if(level <= 10) // fixme: tom's debugging. + if(level < 10) // fixme: tom's debugging. { va_list ap; va_start( ap, fmt ); @@ -409,8 +409,12 @@ bool COMPILER::lexDefault( COMPILER::T_TOKEN& aToken ) else if( m_tokenizer.MatchAhead( "==", []( int c ) -> bool { return c != '='; } ) ) { retval.token = G_EQUAL; + m_tokenizer.NextChar( 2 ); + } + else if( m_tokenizer.MatchAhead( "!=", []( int c ) -> bool { return c != '='; } ) ) + { + retval.token = G_NOT_EQUAL; m_tokenizer.NextChar( 2 ); - //printf( "nc pos %d\n", m_tokenizer.GetPos() ); } else if( m_tokenizer.MatchAhead( "<=", []( int c ) -> bool { return c != '='; } ) ) { @@ -541,6 +545,11 @@ void dumpNode( std::string& buf, TREE_NODE* tok, int depth = 0 ) dumpNode( buf, tok->leaf[0], depth + 1 ); dumpNode( buf, tok->leaf[1], depth + 1 ); break; + case TR_OP_FUNC_CALL: + sprintf( str, "CALL '%s': ", tok->leaf[0]->value.str ); + buf += str; + dumpNode( buf, tok->leaf[1], depth + 1 ); + break; case TR_UNIT: sprintf( str, "UNIT: %d ", tok->value.type ); buf += str; @@ -554,6 +563,12 @@ ERROR_STATUS COMPILER::GetErrorStatus() return dummy; } +void COMPILER::ReportError( const std::string aErrorMsg ) +{ + m_errorStatus.pendingError = true; + m_errorStatus.message = aErrorMsg; +} + void COMPILER::setRoot( TREE_NODE root ) { m_tree = copyNode( root ); @@ -575,14 +590,21 @@ bool COMPILER::generateUCode( UCODE* aCode ) stack.push_back( m_tree ); - //printf("compile: tree %p\n", m_tree); + std::string dump; + + dumpNode( dump, m_tree, 0 ); + + libeval_dbg(3,"Tree: %s", dump.c_str() ); + + while( !stack.empty() ) { auto node = stack.back(); bool isTerminalNode = true; - // printf( "process node %p [op %d] [stack %d]\n", node, node->op, stack.size() ); + + libeval_dbg( 4, "process node %p [op %d] [stack %d]\n", node, node->op, stack.size() ); // process terminal nodes first switch( node->op ) @@ -590,10 +612,54 @@ bool COMPILER::generateUCode( UCODE* aCode ) case TR_STRUCT_REF: { assert( node->leaf[0]->op == TR_IDENTIFIER ); - assert( node->leaf[1]->op == TR_IDENTIFIER ); + //assert( node->leaf[1]->op == TR_IDENTIFIER ); + + + switch( node->leaf[1]->op ) + { + case TR_IDENTIFIER: + { + auto vref = aCode->createVarRef( this, node->leaf[0]->value.str, node->leaf[1]->value.str ); + + if( m_errorStatus.pendingError ) + { + printf("varref fail\n"); + return false; + } + aCode->AddOp( TR_UOP_PUSH_VAR, vref ); + break; + } + case TR_OP_FUNC_CALL: + { + + //printf("got a method call... [%s], this = %s\n", node->leaf[1]->leaf[0]->value.str, node->leaf[0]->value.str); + auto vref = aCode->createVarRef( this, node->leaf[0]->value.str, ""); + auto func = aCode->createFuncCall( this, node->leaf[1]->leaf[0]->value.str ); + + if(!func) + { + m_errorStatus.pendingError = true; + m_errorStatus.stage = ERROR_STATUS::CST_CODEGEN; + return false; + // fixme: generate a message + } + +// printf("cfc4 test\n"); + // func(nullptr, nullptr, nullptr); + + aCode->AddOp( TR_OP_METHOD_CALL, func, vref ); + + isTerminalNode = false; + visitedNodes.insert( node ); + visitedNodes.insert( node->leaf[0] ); + //visitedNodes.insert( node->leaf[1]->leaf[1] ); + + + break; + } + } + - auto vref = aCode->createVarRef( this, node->leaf[0]->value.str, node->leaf[1]->value.str ); - aCode->AddOp( TR_UOP_PUSH_VAR, vref ); break; } @@ -665,9 +731,15 @@ void UCODE::UOP::Exec( CONTEXT* ctx, UCODE* ucode ) ctx->Push( value ); break; } + case TR_UOP_PUSH_VALUE: ctx->Push( reinterpret_cast( m_arg ) ); return; + + case TR_OP_METHOD_CALL: + //printf("CALL METHOD %s\n" ); + m_func( ucode, ctx, m_arg ); + return; default: break; }