Warning, /frameworks/kholidays/src/parsers/plan2/holidayparserplan.ypp is written in an unsupported language. File is not indexed.
0001 /* 0002 Original version from plan: 0003 SPDX-FileCopyrightText: Thomas Driemeyer <thomas@bitrot.de> 0004 0005 Adapted for use in KOrganizer: 0006 SPDX-FileCopyrightText: Preston Brown <pbrown@kde.org> and 0007 SPDX-FileCopyrightText: Reinhold Kainhofer <reinhold@kainhofer.com> 0008 0009 Portions contributed: 0010 SPDX-FileCopyrightText: Peter Littlefield <plittle@sofkin.ca> 0011 0012 Major rewrite using Bison C++ skeleton: 0013 SPDX-FileCopyrightText: 2010 John Layt <john@layt.net> 0014 0015 SPDX-License-Identifier: LGPL-2.0-or-later 0016 */ 0017 0018 %{ /*** C/C++ Declarations ***/ 0019 0020 #include <stdio.h> 0021 #include <stdlib.h> 0022 #include <pwd.h> 0023 #include <sys/types.h> 0024 #include <sys/stat.h> 0025 #include <limits.h> 0026 #include <string> 0027 0028 #include <QString> 0029 0030 0031 %} 0032 0033 /*** yacc/bison Declarations ***/ 0034 0035 /* Require bison 2.3 or later */ 0036 %require "2.3" 0037 0038 /* add debug output code to generated parser. disable this for release 0039 * versions. */ 0040 %debug 0041 0042 /* write out a header file containing the token defines */ 0043 %defines 0044 0045 /* use newer C++ skeleton file */ 0046 %skeleton "lalr1.cc" 0047 0048 /* namespace to enclose parser in */ 0049 %name-prefix="KHolidays" 0050 0051 /* set the parser's class identifier */ 0052 %define "parser_class_name" "HolidayParserPlan" 0053 0054 /* keep track of the current position within the input */ 0055 %locations 0056 %initial-action 0057 { 0058 // initialize the initial location object 0059 @$.begin.filename = driver.fileToParse(); 0060 @$.end.filename = @$.begin.filename; 0061 }; 0062 0063 /* The driver is passed by reference to the parser and to the scanner. This 0064 * provides a simple but effective pure interface, not relying on global 0065 * variables. */ 0066 %parse-param { class HolidayParserDriverPlan& driver } 0067 0068 /* verbose error messages */ 0069 %error-verbose 0070 0071 /*** Grammar Tokens ***/ 0072 0073 %union { int ival; char *sval; } 0074 0075 %type <ival> offset conditionaloffset length expr pexpr number month reldate wdaycondition monthnumber 0076 %type <sval> categories 0077 %token END 0 0078 %token <ival> NUMBER MONTH WDAY 0079 %token <sval> STRING CATEGORY CALENDAR 0080 %token INOP PLUS MINUS YEAR LEAPYEAR SHIFT IF 0081 %token LENGTH EASTER EQ NE LE GE LT GT PASCHA COUNTRY LANGUAGE NAME DESCRIPTION 0082 0083 %destructor { free( $$ ); } STRING 0084 0085 %left OR 0086 %left AND 0087 %right EQ NE LE GE LT GT 0088 %left '-' '+' 0089 %left '*' '/' '%' 0090 %nonassoc '!' 0091 %nonassoc UMINUS 0092 %left '?' ':' 0093 0094 %start planfile 0095 0096 /*** End Grammar Tokens ***/ 0097 0098 %{ 0099 0100 #include "holidayparserdriverplan_p.h" 0101 #include "holidayscannerplan_p.h" 0102 0103 /* this "connects" the bison parser in the driver to the flex scanner class 0104 * object. it defines the yylex() function call to pull the next token from the 0105 * current lexer object of the driver context. */ 0106 #undef yylex 0107 #define yylex driver.m_scanner->lex 0108 0109 %} 0110 0111 %% /*** Grammar Rules ***/ 0112 0113 planfile : metadata list 0114 ; 0115 0116 metadata : countrycode languagecode name description 0117 ; 0118 0119 countrycode : { driver.setFileCountryCode( QString() ); } 0120 | COUNTRY STRING { char *s = $2; driver.setFileCountryCode( QString::fromUtf8( s ) ); free( s ); $2 = NULL; } 0121 ; 0122 0123 languagecode : { driver.setFileLanguageCode( QString() ); } 0124 | LANGUAGE STRING { char *s = $2; driver.setFileLanguageCode( QString::fromUtf8( s ) ); free( s ); $2 = NULL; } 0125 ; 0126 0127 name : { driver.setFileName( QString() ); } 0128 | NAME STRING { char *s = $2; driver.setFileName( QString::fromUtf8( s ) ); free( s ); $2 = NULL; } 0129 ; 0130 0131 description : { driver.setFileDescription( QString() ); } 0132 | DESCRIPTION STRING { char *s = $2; driver.setFileDescription( QString::fromUtf8( s ) ); free( s ); $2 = NULL; } 0133 ; 0134 0135 list : 0136 | list eventname categories calendar eventrule 0137 ; 0138 0139 eventname : STRING { char *s = $1; driver.setEventName( QString::fromUtf8( s ) ); free( s ); $1 = NULL; } 0140 ; 0141 0142 categories : CATEGORY { driver.setEventCategory( $1 ); } 0143 | categories CATEGORY { driver.setEventCategory( $1 ); } 0144 ; 0145 0146 calendar : { driver.setEventCalendarType( QLatin1String("gregorian") ); } 0147 | CALENDAR { driver.setEventCalendarType( QString::fromUtf8( $1 ) ); } 0148 ; 0149 0150 eventrule : EASTER offset length { driver.setFromEaster( $2, $3 ); } 0151 | PASCHA offset length { driver.setFromPascha( $2, $3 ); } 0152 | date offset conditionaloffset length { driver.setFromDate( $2, $3, $4 ); } 0153 | WDAY offset length { driver.setFromWeekdayInMonth( 1, $1, 1, $2, $3 ); } 0154 | pexpr WDAY offset length { driver.setFromWeekdayInMonth( $1, $2, 1, $3, $4 ); } 0155 | pexpr WDAY INOP month offset length { driver.setFromWeekdayInMonth( $1, $2, $4, $5, $6 ); } 0156 | WDAY pexpr date offset length { driver.setFromRelativeWeekday( $2, $1, $4, $5 ); } 0157 ; 0158 0159 offset : { $$ = 0; } 0160 | PLUS expr { $$ = $2; } 0161 | MINUS expr { $$ = -$2; } 0162 ; 0163 0164 conditionaloffset : { $$ = 0; } 0165 | SHIFT wdaycondition IF wdaycondition { $$ = ( $2 << 8 ) | $4; } 0166 ; 0167 0168 wdaycondition : { $$ = 0; } 0169 | WDAY { $$ = ( 1 << $1 ); } 0170 | WDAY OR wdaycondition { $$ = ( 1 << $1 ) | $3; } 0171 ; 0172 0173 length : { $$ = 1; } 0174 | LENGTH expr { $$ = $2; } 0175 ; 0176 0177 date : pexpr '.' month { driver.setEventDate( -99999, $3, $1 ); } 0178 | pexpr '.' month '.' { driver.setEventDate( -99999, $3, $1 ); } 0179 | pexpr '.' month '.' expr { driver.setEventDate( $5, $3, $1 ); } 0180 | month '/' pexpr { driver.setEventDate( -99999, $1, $3 ); } 0181 | month '/' pexpr '/' pexpr { driver.setEventDate( $5, $1, $3 ); } 0182 | monthnumber pexpr { driver.setEventDate( -99999, $1, $2 ); } 0183 | monthnumber pexpr pexpr { driver.setEventDate( $3, $1, $2 ); } 0184 | pexpr monthnumber { driver.setEventDate( -99999, $2, $1 ); } 0185 | pexpr monthnumber pexpr { driver.setEventDate( $3, $2, $1 ); } 0186 | pexpr '.' MONTH pexpr { driver.setEventDate( $4, $3, $1 ); } 0187 | pexpr { driver.setEventDate( $1 ); } 0188 ; 0189 0190 reldate : STRING { char *s = $1; $$ = driver.julianDayFromEventName( s ); free( s ); $1 = NULL; } 0191 | EASTER { $$ = driver.julianDayFromEaster(); } 0192 | PASCHA { $$ = driver.julianDayFromPascha(); } 0193 | pexpr '.' month { $$ = driver.julianDayFromMonthDay( $3, $1 ); } 0194 | pexpr '.' month '.' { $$ = driver.julianDayFromMonthDay( $3, $1 ); } 0195 | month '/' pexpr { $$ = driver.julianDayFromMonthDay( $1, $3 ); } 0196 | pexpr MONTH { $$ = driver.julianDayFromMonthDay( $2, $1 ); } 0197 | monthnumber pexpr { $$ = driver.julianDayFromMonthDay( $1, $2 ); } 0198 | WDAY pexpr pexpr { $$ = driver.julianDayFromRelativeWeekday( $2, $1, $3 ); } 0199 | pexpr WDAY INOP month { $$ = driver.julianDayFromWeekdayInMonth( $1, $2, $4 ); } 0200 ; 0201 0202 month : monthnumber 0203 | pexpr { $$ = driver.adjustedMonthNumber( $1 ); } 0204 ; 0205 0206 monthnumber : MONTH { $$ = driver.adjustedMonthNumber( $1 ); } 0207 ; 0208 0209 expr : pexpr { $$ = $1; } 0210 | expr OR expr { $$ = $1 || $3; } 0211 | expr AND expr { $$ = $1 && $3; } 0212 | expr EQ expr { $$ = $1 == $3; } 0213 | expr NE expr { $$ = $1 != $3; } 0214 | expr LE expr { $$ = $1 <= $3; } 0215 | expr GE expr { $$ = $1 >= $3; } 0216 | expr LT expr { $$ = $1 < $3; } 0217 | expr GT expr { $$ = $1 > $3; } 0218 | expr '+' expr { $$ = $1 + $3; } 0219 | expr '-' expr { $$ = $1 - $3; } 0220 | expr '*' expr { $$ = $1 * $3; } 0221 | expr '/' expr { $$ = $3 ? $1 / $3 : 0; } 0222 | expr '%' expr { $$ = $3 ? $1 % $3 : 0; } 0223 | expr '?' expr ':' expr { $$ = $1 ? $3 : $5; } 0224 | '!' expr { $$ = !$2; } 0225 | '[' reldate ']' { $$ = $2; } 0226 ; 0227 0228 pexpr : '(' expr ')' { $$ = $2; } 0229 | number { $$ = $1; } 0230 ; 0231 0232 number : NUMBER 0233 | '-' NUMBER %prec UMINUS { $$ = -$2; } 0234 | YEAR { $$ = driver.parseYear(); } 0235 | LEAPYEAR pexpr { $$ = driver.isLeapYear( $2 ); } 0236 ; 0237 0238 %% 0239 0240 /*** Private Yacc callbacks and helper functions ***/ 0241 0242 void KHolidays::HolidayParserPlan::error( const KHolidays::HolidayParserPlan::location_type &errorLocation, const std::string &errorMessage ) 0243 { 0244 driver.error( errorLocation, errorMessage.c_str() ); 0245 }