📄 label.cc
字号:
/* This function handles 2 tasks:determine which authors are needed (cannot be elided with et al.);determine which authors can have only last names in the labels.References >= start and < end have the same first i author names.Also they're sorted by A+. */static void consider_authors(reference **start, reference **end, int i){ if (start >= end) return; reference **p = start; if (i >= (*p)->get_nauthors()) { for (++p; p < end && i >= (*p)->get_nauthors(); p++) ; if (p < end && i > 0) { // If we have an author list <A B C> and an author list <A B C D>, // then both lists need C. for (reference **q = start; q < end; q++) (*q)->need_author(i - 1); } start = p; } while (p < end) { reference **last_name_start = p; reference **name_start = p; for (++p; p < end && i < (*p)->get_nauthors() && same_author_last_name(**last_name_start, **p, i); p++) { if (!same_author_name(**name_start, **p, i)) { consider_authors(name_start, p, i + 1); name_start = p; } } consider_authors(name_start, p, i + 1); if (last_name_start == name_start) { for (reference **q = last_name_start; q < p; q++) (*q)->set_last_name_unambiguous(i); } // If we have an author list <A B C D> and <A B C E>, then the lists // need author D and E respectively. if (name_start > start || p < end) { for (reference **q = last_name_start; q < p; q++) (*q)->need_author(i); } }}int same_author_last_name(const reference &r1, const reference &r2, int n){ const char *ae1; const char *as1 = r1.get_sort_field(0, n, 0, &ae1); assert(as1 != 0); const char *ae2; const char *as2 = r2.get_sort_field(0, n, 0, &ae2); assert(as2 != 0); return ae1 - as1 == ae2 - as2 && memcmp(as1, as2, ae1 - as1) == 0;}int same_author_name(const reference &r1, const reference &r2, int n){ const char *ae1; const char *as1 = r1.get_sort_field(0, n, -1, &ae1); assert(as1 != 0); const char *ae2; const char *as2 = r2.get_sort_field(0, n, -1, &ae2); assert(as2 != 0); return ae1 - as1 == ae2 - as2 && memcmp(as1, as2, ae1 - as1) == 0;}void int_set::set(int i){ assert(i >= 0); int bytei = i >> 3; if (bytei >= v.length()) { int old_length = v.length(); v.set_length(bytei + 1); for (int j = old_length; j <= bytei; j++) v[j] = 0; } v[bytei] |= 1 << (i & 7);}int int_set::get(int i) const{ assert(i >= 0); int bytei = i >> 3; return bytei >= v.length() ? 0 : (v[bytei] & (1 << (i & 7))) != 0;}void reference::set_last_name_unambiguous(int i){ last_name_unambiguous.set(i);}void reference::need_author(int n){ if (n > last_needed_author) last_needed_author = n;}const char *reference::get_authors(const char **end) const{ if (!computed_authors) { ((reference *)this)->computed_authors = 1; string &result = ((reference *)this)->authors; int na = get_nauthors(); result.clear(); for (int i = 0; i < na; i++) { if (last_name_unambiguous.get(i)) { const char *e, *start = get_author_last_name(i, &e); assert(start != 0); result.append(start, e - start); } else { const char *e, *start = get_author(i, &e); assert(start != 0); result.append(start, e - start); } if (i == last_needed_author && et_al.length() > 0 && et_al_min_elide > 0 && last_needed_author + et_al_min_elide < na && na >= et_al_min_total) { result += et_al; break; } if (i < na - 1) { if (na == 2) result += join_authors_exactly_two; else if (i < na - 2) result += join_authors_default; else result += join_authors_last_two; } } } const char *start = authors.contents(); *end = start + authors.length(); return start;}int reference::get_nauthors() const{ if (nauthors < 0) { const char *dummy; for (int na = 0; get_author(na, &dummy) != 0; na++) ; ((reference *)this)->nauthors = na; } return nauthors;}#line 1220 "y.tab.c"#define YYABORT goto yyabort#define YYACCEPT goto yyaccept#define YYERROR goto yyerrlabintyyparse(){ register int yym, yyn, yystate;#if YYDEBUG register char *yys; extern char *getenv(); if (yys = getenv("YYDEBUG")) { yyn = *yys; if (yyn >= '0' && yyn <= '9') yydebug = yyn - '0'; }#endif yynerrs = 0; yyerrflag = 0; yychar = (-1); yyssp = yyss; yyvsp = yyvs; *yyssp = yystate = 0;yyloop: if (yyn = yydefred[yystate]) goto yyreduce; if (yychar < 0) { if ((yychar = yylex()) < 0) yychar = 0;#if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("yydebug: state %d, reading %d (%s)\n", yystate, yychar, yys); }#endif } if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yychar) {#if YYDEBUG if (yydebug) printf("yydebug: state %d, shifting to state %d\n", yystate, yytable[yyn]);#endif if (yyssp >= yyss + yystacksize - 1) { goto yyoverflow; } *++yyssp = yystate = yytable[yyn]; *++yyvsp = yylval; yychar = (-1); if (yyerrflag > 0) --yyerrflag; goto yyloop; } if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yychar) { yyn = yytable[yyn]; goto yyreduce; } if (yyerrflag) goto yyinrecovery;#ifdef lint goto yynewerror;#endifyynewerror: yyerror("syntax error");#ifdef lint goto yyerrlab;#endifyyerrlab: ++yynerrs;yyinrecovery: if (yyerrflag < 3) { yyerrflag = 3; for (;;) { if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) {#if YYDEBUG if (yydebug) printf("yydebug: state %d, error recovery shifting\ to state %d\n", *yyssp, yytable[yyn]);#endif if (yyssp >= yyss + yystacksize - 1) { goto yyoverflow; } *++yyssp = yystate = yytable[yyn]; *++yyvsp = yylval; goto yyloop; } else {#if YYDEBUG if (yydebug) printf("yydebug: error recovery discarding state %d\n", *yyssp);#endif if (yyssp <= yyss) goto yyabort; --yyssp; --yyvsp; } } } else { if (yychar == 0) goto yyabort;#if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("yydebug: state %d, error recovery discards token %d (%s)\n", yystate, yychar, yys); }#endif yychar = (-1); goto yyloop; }yyreduce:#if YYDEBUG if (yydebug) printf("yydebug: state %d, reducing by rule %d (%s)\n", yystate, yyn, yyrule[yyn]);#endif yym = yylen[yyn]; yyval = yyvsp[1-yym]; switch (yyn) {case 1:#line 250 "label.y"{ parse_result = (yyvsp[0].expr ? new analyzed_expr(yyvsp[0].expr) : 0); }break;case 2:#line 255 "label.y"{ yyval.expr = yyvsp[0].expr; }break;case 3:#line 257 "label.y"{ yyval.expr = new conditional_expr(yyvsp[-4].expr, yyvsp[-2].expr, yyvsp[0].expr); }break;case 4:#line 262 "label.y"{ yyval.expr = 0; }break;case 5:#line 264 "label.y"{ yyval.expr = yyvsp[0].expr; }break;case 6:#line 269 "label.y"{ yyval.expr = yyvsp[0].expr; }break;case 7:#line 271 "label.y"{ yyval.expr = new alternative_expr(yyvsp[-2].expr, yyvsp[0].expr); }break;case 8:#line 273 "label.y"{ yyval.expr = new conditional_expr(yyvsp[-2].expr, yyvsp[0].expr, 0); }break;case 9:#line 278 "label.y"{ yyval.expr = yyvsp[0].expr; }break;case 10:#line 280 "label.y"{ yyval.expr = new list_expr(yyvsp[-1].expr, yyvsp[0].expr); }break;case 11:#line 285 "label.y"{ yyval.expr = yyvsp[0].expr; }break;case 12:#line 287 "label.y"{ yyval.expr = new substitute_expr(yyvsp[-2].expr, yyvsp[0].expr); }break;case 13:#line 292 "label.y"{ yyval.expr = new at_expr; }break;case 14:#line 294 "label.y"{ yyval.expr = new literal_expr(literals.contents() + yyvsp[0].str.start, yyvsp[0].str.len); }break;case 15:#line 299 "label.y"{ yyval.expr = new field_expr(yyvsp[0].num, 0); }break;case 16:#line 301 "label.y"{ yyval.expr = new field_expr(yyvsp[-1].num, yyvsp[0].num - 1); }break;case 17:#line 303 "label.y"{ switch (yyvsp[0].num) { case 'I': case 'i': case 'A': case 'a': yyval.expr = new format_expr(yyvsp[0].num); break; default: command_error("unrecognized format `%1'", char(yyvsp[0].num)); yyval.expr = new format_expr('a'); break; } }break;case 18:#line 319 "label.y"{ yyval.expr = new format_expr('0', yyvsp[0].dig.ndigits, yyvsp[0].dig.val); }break;case 19:#line 323 "label.y"{ switch (yyvsp[-1].num) { case 'l': yyval.expr = new map_expr(yyvsp[-4].expr, lowercase); break; case 'u': yyval.expr = new map_expr(yyvsp[-4].expr, uppercase); break; case 'c': yyval.expr = new map_expr(yyvsp[-4].expr, capitalize); break; case 'r': yyval.expr = new map_expr(yyvsp[-4].expr, reverse_name); break; case 'a': yyval.expr = new map_expr(yyvsp[-4].expr, abbreviate_name); break; case 'y': yyval.expr = new extractor_expr(yyvsp[-4].expr, find_year, yyvsp[-2].num); break; case 'n': yyval.expr = new extractor_expr(yyvsp[-4].expr, find_last_name, yyvsp[-2].num); break; default: yyval.expr = yyvsp[-4].expr; command_error("unknown function `%1'", char(yyvsp[-1].num)); break; } }break;case 20:#line 354 "label.y"{ yyval.expr = new truncate_expr(yyvsp[-2].expr, yyvsp[0].num); }break;case 21:#line 356 "label.y"{ yyval.expr = new truncate_expr(yyvsp[-2].expr, -yyvsp[0].num); }break;case 22:#line 358 "label.y"{ yyval.expr = new star_expr(yyvsp[-1].expr); }break;case 23:#line 360 "label.y"{ yyval.expr = yyvsp[-1].expr; }break;case 24:#line 362 "label.y"{ yyval.expr = new separator_expr(yyvsp[-1].expr); }break;case 25:#line 367 "label.y"{ yyval.num = -1; }break;case 26:#line 369 "label.y"{ yyval.num = yyvsp[0].num; }break;case 27:#line 374 "label.y"{ yyval.num = yyvsp[0].num; }break;case 28:#line 376 "label.y"{ yyval.num = yyvsp[-1].num*10 + yyvsp[0].num; }break;case 29:#line 381 "label.y"{ yyval.dig.ndigits = 1; yyval.dig.val = yyvsp[0].num; }break;case 30:#line 383 "label.y"{ yyval.dig.ndigits = yyvsp[-1].dig.ndigits + 1; yyval.dig.val = yyvsp[-1].dig.val*10 + yyvsp[0].num; }break;case 31:#line 389 "label.y"{ yyval.num = 0; }break;case 32:#line 391 "label.y"{ yyval.num = 1; }break;case 33:#line 393 "label.y"{ yyval.num = -1; }break;#line 1538 "y.tab.c" } yyssp -= yym; yystate = *yyssp; yyvsp -= yym; yym = yylhs[yyn]; if (yystate == 0 && yym == 0) {#if YYDEBUG if (yydebug) printf("yydebug: after reduction, shifting from state 0 to\ state %d\n", YYFINAL);#endif yystate = YYFINAL; *++yyssp = YYFINAL; *++yyvsp = yyval; if (yychar < 0) { if ((yychar = yylex()) < 0) yychar = 0;#if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("yydebug: state %d, reading %d (%s)\n", YYFINAL, yychar, yys); }#endif } if (yychar == 0) goto yyaccept; goto yyloop; } if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yystate) yystate = yytable[yyn]; else yystate = yydgoto[yym];#if YYDEBUG if (yydebug) printf("yydebug: after reduction, shifting from state %d \to state %d\n", *yyssp, yystate);#endif if (yyssp >= yyss + yystacksize - 1) { goto yyoverflow; } *++yyssp = yystate; *++yyvsp = yyval; goto yyloop;yyoverflow: yyerror("yacc stack overflow");yyabort: return (1);yyaccept: return (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -