YoushouldhavereceivedacopyoftheGNUGeneralPublicLicense
along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains partoralloftheBisonparserskeletonanddistributethatwork undertermsofyourchoice,solongasthatworkisn'titselfa parsergeneratorusingtheskeletonoramodifiedversionthereof asaparserskeleton.Alternatively,ifyoumodifyorredistribute theparserskeletonitself,youmay(atyouroption)removethis specialexception,whichwillcausetheskeletonandtheresulting BisonoutputfilestobelicensedundertheGNUGeneralPublic Licensewithoutthisspecialexception.
ThisspecialexceptionwasaddedbytheFreeSoftwareFoundationin
version 2.2 of Bison. */
/* C LALR(1) parser skeleton written by Richard Stallman, by
simplifying the original so-called "semantic" parser. */
/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, especiallythosewhosenamestartwithYY_oryy_.Theyare
private implementation details that can be changed or removed. */
/* All symbols defined below should begin with yy or YY, to avoid infringingonusernamespace.Thisshouldbedoneevenforlocal variables,astheymightotherwisebeexpandedbyusermacros. Therearesomeunavoidableexceptionswithinincludefilesto definenecessarylibrarysymbols;theyarenoted"INFRINGESON
USER NAME SPACE" below. */
YoushouldhavereceivedacopyoftheGNUGeneralPublicLicensealongwith
this program. If not, see https://www.gnu.org/licenses/. */
/* This is a simple program, meant only to show one way to use GMP for this sortofthing.There'sfewfeatures,anderrorcheckingisminimal. Standardinputisread,calc_help()belowshowstheinputsaccepted.
Avoidingrepeatedinitializingandclearingof"mpz_t"sisimportant.In thisprogramthetimespentparsingisobviouslymuchgreaterthanany possiblesavingfromthis,butapropercalculatororlanguageshould takesometroubleoverit.Don'tbesurprisedifaninit/cleartakes3 ormoretimesaslongasa10limbaddition,dependingonthesystem(see
the mpz_init_realloc_clear example in tune/README). */
#include <stdio.h> #include <stdlib.h> #include <string.h> #include"gmp.h" #define NO_CALC_H /* because it conflicts with normal calc.c stuff */ #include"calc-common.h"
void
calc_help (void)
{
printf ("Examples:\n");
printf (" 2+3*4 expressions are evaluated\n");
printf (" x=5^6 variables a to z can be set and used\n");
printf ("Operators:\n");
printf (" + - * arithmetic\n");
printf (" / %% division and remainder (rounding towards negative infinity)\n");
printf (" ^ exponentiation\n");
printf (" ! factorial\n");
printf (" << >> left and right shifts\n");
printf (" <= >= > \\ comparisons, giving 1 if true, 0 if false\n");
printf (" == != < /\n");
printf (" && || logical and/or, giving 1 if true, 0 if false\n");
printf ("Functions:\n");
printf (" abs(n) absolute value\n");
printf (" bin(n,m) binomial coefficient\n");
printf (" fib(n) fibonacci number\n");
printf (" gcd(a,b,..) greatest common divisor\n");
printf (" kron(a,b) kronecker symbol\n");
printf (" lcm(a,b,..) least common multiple\n");
printf (" lucnum(n) lucas number\n");
printf (" nextprime(n) next prime after n\n");
printf (" powm(b,e,m) modulo powering, b^e%%m\n");
printf (" root(n,r) r-th root\n");
printf (" sqrt(n) square root\n");
printf ("Other:\n");
printf (" hex \\ set hex or decimal for input and output\n");
printf (" decimal / (\"0x\" can be used for hex too)\n");
printf (" quit exit program (EOF works too)\n");
printf (" ; statements are separated with a ; or newline\n");
printf (" \\ continue expressions with \\ before newline\n");
printf (" # xxx comments are # though to newline\n");
printf ("Hex numbers must be entered in upper case, to distinguish them from the\n");
printf ("variables a to f (like in bc).\n");
}
int ibase = 0; int obase = 10;
/* The stack is a fixed size, which means there's a limit on the nesting allowedinexpressions.Amoresophisticatedprogramcouldletitgrow
dynamically. */
mpz_t stack[100];
mpz_ptr sp = stack[0];
#define CHECK_OVERFLOW() \ if (sp >= stack[numberof(stack)]) /* FIXME */ \
{ \
fprintf (stderr, \ "Value stack overflow, too much nesting in expression\n"); \
YYERROR; \
}
#define CHECK_EMPTY() \ if (sp != stack[0]) \
{ \
fprintf (stderr, "Oops, expected the value stack to be empty\n"); \
sp = stack[0]; \
}
/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure <limits.h>and(ifavailable)<stdint.h>areincluded
so that the code can choose integer types of a good width. */
#ifndef __PTRDIFF_MAX__ # include <limits.h> /* INFRINGES ON USER NAME SPACE */ # ifdefined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include <stdint.h> /* INFRINGES ON USER NAME SPACE */ # define YY_STDINT_H # endif #endif
/* Narrow types that promote to a signed type and that can represent a signedorunsignedintegerofatleastNbits.Intablestheycan savespaceanddecreasecachepressure.Promotingtoasignedtype
helps avoid bugs in integer arithmetic. */
/* The parser invokes alloca or malloc; define the necessary symbols. */
# ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include <alloca.h> /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include <malloc.h> /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # endif # endif # endif
# ifdef YYSTACK_ALLOC /* Pacify GCC's 'empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, andapagesizecanbeassmallas4096bytes.Sowecannotsafely invokealloca(N)ifNexceeds4096.Useaslightlysmallernumber
to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032/* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \
&& ! ((defined YYMALLOC || defined malloc) \
&& (defined YYFREE || defined free))) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined EXIT_SUCCESS void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined EXIT_SUCCESS void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif/* !defined yyoverflow */
#if (! defined yyoverflow \
&& (! defined __cplusplus \
|| (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
/* A type that is properly aligned for any stack member. */ union yyalloc
{
yy_state_t yyss_alloc;
YYSTYPE yyvs_alloc;
};
/* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1)
/* The size of an array large to enough to hold all stacks, each with
N elements. */ # define YYSTACK_BYTES(N) \
((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \
+ YYSTACK_GAP_MAXIMUM)
# define YYCOPY_NEEDED 1
/* Relocate STACK from its old location to the new one. The localvariablesYYSIZEandYYSTACKSIZEgivetheoldandnewnumberof elementsinthestack,andYYPTRgivesthenewlocationofthe stack.AdvanceYYPTRtoaproperlyalignedlocationforthenext
stack. */ # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \
{ \
YYPTRDIFF_T yynewbytes; \
YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
Stack = &yyptr->Stack_alloc; \
yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \
yyptr += yynewbytes / YYSIZEOF (*yyptr); \
} \ while (0)
#endif
#ifdefined YYCOPY_NEEDED && YYCOPY_NEEDED /* Copy COUNT objects from SRC to DST. The source and destination do
not overlap. */ # ifndef YYCOPY # ifdefined __GNUC__ && 1 < __GNUC__ # define YYCOPY(Dst, Src, Count) \
__builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) # else # define YYCOPY(Dst, Src, Count) \ do \
{ \
YYPTRDIFF_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \
(Dst)[yyi] = (Src)[yyi]; \
} \ while (0) # endif # endif #endif/* !YYCOPY_NEEDED */
/* YYFINAL -- State number of the termination state. */ #define YYFINAL 41 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 552
/* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 44 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 7 /* YYNRULES -- Number of rules. */ #define YYNRULES 49 /* YYNSTATES -- Number of states. */ #define YYNSTATES 118
/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
as returned by yylex, with out-of-bounds checking. */ #define YYTRANSLATE(YYX) \
(0 <= (YYX) && (YYX) <= YYMAXUTOK \
? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \
: YYSYMBOL_YYUNDEF)
/** Accessing symbol of state STATE. */ #define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State])
#if YYDEBUG || 0 /* The user-facing name of the symbol whose (internal) number is
YYSYMBOL. No bounds checking. */ staticconstchar *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED;
/* The semantic value of the lookahead symbol. */
YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs;
/*----------. |yyparse.|
`----------*/
int
yyparse (void)
{
yy_state_fast_t yystate = 0; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus = 0;
/* Refer to the stacks through separate pointers, to allow yyoverflow
to reallocate them elsewhere. */
/* Their size. */
YYPTRDIFF_T yystacksize = YYINITDEPTH;
/* The state stack: array, bottom, top. */
yy_state_t yyssa[YYINITDEPTH];
yy_state_t *yyss = yyssa;
yy_state_t *yyssp = yyss;
/* The semantic value stack: array, bottom, top. */
YYSTYPE yyvsa[YYINITDEPTH];
YYSTYPE *yyvs = yyvsa;
YYSTYPE *yyvsp = yyvs;
int yyn; /* The return value of yyparse. */ int yyresult; /* Lookahead symbol kind. */
yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; /* The variables used to return semantic value and location from the
action routines. */
YYSTYPE yyval;
/* The number of symbols on the RHS of the reduced rule.
Keep to zero when no symbol should be popped. */ int yylen = 0;
YYDPRINTF ((stderr, "Starting parse\n"));
yychar = YYEMPTY; /* Cause a token to be read. */
goto yysetstate;
/*------------------------------------------------------------. |yynewstate--pushanewstate,whichisfoundinyystate.|
`------------------------------------------------------------*/
yynewstate: /* In all cases, when you get here, the value and location stacks
have just been pushed. So pushing a state here evens the stacks. */
yyssp++;
if (yyss + yystacksize - 1 <= yyssp) #if !defined yyoverflow && !defined YYSTACK_RELOCATE
YYNOMEM; #else
{ /* Get the current used size of the three stacks, in elements. */
YYPTRDIFF_T yysize = yyssp - yyss + 1;
# ifdefined yyoverflow
{ /* Give user a chance to reallocate the stack. Use copies of thesesothatthe&'sdon'tforcetherealonesinto
memory. */
yy_state_t *yyss1 = yyss;
YYSTYPE *yyvs1 = yyvs;
/* Each stack pointer address is followed by the size of the datainuseinthatstack,inbytes.Thisusedtobea conditionalaroundjustthetwoextraargs,butthatmight
be undefined if yyoverflow is a macro. */
yyoverflow (YY_("memory exhausted"),
&yyss1, yysize * YYSIZEOF (*yyssp),
&yyvs1, yysize * YYSIZEOF (*yyvsp),
&yystacksize);
yyss = yyss1;
yyvs = yyvs1;
} # else/* defined YYSTACK_RELOCATE */ /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize)
YYNOMEM;
yystacksize *= 2; if (YYMAXDEPTH < yystacksize)
yystacksize = YYMAXDEPTH;
/*-----------. |yybackup.|
`-----------*/
yybackup: /* Do appropriate processing given the current state. Read a
lookahead token if we need one and don't already have one. */
/* First try to decide what to do without reference to lookahead token. */
yyn = yypact[yystate]; if (yypact_value_is_default (yyn)) goto yydefault;
/* Not known => get a lookahead token if don't already have one. */
/* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ if (yychar == YYEMPTY)
{
YYDPRINTF ((stderr, "Reading a token\n"));
yychar = yylex ();
}
if (yychar <= YYEOF)
{
yychar = YYEOF;
yytoken = YYSYMBOL_YYEOF;
YYDPRINTF ((stderr, "Now at end of input.\n"));
} elseif (yychar == YYerror)
{ /* The scanner already issued an error message, process directly toerrorrecovery.Butdonotkeeptheerrortokenas lookahead,itistoospecialandmayleadustoanendless
loop in error recovery. */
yychar = YYUNDEF;
yytoken = YYSYMBOL_YYerror; goto yyerrlab1;
} else
{
yytoken = YYTRANSLATE (yychar);
YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
}
/* If the proper action on seeing token YYTOKEN is to reduce or to
detect an error, take that action. */
yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault;
yyn = yytable[yyn]; if (yyn <= 0)
{ if (yytable_value_is_error (yyn)) goto yyerrlab;
yyn = -yyn; goto yyreduce;
}
/* Count tokens shifted since error; after three, turn off error
status. */ if (yyerrstatus)
yyerrstatus--;
/*-----------------------------. |yyreduce--doareduction.|
`-----------------------------*/
yyreduce: /* yyn is the number of a rule to reduce with. */
yylen = yyr2[yyn];
/* If YYLEN is nonzero, implement the default value of the action: '$$=$1'.
Otherwise,thefollowinglinesetsYYVALtogarbage. ThisbehaviorisundocumentedandBison usersshouldnotrelyuponit.AssigningtoYYVAL unconditionallymakestheparserabitsmaller,anditavoidsa
GCC warning that YYVAL may be used uninitialized. */
yyval = yyvsp[1-yylen];
default: break;
} /* User semantic actions sometimes alter yychar, and that requires thatyytokenbeupdatedwiththenewtranslation.Wetakethe approachoftranslatingimmediatelybeforeeveryuseofyytoken. Onealternativeistranslatinghereaftereverysemanticaction, butthattranslationwouldbemissedifthesemanticactioninvokes YYABORT,YYACCEPT,orYYERRORimmediatelyafteralteringyycharor ifitinvokesYYBACKUP.InthecaseofYYABORTorYYACCEPT,an incorrectdestructormightthenbeinvokedimmediately.Inthe caseofYYERRORorYYBACKUP,subsequentparseractionsmightlead toanincorrectdestructorcallorverbosesyntaxerrormessage
before the lookahead is translated. */
YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc);
YYPOPSTACK (yylen);
yylen = 0;
*++yyvsp = yyval;
/* Now 'shift' the result of the reduction. Determine what state thatgoesto,basedonthestatewepoppedbacktoandtherule
number reduced by. */
{ constint yylhs = yyr1[yyn] - YYNTOKENS; constint yyi = yypgoto[yylhs] + *yyssp;
yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
? yytable[yyi]
: yydefgoto[yylhs]);
}
goto yynewstate;
/*--------------------------------------. |yyerrlab--hereondetectingerror.|
`--------------------------------------*/
yyerrlab: /* Make sure we have latest lookahead translation. See comments at
user semantic actions for why this is necessary. */
yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus)
{
++yynerrs;
yyerror (YY_("syntax error"));
}
if (yyerrstatus == 3)
{ /* If just tried and failed to reuse lookahead token after an
error, discard it. */
if (yychar <= YYEOF)
{ /* Return failure if at end of input. */ if (yychar == YYEOF)
YYABORT;
} else
{
yydestruct ("Error: discarding",
yytoken, &yylval);
yychar = YYEMPTY;
}
}
/* Else will try to reuse lookahead token after shifting the error
token. */ goto yyerrlab1;
/*---------------------------------------------------. |yyerrorlab--errorraisedexplicitlybyYYERROR.|
`---------------------------------------------------*/
yyerrorlab: /* Pacify compilers when the user code never invokes YYERROR and the
label yyerrorlab therefore never appears in user code. */ if (0)
YYERROR;
++yynerrs;
/* Do not reclaim the symbols of the rule whose action triggered
this YYERROR. */
YYPOPSTACK (yylen);
yylen = 0;
YY_STACK_PRINT (yyss, yyssp);
yystate = *yyssp; goto yyerrlab1;
/*-------------------------------------------------------------. |yyerrlab1--commoncodeforbothsyntaxerrorandYYERROR.|
`-------------------------------------------------------------*/
yyerrlab1:
yyerrstatus = 3; /* Each real token shifted decrements this. */
/* Pop stack until we find a state that shifts the error token. */ for (;;)
{
yyn = yypact[yystate]; if (!yypact_value_is_default (yyn))
{
yyn += YYSYMBOL_YYerror; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror)
{
yyn = yytable[yyn]; if (0 < yyn) break;
}
}
/* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss)
YYABORT;
/*----------------------------------------------------------. |yyreturnlab--parsingisfinished,cleanupandreturn.|
`----------------------------------------------------------*/
yyreturnlab: if (yychar != YYEMPTY)
{ /* Make sure we have latest lookahead translation. See comments at
user semantic actions for why this is necessary. */
yytoken = YYTRANSLATE (yychar);
yydestruct ("Cleanup: discarding lookahead",
yytoken, &yylval);
} /* Do not reclaim the symbols of the rule whose action triggered
this YYABORT or YYACCEPT. */
YYPOPSTACK (yylen);
YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss)
{
yydestruct ("Cleanup: popping",
YY_ACCESSING_SYMBOL (+*yyssp), yyvsp);
YYPOPSTACK (1);
} #ifndef yyoverflow if (yyss != yyssa)
YYSTACK_FREE (yyss); #endif
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.