1 /* 2 * Copyright (c) 2014-2020 Christian Schoenebeck 3 * 4 * http://www.linuxsampler.org 5 * 6 * This file is part of LinuxSampler and released under the same terms. 7 * See README file for details. 8 */ 9 10 // types shared between auto generated lexer and parser ... 11 12 #ifndef LS_INSTRSCRIPTSPARSER_SHARED_H 13 #define LS_INSTRSCRIPTSPARSER_SHARED_H 14 15 #include <stdio.h> 16 #include "tree.h" 17 18 #if AC_APPLE_UNIVERSAL_BUILD 19 # include "parser.tab.h" 20 #else 21 # include "parser.h" 22 #endif 23 24 #include "../common/global_private.h" 25 26 struct _YYSTYPE { 27 union { 28 LinuxSampler::vmint iValue; 29 LinuxSampler::vmfloat fValue; 30 // Intentionally using C-strings instead of std::string for parser's 31 // string tokens, because any destructor based class had a negative 32 // impact on parser performance in benchmarks. Reason for this is that 33 // text tokens are the most common one while parsing, plus the parser 34 // copies the YYSTYPE struct a lot (i.e. when shifting). For C-strings 35 // coming directly from Flex, we don't have to free them. For C-strings 36 // allocated by us, use yyextra->autoFreeAfterParse(s); 37 char* sValue; 38 struct { 39 LinuxSampler::vmint iValue; 40 LinuxSampler::MetricPrefix_t prefix[2]; 41 LinuxSampler::StdUnit_t unit; 42 } iUnitValue; 43 struct { 44 LinuxSampler::vmfloat fValue; 45 LinuxSampler::MetricPrefix_t prefix[2]; 46 LinuxSampler::StdUnit_t unit; 47 } fUnitValue; 48 }; 49 LinuxSampler::EventHandlersRef nEventHandlers; 50 LinuxSampler::EventHandlerRef nEventHandler; 51 LinuxSampler::StatementsRef nStatements; 52 LinuxSampler::StatementRef nStatement; 53 LinuxSampler::FunctionCallRef nFunctionCall; 54 LinuxSampler::ArgsRef nArgs; 55 LinuxSampler::ExpressionRef nExpression; 56 LinuxSampler::CaseBranch nCaseBranch; 57 LinuxSampler::CaseBranches nCaseBranches; 58 LinuxSampler::Qualifier_t varQualifier; 59 }; 60 #define YYSTYPE _YYSTYPE 61 #define yystype YYSTYPE ///< For backward compatibility. 62 #ifndef YYSTYPE_IS_DECLARED 63 # define YYSTYPE_IS_DECLARED ///< We tell the lexer / parser that we use our own data structure as defined above. 64 #endif 65 66 // custom Bison location type to support raw byte positions 67 struct _YYLTYPE { 68 int first_line; 69 int first_column; 70 int last_line; 71 int last_column; 72 int first_byte; 73 int length_bytes; 74 }; 75 #define YYLTYPE _YYLTYPE 76 #define YYLTYPE_IS_DECLARED 1 77 78 // override Bison's default location passing to support raw byte positions 79 #define YYLLOC_DEFAULT(Cur, Rhs, N) \ 80 do \ 81 if (N) \ 82 { \ 83 (Cur).first_line = YYRHSLOC(Rhs, 1).first_line; \ 84 (Cur).first_column = YYRHSLOC(Rhs, 1).first_column; \ 85 (Cur).last_line = YYRHSLOC(Rhs, N).last_line; \ 86 (Cur).last_column = YYRHSLOC(Rhs, N).last_column; \ 87 (Cur).first_byte = YYRHSLOC(Rhs, 1).first_byte; \ 88 (Cur).length_bytes = (YYRHSLOC(Rhs, N).first_byte - \ 89 YYRHSLOC(Rhs, 1).first_byte) + \ 90 YYRHSLOC(Rhs, N).length_bytes; \ 91 } \ 92 else \ 93 { \ 94 (Cur).first_line = (Cur).last_line = \ 95 YYRHSLOC(Rhs, 0).last_line; \ 96 (Cur).first_column = (Cur).last_column = \ 97 YYRHSLOC(Rhs, 0).last_column; \ 98 (Cur).first_byte = YYRHSLOC(Rhs, 0).first_byte; \ 99 (Cur).length_bytes = YYRHSLOC(Rhs, 0).length_bytes; \ 100 } \ 101 while (0) 102 103 // Force YYCOPY() to use copy by value. 104 // 105 // By default YYCOPY() is using __builtin_memcpy, which is slightly problematic 106 // with our YYSTYPE (see above) since it has dynamic objects as member variables 107 // and hence __builtin_memcpy would overwrite their vpointer. In practice though 108 // this is more of a theoretical fix and probably just silences compiler 109 // warnings. So in practice __builtin_memcpy would probably not cause any 110 // misbehaviours, because it is expected that Bison generated parsers only use 111 // YYCOPY() to relocate the parser's stack (that is moving objects in memory), 112 // but not for really creating duplicates of any objects. 113 // 114 // In my benchmarks I did not encounter any measurable performance difference by 115 // this change, so shutting up the compiler wins for now. 116 #define YYCOPY(To, From, Count) \ 117 do { \ 118 for (YYSIZE_T i = 0; i < (Count); ++i) \ 119 (To)[i] = (From)[i]; \ 120 } while (YYID (0)); \ 121 122 #endif // LS_INSTRSCRIPTSPARSER_SHARED_H 123