Warning, /utilities/kregexpeditor/src/qregexpparser.y is written in an unsupported language. File is not indexed.
0001 /* 0002 * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org> 0003 * 0004 * This library is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU Library General Public 0006 * License version 2 as published by the Free Software Foundation. 0007 * 0008 * This library is distributed in the hope that it will be useful, 0009 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0011 * Library General Public License for more details. 0012 * 0013 * You should have received a copy of the GNU Library General Public License 0014 * along with this library; see the file COPYING.LIB. If not, write to 0015 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0016 * Boston, MA 02110-1301, USA. 0017 **/ 0018 %{ 0019 #ifndef YYENABLE_NLS 0020 # define YYENABLE_NLS 0 0021 #endif 0022 0023 #ifndef YYLTYPE_IS_TRIVIAL 0024 # define YYLTYPE_IS_TRIVIAL 0 0025 #endif 0026 0027 #include <KLocalizedString> 0028 #include <kmessagebox.h> 0029 0030 0031 #include <stdlib.h> 0032 0033 #include "regexp.h" 0034 #include "textregexp.h" 0035 #include "textrangeregexp.h" 0036 #include "repeatregexp.h" 0037 #include "lookaheadregexp.h" 0038 #include "concregexp.h" 0039 #include "altnregexp.h" 0040 #include "positionregexp.h" 0041 #include "dotregexp.h" 0042 #include "compoundregexp.h" 0043 #include "gen_qregexpparser.hh" 0044 0045 #define YY_EXTRA_TYPE struct parse_context * 0046 0047 extern int yylex( YYSTYPE* yylval, yyscan_t scanner ); 0048 extern void scannerInit( yyscan_t* scanner, struct parse_context* context, const QString& qstr ); 0049 extern void scannerDestroy( yyscan_t scanner ); 0050 int yyerror( yyscan_t scanner, struct parse_context* context, const char * ); 0051 void setParseResult( RegExp*, struct parse_context* ); 0052 RegExp* parseQtRegExp( const QString &qstr, bool* ok ); 0053 %} 0054 0055 %code requires { 0056 #include "qregexpparsercommon.h" 0057 #ifndef YY_TYPEDEF_YY_SCANNER_T 0058 #define YY_TYPEDEF_YY_SCANNER_T 0059 typedef void *yyscan_t; 0060 #endif 0061 } 0062 0063 %union { 0064 struct { 0065 int min; 0066 int max; 0067 } range; 0068 int backRef; 0069 RegExp* regexp; 0070 char ch; 0071 } 0072 0073 %token TOK_Dot 0074 %token TOK_Dollar 0075 %token TOK_Carat 0076 %token TOK_MagicLeftParent 0077 %token TOK_PosLookAhead 0078 %token TOK_NegLookAhead 0079 %token TOK_LeftParen 0080 %token TOK_RightParent 0081 %token TOK_Bar 0082 %token TOK_Quantifier 0083 %token TOK_BackRef 0084 %token TOK_CharClass 0085 %token TOK_Char 0086 %token TOK_EscapeChar 0087 %token TOK_PosWordChar 0088 %token TOK_PosNonWordChar 0089 0090 %start regexp 0091 0092 %define api.pure 0093 0094 %param { yyscan_t scanner } 0095 %parse-param { struct parse_context *context } 0096 0097 %% 0098 0099 empty : /* nothing */ ; 0100 0101 regexp : expression { setParseResult( $<regexp>1, context ) ; } 0102 | empty { setParseResult( new ConcRegExp( false ), context ); } 0103 ; 0104 0105 expression : expression TOK_Bar term { 0106 if ( dynamic_cast<AltnRegExp*>( $<regexp>1 ) ) { 0107 $<regexp>$ = $<regexp>1; 0108 } 0109 else { 0110 $<regexp>$ = new AltnRegExp( false ); 0111 dynamic_cast<AltnRegExp*>( $<regexp>$ )->addRegExp( $<regexp>1 ); 0112 } 0113 dynamic_cast<AltnRegExp*>( $<regexp>$ )->addRegExp( $<regexp>3 ); 0114 } 0115 | term { $<regexp>$ = $<regexp>1; } 0116 | expression TOK_Bar { 0117 if ( dynamic_cast<AltnRegExp*>( $<regexp>1 ) ) { 0118 $<regexp>$ = $<regexp>1; 0119 } 0120 else { 0121 $<regexp>$ = new AltnRegExp( false ); 0122 dynamic_cast<AltnRegExp*>( $<regexp>$ )->addRegExp( $<regexp>1 ); 0123 } 0124 dynamic_cast<AltnRegExp*>( $<regexp>$ )->addRegExp( new TextRegExp( false, QString::fromLatin1("") ) ); 0125 } 0126 | TOK_Bar term { 0127 $<regexp>$ = new AltnRegExp( false ); 0128 dynamic_cast<AltnRegExp*>( $<regexp>$ )->addRegExp( new TextRegExp( false, QString::fromLatin1("") ) ); 0129 dynamic_cast<AltnRegExp*>( $<regexp>$ )->addRegExp( $<regexp>2 ); 0130 } 0131 | TOK_Bar { $<regexp>$ = new AltnRegExp( false ); } 0132 ; 0133 0134 term : term factor { 0135 RegExp* last = dynamic_cast<ConcRegExp*>( $<regexp>1 )->lastRegExp(); 0136 TextRegExp *reg1, *reg2; 0137 0138 if ( last && ( reg1 = dynamic_cast<TextRegExp*>( last ) ) && 0139 ( reg2 = dynamic_cast<TextRegExp*>( $<regexp>2 ) ) ) { 0140 reg1->append( reg2->text() ); 0141 delete reg2; 0142 } 0143 else { 0144 dynamic_cast<ConcRegExp*>($<regexp>$)->addRegExp( $<regexp>2 ); 0145 } 0146 $<regexp>$ = $<regexp>1; 0147 } 0148 | factor { 0149 ConcRegExp* reg = new ConcRegExp( false ); 0150 reg->addRegExp( $<regexp>1 ); 0151 $<regexp>$ = reg; 0152 } 0153 ; 0154 0155 factor : atom TOK_Quantifier { 0156 $<regexp>$ = new RepeatRegExp( false, $<range>2.min, $<range>2.max, $<regexp>1 ); 0157 } 0158 | atom { $<regexp>$ = $<regexp>1; } 0159 ; 0160 0161 atom : TOK_LeftParen expression TOK_RightParent { 0162 $<regexp>$ = $<regexp>2; 0163 } 0164 | TOK_MagicLeftParent expression TOK_RightParent { $<regexp>$ = $<regexp>2; } 0165 | TOK_PosLookAhead expression TOK_RightParent { 0166 $<regexp>$ = new LookAheadRegExp( false, LookAheadRegExp::POSITIVE, $<regexp>2 ); 0167 } 0168 | TOK_NegLookAhead expression TOK_RightParent { 0169 $<regexp>$ = new LookAheadRegExp( false, LookAheadRegExp::NEGATIVE, $<regexp>2 ); 0170 } 0171 | TOK_CharClass { $<regexp>$ = $<regexp>1; } 0172 | char { $<regexp>$ = $<regexp>1; } 0173 | TOK_Dollar { $<regexp>$ = new PositionRegExp( false, PositionRegExp::ENDLINE ); } 0174 | TOK_Carat { $<regexp>$ = new PositionRegExp( false, PositionRegExp::BEGLINE ); } 0175 | TOK_Dot { $<regexp>$ = new DotRegExp( false ); } 0176 | TOK_BackRef { 0177 QString match = QString::fromLocal8Bit("\\%1").arg( $<backRef>1 ); 0178 $<regexp>$ = new TextRegExp( false, match ); 0179 context->backrefs << match; 0180 } 0181 | TOK_PosWordChar { $<regexp>$ = new PositionRegExp( false, PositionRegExp::WORDBOUNDARY ); } 0182 | TOK_PosNonWordChar { $<regexp>$ = new PositionRegExp( false, PositionRegExp::NONWORDBOUNDARY ); } 0183 ; 0184 0185 char : TOK_Char { 0186 if ( $<ch>1 == '{' || $<ch>1 == '}' || $<ch>1 == '[' || $<ch>1 == ']' || $<ch>1 == '\\' ) { 0187 yyerror( scanner, context, "illigal character - needs escaping" ); 0188 } 0189 $<regexp>$ = new TextRegExp( false, QString::fromLocal8Bit("%1").arg($<ch>1)); 0190 } 0191 | TOK_EscapeChar { $<regexp>$ = new TextRegExp( false, QString::fromLocal8Bit("%1").arg($<ch>1)); } 0192 ; 0193 0194 %% 0195 0196 RegExp* parseQtRegExp( const QString &qstr, bool* ok ) { 0197 struct parse_context context; 0198 yyscan_t scanner; 0199 context.result = 0; 0200 context.nerrs = 0; 0201 scannerInit( &scanner, &context, qstr ); 0202 (void) yyparse( scanner, &context ); 0203 scannerDestroy( scanner ); 0204 for (const QString &match : std::as_const(context.backrefs)) { 0205 KMessageBox::information(nullptr,i18n("<p>Back reference regular expressions are not supported.</p>" 0206 "<p><tt>\\1</tt>, <tt>\\2</tt>, ... are <i>back references</i>, meaning they " 0207 "refer to previous matches. " 0208 "Unfortunately this is not supported in the current version of this editor.</p>" 0209 "<p>In the graphical area the text <b>%1</b> has been inserted. This is however " 0210 "just a workaround to ensure that the application handles the regexp at all. " 0211 "Therefore, as soon as you edit the regular expression in the graphical area, " 0212 "the back reference will be replaced by matching the text <b>%2</b> literally.</p>", 0213 match, match ), 0214 i18n("Back reference regular expressions not supported"), 0215 QString::fromLocal8Bit("backReferenceNotSupported") ); 0216 } 0217 *ok = ( context.nerrs == 0 ); 0218 return context.result; 0219 } 0220 0221 void setParseResult( RegExp* regexp, struct parse_context* context ) { 0222 context->result = regexp; 0223 } 0224 0225 int yyerror( yyscan_t, struct parse_context* context, const char * ) { 0226 context->nerrs++; 0227 return 0; 0228 }