Warning, /kdevelop/kdevelop-pg-qt/kdev-pg/kdev-pg-parser.yy is written in an unsupported language. File is not indexed.
0001 0002 %{ 0003 /* This file is part of kdev-pg-qt 0004 Copyright (C) 2005 Roberto Raggi <roberto@kdevelop.org> 0005 Copyright (C) 2006 Jakob Petsovits <jpetso@gmx.at> 0006 0007 This library is free software; you can redistribute it and/or 0008 modify it under the terms of the GNU Library General Public 0009 License as published by the Free Software Foundation; either 0010 version 2 of the License, or (at your option) any later version. 0011 0012 This library is distributed in the hope that it will be useful, 0013 but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 Library General Public License for more details. 0016 0017 You should have received a copy of the GNU Library General Public License 0018 along with this library; see the file COPYING.LIB. If not, write to 0019 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0020 Boston, MA 02110-1301, USA. 0021 */ 0022 0023 #include "kdev-pg.h" 0024 #include "kdev-pg-clone-tree.h" 0025 #include "kdev-pg-regexp.h" 0026 #include "kdev-pg-unicode-loader.h" 0027 #include "kdev-pg-checker.h" 0028 0029 #include <QFile> 0030 #include <cassert> 0031 0032 extern int yylex(); 0033 extern void yyerror(const char* msg); 0034 extern int yyLine; 0035 0036 QString lexerEnv; 0037 0038 namespace KDevPG 0039 { 0040 extern QFile file; 0041 extern QTextStream checkOut; 0042 } 0043 0044 KDevPG::Model::OperatorItem *operatorNode = nullptr; 0045 QString r; 0046 0047 %} 0048 0049 %union { 0050 KDevPG::Model::Node *item; 0051 char* str; 0052 KDevPG::Model::VariableDeclarationItem::DeclarationType declarationType; 0053 KDevPG::Model::VariableDeclarationItem::StorageType storageType; 0054 KDevPG::Model::VariableDeclarationItem::VariableType variableType; 0055 KDevPG::Model::Operator *operatorInformation; 0056 KDevPG::GNFA *nfa; 0057 } 0058 0059 %token T_IDENTIFIER T_ARROW T_TERMINAL T_CODE T_STRING T_UNQUOTED_STRING T_NUMBER ';' 0060 %token T_TOKEN_DECLARATION T_TOKEN_STREAM_DECLARATION T_NAMESPACE_DECLARATION 0061 %token T_PARSERCLASS_DECLARATION T_LEXERCLASS_DECLARATION 0062 %token T_PUBLIC T_PRIVATE T_PROTECTED T_DECLARATION T_BITS 0063 %token T_CONSTRUCTOR T_DESTRUCTOR T_TRY_RECOVER T_TRY_ROLLBACK T_CATCH 0064 %token T_RULE_ARGUMENTS T_MEMBER T_TEMPORARY T_ARGUMENT T_EXPORT_MACRO 0065 %token T_NODE T_NODE_SEQUENCE T_TOKEN T_VARIABLE T_EXPORT_MACRO_HEADER 0066 %token T_AST_DECLARATION 0067 %token T_PARSER_DECLARATION_HEADER T_PARSER_BITS_HEADER T_AST_HEADER 0068 %token T_LEXER_DECLARATION_HEADER T_LEXER_BITS_HEADER 0069 %token T_PARSER_BASE T_AST_BASE T_LEXER_BASE 0070 %token T_BIN T_PRE T_POST T_TERN 0071 %token T_LOPR T_ROPR 0072 %token T_LEFT_ASSOC T_RIGHT_ASSOC T_IS_LEFT_ASSOC T_IS_RIGHT_ASSOC T_PRIORITY 0073 %token T_PAREN 0074 %token T_INLINE 0075 %token T_LEXER T_INPUT_STREAM T_INPUT_ENCODING T_TABLE_LEXER T_SEQUENCE_LEXER 0076 %token T_NAMED_REGEXP T_CONTINUE T_RANGE T_FAIL T_LOOKAHEAD T_BARRIER 0077 %token T_ENTER_RULE_SET T_LEAVE_RULE_SET 0078 0079 %type<str> T_IDENTIFIER T_TERMINAL T_CODE T_STRING T_UNQUOTED_STRING T_RULE_ARGUMENTS T_NUMBER T_NAMED_REGEXP T_RANGE 0080 %type<str> name code_opt rule_arguments_opt priority assoc opt_lexer_action 0081 %type<item> item primary_item try_item primary_atom unary_item 0082 %type<item> postfix_item option_item item_sequence conditional_item 0083 %type<item> member_declaration_rest variableDeclarations variableDeclaration operatorRule 0084 %type<declarationType> declarationType_opt 0085 %type<storageType> scope storageType 0086 %type<variableType> variableType 0087 /* %type<void> operatorDeclaration operatorDeclarations operatorRule */ 0088 %type<operatorInformation> operator 0089 %type<nfa> regexp regexp1 regexp2 regexp3 regexp4 regexp5 regexp6 regexp7 aregexp aregexp1 aregexp2 aregexp3 aregexp4 aregexp5 aregexp6 aregexp7 0090 0091 %% 0092 0093 system 0094 : code_opt { KDevPG::globalSystem.decl = $1; } 0095 declarations 0096 rules 0097 code_opt { KDevPG::globalSystem.bits += $5; } 0098 ; 0099 0100 declarations 0101 : declaration 0102 | declarations declaration 0103 ; 0104 0105 declaration 0106 : T_PARSERCLASS_DECLARATION member_declaration_rest 0107 { KDevPG::globalSystem.pushParserClassMember($2); } 0108 | T_PARSERCLASS_DECLARATION '(' T_BITS ')' T_CODE 0109 { KDevPG::globalSystem.bits += $5; } 0110 | T_LEXERCLASS_DECLARATION member_declaration_rest 0111 { KDevPG::globalSystem.pushLexerClassMember($2); } 0112 | T_LEXERCLASS_DECLARATION '(' T_BITS ')' T_CODE 0113 { KDevPG::globalSystem.lexerBits += $5; } 0114 | T_TOKEN_DECLARATION declared_tokens ';' 0115 | T_TABLE_LEXER 0116 { if(KDevPG::globalSystem.hasLexer) 0117 { KDevPG::checkOut << "** ERROR you have to specify the lexer-type (%table_lexer) before any lexer rules"; exit(-1); } 0118 switch(KDevPG::GDFA::type) 0119 { 0120 case KDevPG::SAscii: KDevPG::GDFA::type = KDevPG::TAscii; break; 0121 case KDevPG::SLatin1: KDevPG::GDFA::type = KDevPG::TLatin1; break; 0122 case KDevPG::SUtf8: KDevPG::GDFA::type = KDevPG::TUtf8; break; 0123 case KDevPG::SUcs2: KDevPG::GDFA::type = KDevPG::TUcs2; break; 0124 case KDevPG::SUtf16: KDevPG::GDFA::type = KDevPG::TUtf16; break; 0125 /* case KDevPG::SUcs4: KDevPG::GDFA::type = KDevPG::TUcs4; break; */ 0126 default: /* empty */; 0127 } 0128 } 0129 | T_SEQUENCE_LEXER 0130 { if(KDevPG::globalSystem.hasLexer) 0131 { KDevPG::checkOut << "** ERROR you have to specify the lexer-type (%sequence_lexer) before any lexer rules"; exit(-1); } 0132 switch(KDevPG::GDFA::type) 0133 { 0134 case KDevPG::TAscii: KDevPG::GDFA::type = KDevPG::SAscii; break; 0135 case KDevPG::TLatin1: KDevPG::GDFA::type = KDevPG::SLatin1; break; 0136 case KDevPG::TUtf8: KDevPG::GDFA::type = KDevPG::SUtf8; break; 0137 case KDevPG::TUcs2: KDevPG::GDFA::type = KDevPG::SUcs2; break; 0138 case KDevPG::TUtf16: KDevPG::GDFA::type = KDevPG::SUtf16; break; 0139 /* case KDevPG::TUcs4: KDevPG::GDFA::type = KDevPG::SUcs4; break; */ 0140 default: /* empty */; 0141 } 0142 } 0143 | T_INPUT_ENCODING T_STRING 0144 { 0145 if(KDevPG::globalSystem.hasLexer) 0146 { KDevPG::checkOut << "** ERROR you have to specify the lexer-type (%sequence_lexer) before any lexer rules"; exit(-1); } 0147 int base = (KDevPG::GDFA::type / 4) * 4; // warning: magic constant: number of different codecs 0148 QString str = $2; 0149 str = str.toLower(); 0150 str.replace('-', ""); 0151 if(str == "ascii") 0152 /* base += 0*/; 0153 else if(str == "latin1") 0154 base += 1; 0155 else if(str == "utf8") 0156 base += 2; 0157 else if(str == "ucs2") 0158 base += 3; 0159 else if(str == "utf16") 0160 base += 4; 0161 else if(str == "ucs4" || str == "utf32") 0162 base += 5; 0163 else 0164 { 0165 KDevPG::checkOut << "** ERROR unknown codec ``" << $2 << "''" << Qt::endl; 0166 exit(-1); 0167 } 0168 KDevPG::GDFA::type = KDevPG::AutomatonType(base); 0169 } 0170 | T_TOKEN_STREAM_DECLARATION T_IDENTIFIER ';' 0171 { KDevPG::globalSystem.tokenStream = $2; } 0172 | T_EXPORT_MACRO T_STRING 0173 { KDevPG::globalSystem.exportMacro = $2; } 0174 | T_EXPORT_MACRO_HEADER T_STRING 0175 { KDevPG::globalSystem.exportMacroHeader = $2; } 0176 | T_NAMESPACE_DECLARATION T_CODE 0177 { KDevPG::globalSystem.namespaceCode = $2; } 0178 | T_AST_DECLARATION T_CODE 0179 { KDevPG::globalSystem.astCode = $2; } 0180 | T_PARSER_DECLARATION_HEADER T_STRING 0181 { KDevPG::globalSystem.pushParserDeclarationHeader($2); } 0182 | T_PARSER_BITS_HEADER T_STRING 0183 { KDevPG::globalSystem.pushParserBitsHeader($2); } 0184 | T_AST_HEADER T_STRING 0185 { KDevPG::globalSystem.pushAstHeader($2); } 0186 | T_LEXER_DECLARATION_HEADER T_STRING 0187 { KDevPG::globalSystem.pushLexerDeclarationHeader($2); } 0188 | T_INPUT_STREAM T_STRING 0189 { KDevPG::globalSystem.inputStream = $2; } 0190 | T_LEXER_BITS_HEADER T_STRING 0191 { KDevPG::globalSystem.pushLexerBitsHeader($2); } 0192 | T_AST_BASE T_IDENTIFIER T_STRING 0193 { KDevPG::globalSystem.astBaseClasses[$2] = $3; } 0194 | T_PARSER_BASE T_STRING 0195 { KDevPG::globalSystem.parserBaseClass = $2; } 0196 | T_LEXER_BASE T_STRING 0197 { KDevPG::globalSystem.lexerBaseClass = $2; } 0198 | T_LEXER T_STRING { KDevPG::globalSystem.hasLexer = true; lexerEnv = $2; if(KDevPG::globalSystem.lexerActions[lexerEnv].empty()) KDevPG::globalSystem.lexerActions[lexerEnv].push_back("qDebug() << \"error\"; exit(-1);"); } T_ARROW lexer_declaration_rest ';' 0199 | T_LEXER { KDevPG::globalSystem.hasLexer = true; KDevPG::loadUnicodeData(); lexerEnv = "start"; if(KDevPG::globalSystem.lexerActions["start"].empty()) KDevPG::globalSystem.lexerActions["start"].push_back("qDebug() << \"error\"; exit(-1);"); } T_ARROW lexer_declaration_rest ';' 0200 ; 0201 0202 lexer_declaration_rest 0203 : regexp T_ARROW T_IDENTIFIER ';' 0204 { KDevPG::globalSystem.regexpById[$3] = $1; 0205 } lexer_declaration_rest 0206 | regexp code_opt opt_lexer_action ';' 0207 { 0208 if($1->acceptsEpsilon()) 0209 KDevPG::checkOut << "** WARNING Lexer rule accepting the empty word at line " << yyLine << Qt::endl; 0210 else if($1->isEmpty()) 0211 KDevPG::checkOut << "** WARNING Lexer rule not accepting anything at line " << yyLine << Qt::endl; 0212 QString s = QString($2) + QString(r); 0213 KDevPG::globalSystem.lexerEnvs[lexerEnv].push_back($1); 0214 KDevPG::globalSystem.lexerActions[lexerEnv].push_back(s); 0215 } lexer_declaration_rest 0216 | regexp T_LOOKAHEAD '(' regexp ')' code_opt opt_lexer_action ';' 0217 { 0218 if($1->acceptsEpsilon()) 0219 KDevPG::checkOut << "** WARNING Lexer rule accepting the empty word at line " << yyLine << Qt::endl; 0220 else if($1->isEmpty()) 0221 KDevPG::checkOut << "** WARNING Lexer rule not accepting anything at line " << yyLine << Qt::endl; 0222 bool ignore = false; 0223 auto minLen = $4->minLength(), maxLen = $4->maxLength(); 0224 if(minLen == 0) 0225 { 0226 KDevPG::checkOut << "** WARNING Lexer rule specifying epsilon-lookahead at line " << yyLine << ", ignore the lookahead." << Qt::endl; 0227 ignore = true; 0228 } 0229 else if(minLen != maxLen) 0230 { 0231 KDevPG::checkOut << "** WARNING Invalid lookahead (no fixed length) at line " << yyLine << " (min length: " << (minLen == -1 ? "none" : QString::number(minLen)) << ", max length: " << (maxLen == -2 ? "infinity" : (maxLen == -1 ? "none" : QString::number(maxLen))) << "), ignore the lookahead." << Qt::endl; 0232 ignore = true; 0233 } 0234 if(ignore) 0235 { 0236 QString s = QString($6) + QString(r); 0237 KDevPG::globalSystem.lexerEnvs[lexerEnv].push_back($1); 0238 KDevPG::globalSystem.lexerActions[lexerEnv].push_back(s); 0239 } 0240 else 0241 { 0242 QString s = "Iterator::plain() -= " + QString::number(minLen) + "; " + QString($6) + QString(r); 0243 *$1 <<= *$4; 0244 KDevPG::globalSystem.lexerEnvs[lexerEnv].push_back($1); 0245 KDevPG::globalSystem.lexerActions[lexerEnv].push_back(s); 0246 } 0247 } lexer_declaration_rest 0248 | regexp T_BARRIER '(' regexp ')' code_opt opt_lexer_action ';' 0249 { 0250 if($1->acceptsEpsilon()) 0251 KDevPG::checkOut << "** WARNING Lexer rule accepting the empty word at line " << yyLine << Qt::endl; 0252 else if($1->isEmpty()) 0253 KDevPG::checkOut << "** WARNING Lexer rule not accepting anything at line " << yyLine << Qt::endl; 0254 bool ignore = false; 0255 auto minLen = $4->minLength(), maxLen = $4->maxLength(); 0256 if(minLen == 0) 0257 { 0258 KDevPG::checkOut << "** WARNING Lexer rule specifying epsilon-barrier at line " << yyLine << ", ignore the barrier." << Qt::endl; 0259 ignore = true; 0260 } 0261 else if(minLen != maxLen) 0262 { 0263 KDevPG::checkOut << "** WARNING Invalid barrier (no fixed length) at line " << yyLine << " (min length: " << (minLen == -1 ? "none" : QString::number(minLen)) << ", max length: " << (maxLen == -2 ? "infinity" : (maxLen == -1 ? "none" : QString::number(maxLen))) << "), ignore the barrier." << Qt::endl; 0264 ignore = true; 0265 } 0266 if(ignore) 0267 { 0268 QString s = QString($6) + QString(r); 0269 KDevPG::globalSystem.lexerEnvs[lexerEnv].push_back($1); 0270 KDevPG::globalSystem.lexerActions[lexerEnv].push_back(s); 0271 } 0272 else 0273 { 0274 KDevPG::GNFA exclude = KDevPG::GNFA::anything(); 0275 exclude <<= *$4; 0276 exclude <<= KDevPG::GNFA::anything(); 0277 KDevPG::GNFA *staying = new KDevPG::GNFA(*$1); 0278 *staying ^= exclude; 0279 KDevPG::globalSystem.lexerEnvs[lexerEnv].push_back(staying); 0280 KDevPG::globalSystem.lexerActions[lexerEnv].push_back(QString($6) + QString(r)); 0281 // barrier should not get read partially 0282 exclude <<= KDevPG::GNFA::anyChar(); 0283 *$1 <<= *$4; 0284 *$1 ^= exclude; 0285 QString s = "Iterator::plain() -= " + QString::number(minLen) + "; " + QString($6) + QString(r); 0286 KDevPG::globalSystem.lexerEnvs[lexerEnv].push_back($1); 0287 KDevPG::globalSystem.lexerActions[lexerEnv].push_back(s); 0288 } 0289 } lexer_declaration_rest 0290 | T_FAIL T_CODE 0291 { 0292 KDevPG::globalSystem.lexerActions[lexerEnv][0] = QString($2); 0293 } lexer_declaration_rest 0294 | T_ENTER_RULE_SET T_CODE 0295 { 0296 KDevPG::globalSystem.enteringCode[lexerEnv] = QString($2); 0297 } lexer_declaration_rest 0298 | T_LEAVE_RULE_SET T_CODE 0299 { 0300 KDevPG::globalSystem.leavingCode[lexerEnv] = QString($2); 0301 } lexer_declaration_rest 0302 | /* empty */ 0303 ; 0304 0305 opt_lexer_action 0306 : T_TERMINAL { 0307 r = "\nlxRETURN(" + QString($1) + ")\n"; 0308 } 0309 | T_CONTINUE { 0310 r = "\nlxCONTINUE;\n"; 0311 } 0312 | /* empty */ { r = "\nlxSKIP\n"; } 0313 ; 0314 0315 regexp 0316 : regexp '|' regexp1 { $$ = new KDevPG::GNFA(*$1 |= *$3); delete $1; delete $3; } 0317 | regexp1 { $$ = $1; } 0318 ; 0319 0320 regexp1 0321 : regexp1 '&' regexp2 { $$ = new KDevPG::GNFA(*$1 &= *$3); delete $1; delete $3; } 0322 | regexp2 { $$ = $1; } 0323 ; 0324 0325 regexp2 0326 : regexp3 '^' regexp2 { $$ = new KDevPG::GNFA(*$1 ^= *$3); delete $1; delete $3; } 0327 | regexp3 { $$ = $1; } 0328 ; 0329 0330 regexp3 0331 : '~' regexp3 { $$ = new KDevPG::GNFA($2->negate()); delete $2; } 0332 | '?' regexp3 { $$ = new KDevPG::GNFA(*$2 |= KDevPG::GNFA::emptyWord()); delete $2; } 0333 | regexp4 { $$ = $1; } 0334 ; 0335 0336 regexp4 0337 : regexp4 regexp5 { $$ = new KDevPG::GNFA(*$1 <<= *$2); delete $1; delete $2; } 0338 | regexp5 { $$ = $1; } 0339 ; 0340 0341 regexp5 0342 : regexp5 '@' regexp6 { $$ = new KDevPG::GNFA(*$1); KDevPG::GNFA *tmp = new KDevPG::GNFA(*$3 <<= *$1); **tmp; *$$ <<= *tmp; delete tmp; delete $1; delete $3; } 0343 | regexp6 { $$ = $1; } 0344 ; 0345 0346 regexp6 0347 : regexp6 '*' { $$ = new KDevPG::GNFA(**$1); delete $1; } 0348 | regexp6 '+' { $$ = new KDevPG::GNFA(*$1); **$$; *$$ <<= *$1; delete $1; } 0349 | regexp7 { $$ = $1; } 0350 ; 0351 0352 regexp7 0353 : '(' regexp ')' { $$ = new KDevPG::GNFA(*$2); delete $2; } 0354 | '[' aregexp ']' { $$ = $2; } 0355 | '.' { $$ = new KDevPG::GNFA(KDevPG::GNFA::anyChar()); } 0356 | T_STRING { $$ = new KDevPG::GNFA(KDevPG::GNFA::word(KDevPG::unescaped(QByteArray($1)))); } 0357 | T_UNQUOTED_STRING { $$ = new KDevPG::GNFA(KDevPG::GNFA::word(KDevPG::unescaped(QByteArray($1)))); } 0358 | T_NAMED_REGEXP { 0359 if(!KDevPG::globalSystem.regexpById.contains($1)) 0360 { 0361 KDevPG::checkOut << "** ERROR: no named regexp " << $1 << Qt::endl; 0362 exit(-1); 0363 } 0364 KDevPG::GNFA *regexp = KDevPG::globalSystem.regexpById[$1]; 0365 if(!KDevPG::globalSystem.dfaForNfa.contains(regexp)) 0366 { 0367 KDevPG::globalSystem.dfaForNfa[regexp] = new KDevPG::GDFA(regexp->dfa()); 0368 KDevPG::globalSystem.dfaForNfa[regexp]->minimize(); 0369 *regexp = KDevPG::globalSystem.dfaForNfa[regexp]->nfa(); 0370 } 0371 $$ = new KDevPG::GNFA(*regexp); 0372 } 0373 | /* empty */ { $$ = new KDevPG::GNFA(KDevPG::GNFA::emptyWord()); } 0374 ; 0375 0376 aregexp 0377 : aregexp '|' aregexp1 { $$ = new KDevPG::GNFA(*$1 |= *$3); delete $1; delete $3; } 0378 | aregexp1 { $$ = $1; } 0379 ; 0380 0381 aregexp1 0382 : aregexp1 '&' aregexp2 { $$ = new KDevPG::GNFA(*$1 &= *$3); delete $1; delete $3; } 0383 | aregexp2 { $$ = $1; } 0384 ; 0385 0386 aregexp2 0387 : aregexp3 '^' aregexp2 { $$ = new KDevPG::GNFA(*$1 ^= *$3); delete $1; delete $3; } 0388 | aregexp3 { $$ = $1; } 0389 ; 0390 0391 aregexp3 0392 : '~' aregexp3 { $$ = new KDevPG::GNFA($2->negate()); delete $2; } 0393 | '?' aregexp3 { $$ = new KDevPG::GNFA(*$2 |= KDevPG::GNFA::emptyWord()); delete $2; } 0394 | aregexp4 { $$ = $1; } 0395 ; 0396 0397 aregexp4 0398 : aregexp4 aregexp5 { $$ = new KDevPG::GNFA(*$1 |= *$2); delete $1; delete $2; } 0399 | aregexp5 0400 ; 0401 0402 aregexp5 0403 : aregexp5 '@' aregexp6 { $$ = new KDevPG::GNFA(*$1); KDevPG::GNFA *tmp = new KDevPG::GNFA(*$3 <<= *$1); **tmp; *$$ <<= *tmp; delete tmp; delete $1; delete $3; } 0404 | aregexp6 { $$ = $1; } 0405 ; 0406 0407 aregexp6 0408 : aregexp6 '*' { $$ = new KDevPG::GNFA(**$1); delete $1; } 0409 | aregexp6 '+' { $$ = new KDevPG::GNFA(*$1); **$$; *$$ <<= *$1; delete $1; } 0410 | aregexp7 { $$ = $1; } 0411 ; 0412 0413 aregexp7 0414 : '(' regexp ')' { $$ = new KDevPG::GNFA(*$2); delete $2; } 0415 | '[' aregexp ']' { $$ = $2; } 0416 | '.' { $$ = new KDevPG::GNFA(KDevPG::GNFA::anyChar()); } 0417 | T_STRING { $$ = new KDevPG::GNFA(KDevPG::GNFA::word(KDevPG::unescaped(QByteArray($1)))); } 0418 | T_RANGE { 0419 quint32 begin, end; 0420 QString str = KDevPG::unescaped(QByteArray($1)); 0421 assert(str.size() >= 3 && str.size() <= 5); 0422 if(str[1] == '-') 0423 { 0424 begin = str[0].unicode(); 0425 if(str.size() == 3) 0426 end = str[2].unicode(); 0427 else 0428 end = QChar::surrogateToUcs4(str[2], str[3]); 0429 } 0430 else 0431 { 0432 begin = QChar::surrogateToUcs4(str[0], str[1]); 0433 assert(str[2] == '-'); 0434 if(str.size() == 4) 0435 end = str[3].unicode(); 0436 else 0437 end = QChar::surrogateToUcs4(str[3], str[4]); 0438 } 0439 $$ = new KDevPG::GNFA(KDevPG::GNFA::range(begin, end+1)); 0440 } 0441 | T_UNQUOTED_STRING { $$ = new KDevPG::GNFA(KDevPG::GNFA::collection(KDevPG::unescaped(QByteArray($1)))); } 0442 | T_NAMED_REGEXP { 0443 if(!KDevPG::globalSystem.regexpById.contains($1)) 0444 { 0445 KDevPG::checkOut << "** ERROR: no named regexp " << $1 << Qt::endl; 0446 exit(-1); 0447 } 0448 KDevPG::GNFA *regexp = KDevPG::globalSystem.regexpById[$1]; 0449 if(!KDevPG::globalSystem.dfaForNfa.contains(regexp)) 0450 { 0451 KDevPG::globalSystem.dfaForNfa[regexp] = new KDevPG::GDFA(regexp->dfa()); 0452 KDevPG::globalSystem.dfaForNfa[regexp]->minimize(); 0453 *regexp = KDevPG::globalSystem.dfaForNfa[regexp]->nfa(); 0454 } 0455 $$ = new KDevPG::GNFA(*regexp); 0456 } 0457 | /* empty */ { $$ = new KDevPG::GNFA(KDevPG::GNFA::emptyWord()); } 0458 ; 0459 0460 0461 member_declaration_rest 0462 : '(' T_PUBLIC T_DECLARATION ')' T_CODE 0463 { $$ = KDevPG::member(KDevPG::Settings::MemberItem::PublicDeclaration, $5); } 0464 | '(' T_PROTECTED T_DECLARATION ')' T_CODE 0465 { $$ = KDevPG::member(KDevPG::Settings::MemberItem::ProtectedDeclaration, $5); } 0466 | '(' T_PRIVATE T_DECLARATION ')' T_CODE 0467 { $$ = KDevPG::member(KDevPG::Settings::MemberItem::PrivateDeclaration, $5); } 0468 | '(' T_CONSTRUCTOR ')' T_CODE 0469 { $$ = KDevPG::member(KDevPG::Settings::MemberItem::ConstructorCode, $4); } 0470 | '(' T_DESTRUCTOR ')' T_CODE 0471 { $$ = KDevPG::member(KDevPG::Settings::MemberItem::DestructorCode, $4); } 0472 ; 0473 0474 declared_tokens 0475 : T_TERMINAL { KDevPG::globalSystem.pushTerminal($1,$1); } 0476 | T_TERMINAL '(' T_STRING ')' { KDevPG::globalSystem.pushTerminal($1,$3); } 0477 | declared_tokens ',' T_TERMINAL { KDevPG::globalSystem.pushTerminal($3,$3); } 0478 | declared_tokens ',' T_TERMINAL '(' T_STRING ')' 0479 { KDevPG::globalSystem.pushTerminal($3,$5); } 0480 ; 0481 0482 rules 0483 : /* empty */ 0484 | rules item ';' { KDevPG::globalSystem.pushRule($2); } 0485 ; 0486 0487 primary_item 0488 : '0' { $$ = KDevPG::globalSystem.zero(); } 0489 | '(' option_item ')' { $$ = $2; } 0490 | try_item { $$ = $1; } 0491 | primary_atom { $$ = $1; } 0492 | T_INLINE T_IDENTIFIER { $$ = KDevPG::inlinedNonTerminal(KDevPG::globalSystem.pushSymbol($2)); } 0493 | name scope primary_atom { $$ = KDevPG::annotation($1, $3, false, $2); } 0494 | '#' name scope primary_atom { $$ = KDevPG::annotation($2, $4, true, $3); } 0495 ; 0496 0497 primary_atom 0498 : T_IDENTIFIER rule_arguments_opt { $$ = KDevPG::nonTerminal(KDevPG::globalSystem.pushSymbol($1), $2); } 0499 | T_TERMINAL { $$ = KDevPG::globalSystem.terminal($1); } 0500 ; 0501 0502 try_item 0503 : T_TRY_RECOVER '(' option_item ')' 0504 { 0505 KDevPG::globalSystem.needStateManagement = true; 0506 $$ = KDevPG::tryCatch($3, nullptr); 0507 } 0508 | T_TRY_ROLLBACK '(' option_item ')' T_CATCH '(' option_item ')' 0509 { 0510 KDevPG::globalSystem.needStateManagement = true; 0511 $$ = KDevPG::tryCatch($3, $7); 0512 } 0513 0514 rule_arguments_opt 0515 : /* empty */ { $$ = const_cast<char*>(""); } 0516 | T_RULE_ARGUMENTS { $$ = $1; } 0517 ; 0518 0519 name 0520 : T_IDENTIFIER { $$ = $1; } 0521 /* | T_IDENTIFIER '.' T_IDENTIFIER 0522 { 0523 $$ = $3; 0524 fprintf(stderr, "** WARNING support for scoped name" 0525 " ``%s.%s'' not implemented\n", $1, $3); 0526 }*/ 0527 ; 0528 0529 scope 0530 : '=' { $$ = KDevPG::Model::VariableDeclarationItem::StorageAstMember; } 0531 | ':' { $$ = KDevPG::Model::VariableDeclarationItem::StorageTemporary; } 0532 ; 0533 0534 unary_item 0535 : primary_item '+' { $$ = KDevPG::plus($1); } 0536 | primary_item '*' { $$ = KDevPG::star($1); } 0537 | primary_item { $$ = $1; } 0538 | '?' primary_item { $$ = KDevPG::alternative($2, KDevPG::globalSystem.zero()); } 0539 ; 0540 0541 postfix_item 0542 : unary_item { $$ = $1; } 0543 | postfix_item '@' primary_item 0544 { 0545 KDevPG::CloneTree cl; 0546 $$ = KDevPG::cons($1, KDevPG::star(KDevPG::cons(cl.clone($3), cl.clone($1)))); 0547 } 0548 | postfix_item T_CODE { $$ = KDevPG::action($1, $2); } 0549 | T_CODE { $$ = KDevPG::action(nullptr, $1); } 0550 ; 0551 0552 item_sequence 0553 : postfix_item { $$ = $1; } 0554 | item_sequence postfix_item { $$ = KDevPG::cons($1, $2); } 0555 ; 0556 0557 conditional_item 0558 : item_sequence { $$ = $1; } 0559 | '?' T_CODE item_sequence { $$ = KDevPG::condition($2, $3); } 0560 ; 0561 0562 option_item 0563 : conditional_item { $$ = $1; } 0564 | option_item '|' conditional_item { $$ = KDevPG::alternative($1, $3); } 0565 ; 0566 0567 item 0568 : option_item T_ARROW T_IDENTIFIER T_CODE '[' variableDeclarations ']' 0569 { 0570 $$ = KDevPG::evolve($1, KDevPG::globalSystem.pushSymbol($3), 0571 (KDevPG::Model::VariableDeclarationItem*) $6, $4); 0572 } 0573 | option_item T_ARROW T_IDENTIFIER '[' variableDeclarations ']' code_opt 0574 { 0575 $$ = KDevPG::evolve($1, KDevPG::globalSystem.pushSymbol($3), 0576 (KDevPG::Model::VariableDeclarationItem*) $5, $7); 0577 } 0578 | option_item T_ARROW T_IDENTIFIER code_opt 0579 { $$ = KDevPG::evolve($1, KDevPG::globalSystem.pushSymbol($3), nullptr, $4); } 0580 | { if(KDevPG::globalSystem.generateAst == false) 0581 { 0582 qFatal("Operator-expression-parsing is not yet supported with --no-ast!"); 0583 exit(-1); 0584 } 0585 operatorNode = KDevPG::createNode<KDevPG::Model::OperatorItem>(); 0586 } operatorRule { KDevPG::globalSystem.needOperatorStack = true; $$ = $2; } 0587 ; 0588 0589 code_opt 0590 : /* empty */ { $$ = const_cast<char*>(""); } 0591 | T_CODE { $$ = $1; } 0592 ; 0593 0594 0595 operatorDeclarations 0596 : operatorDeclaration operatorDeclarations 0597 | /* empty */ { ; } 0598 ; 0599 0600 operatorRule 0601 : T_LOPR primary_atom operatorDeclarations T_ROPR T_IDENTIFIER '[' variableDeclarations ']' code_opt 0602 { 0603 operatorNode->mBase = (KDevPG::Model::NonTerminalItem*)$2; 0604 operatorNode->mName = $5; 0605 if(!KDevPG::globalSystem.astBaseClasses.contains(operatorNode->mBase->mSymbol->mName)) 0606 KDevPG::globalSystem.astBaseClasses[operatorNode->mBase->mSymbol->mName] = KDevPG::capitalized(operatorNode->mName) + "Ast"; 0607 $$ = KDevPG::evolve(operatorNode, KDevPG::globalSystem.pushSymbol($5), (KDevPG::Model::VariableDeclarationItem*)$7, $9); 0608 } 0609 | T_LOPR primary_atom operatorDeclarations T_ROPR T_IDENTIFIER T_CODE '[' variableDeclarations ']' 0610 { 0611 operatorNode->mBase = (KDevPG::Model::NonTerminalItem*)$2; 0612 operatorNode->mName = $5; 0613 if(!KDevPG::globalSystem.astBaseClasses.contains(operatorNode->mBase->mSymbol->mName)) 0614 KDevPG::globalSystem.astBaseClasses[operatorNode->mBase->mSymbol->mName] = KDevPG::capitalized(operatorNode->mName) + "Ast"; 0615 $$ = KDevPG::evolve(operatorNode, KDevPG::globalSystem.pushSymbol($5), (KDevPG::Model::VariableDeclarationItem*)$8, $6); 0616 } 0617 | T_LOPR primary_atom operatorDeclarations T_ROPR T_IDENTIFIER code_opt 0618 { 0619 operatorNode->mBase = (KDevPG::Model::NonTerminalItem*)$2; 0620 operatorNode->mName = $5; 0621 if(!KDevPG::globalSystem.astBaseClasses.contains(operatorNode->mBase->mSymbol->mName)) 0622 KDevPG::globalSystem.astBaseClasses[operatorNode->mBase->mSymbol->mName] = KDevPG::capitalized(operatorNode->mName) + "Ast"; 0623 $$ = KDevPG::evolve(operatorNode, KDevPG::globalSystem.pushSymbol($5), nullptr, $6); 0624 } 0625 ; 0626 0627 operatorDeclaration 0628 : T_BIN operator priority assoc { operatorNode->pushBin(*$2, $4, $3); free($2); } 0629 | T_TERN operator operator priority assoc { operatorNode->pushTern(*$2, *$3, $5, $4); free($2); free($3); } 0630 | T_PRE operator priority { operatorNode->pushPre(*$2, $3); free($2); } 0631 | T_POST operator priority { operatorNode->pushPost(*$2, "0", $3); free($2); free($3); } 0632 | T_POST operator priority assoc { operatorNode->pushPost(*$2, $4, $3); free($2); } 0633 | T_PAREN operator operator { operatorNode->pushParen(*$2, *$3); free($2); free($3); } 0634 ; 0635 0636 priority 0637 : '0' { $$ = (char*)"0"; } 0638 | T_NUMBER { $$ = $1; } 0639 | T_PRIORITY T_CODE { $$ = $2; } 0640 ; 0641 0642 assoc 0643 : T_LEFT_ASSOC { $$ = (char*)"1"; } 0644 | T_RIGHT_ASSOC { $$ = (char*)"0"; } 0645 | T_IS_LEFT_ASSOC T_CODE { uint yyleng = strlen($2); 0646 char *tmp = (char*)calloc(yyleng+7, sizeof(char)); 0647 tmp[0] = '('; 0648 strcpy(tmp+1, $2); 0649 strcpy(tmp+yyleng+6-6+1, "?1:0)"); 0650 $$ = tmp; 0651 } 0652 | T_IS_RIGHT_ASSOC T_CODE { uint yyleng = strlen($2); 0653 char *tmp = (char*)calloc(yyleng+7, sizeof(char)); 0654 tmp[0] = '('; 0655 strcpy(tmp+1, $2); 0656 strcpy(tmp+yyleng+6-6+1, "?0:1)"); 0657 $$ = tmp; 0658 } 0659 ; 0660 0661 operator 0662 : '?' T_CODE T_TERMINAL T_CODE { $$ = KDevPG::makeOperator(KDevPG::globalSystem.terminal($3), $2, $4); } 0663 | '?' T_CODE T_TERMINAL { $$ = KDevPG::makeOperator(KDevPG::globalSystem.terminal($3), $2, ""); } 0664 | T_TERMINAL T_CODE { $$ = KDevPG::makeOperator(KDevPG::globalSystem.terminal($1), "", $2); } 0665 | T_TERMINAL { $$ = KDevPG::makeOperator(KDevPG::globalSystem.terminal($1), "", ""); } 0666 ; 0667 0668 variableDeclarations 0669 : variableDeclaration { $$ = $1; } 0670 | variableDeclarations variableDeclaration 0671 { 0672 KDevPG::Model::VariableDeclarationItem *last = (KDevPG::Model::VariableDeclarationItem*) $1; 0673 while (last->mNext != nullptr) { 0674 last = last->mNext; 0675 } 0676 last->mNext = (KDevPG::Model::VariableDeclarationItem*) $2; 0677 $$ = $1; 0678 } 0679 ; 0680 0681 variableDeclaration 0682 : declarationType_opt storageType variableType T_IDENTIFIER ':' T_IDENTIFIER 0683 { $$ = KDevPG::variableDeclaration($1, $2, $3, false, $4, $6); } 0684 | declarationType_opt storageType T_TOKEN T_IDENTIFIER ';' 0685 { $$ = KDevPG::variableDeclaration($1, $2, KDevPG::Model::VariableDeclarationItem::TypeToken, false, $4, ""); } 0686 | declarationType_opt storageType variableType '#' T_IDENTIFIER ':' T_IDENTIFIER 0687 { $$ = KDevPG::variableDeclaration($1, $2, $3, true, $5, $7); } 0688 | declarationType_opt storageType T_TOKEN '#' T_IDENTIFIER ';' 0689 { $$ = KDevPG::variableDeclaration($1, $2, KDevPG::Model::VariableDeclarationItem::TypeToken, true, $5, ""); } 0690 ; 0691 0692 declarationType_opt 0693 : /* empty */ { $$ = KDevPG::Model::VariableDeclarationItem::DeclarationLocal; } 0694 | T_ARGUMENT { $$ = KDevPG::Model::VariableDeclarationItem::DeclarationArgument; } 0695 ; 0696 0697 storageType 0698 : T_MEMBER { $$ = KDevPG::Model::VariableDeclarationItem::StorageAstMember; } 0699 | T_TEMPORARY { $$ = KDevPG::Model::VariableDeclarationItem::StorageTemporary; } 0700 ; 0701 0702 variableType 0703 : T_NODE { $$ = KDevPG::Model::VariableDeclarationItem::TypeNode; } 0704 | T_VARIABLE { $$ = KDevPG::Model::VariableDeclarationItem::TypeVariable; } 0705 ; 0706 0707 %%