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 }