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 }