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 %%