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 }