diff --git a/InProgress/StackGraphs_to_CFL_Reachability/IEEE.bst b/InProgress/StackGraphs_to_CFL_Reachability/IEEE.bst new file mode 100644 index 00000000..e7324041 --- /dev/null +++ b/InProgress/StackGraphs_to_CFL_Reachability/IEEE.bst @@ -0,0 +1,3608 @@ +%% +%% IEEEtran.bst +%% BibTeX Bibliography Style file for IEEE Journals and Conferences (unsorted) +%% Version 1.14 (2015/08/26) +%% +%% Copyright (c) 2003-2015 Michael Shell +%% +%% +%% Original starting code base and algorithms obtained from the output of +%% Patrick W. Daly's makebst package as well as from prior versions of +%% IEEE BibTeX styles: +%% +%% 1. Howard Trickey and Oren Patashnik's ieeetr.bst (1985/1988) +%% 2. Silvano Balemi and Richard H. Roy's IEEEbib.bst (1993) +%% +%% Support sites: +%% http://www.michaelshell.org/tex/ieeetran/ +%% http://www.ctan.org/pkg/ieeetran +%% and/or +%% http://www.ieee.org/ +%% +%% For use with BibTeX version 0.99a or later +%% +%% This is a numerical citation style. +%% +%%************************************************************************* +%% Legal Notice: +%% This code is offered as-is without any warranty either expressed or +%% implied; without even the implied warranty of MERCHANTABILITY or +%% FITNESS FOR A PARTICULAR PURPOSE! +%% User assumes all risk. +%% In no event shall the IEEE or any contributor to this code be liable for +%% any damages or losses, including, but not limited to, incidental, +%% consequential, or any other damages, resulting from the use or misuse +%% of any information contained here. +%% +%% All comments are the opinions of their respective authors and are not +%% necessarily endorsed by the IEEE. +%% +%% This work is distributed under the LaTeX Project Public License (LPPL) +%% ( http://www.latex-project.org/ ) version 1.3, and may be freely used, +%% distributed and modified. A copy of the LPPL, version 1.3, is included +%% in the base LaTeX documentation of all distributions of LaTeX released +%% 2003/12/01 or later. +%% Retain all contribution notices and credits. +%% ** Modified files should be clearly indicated as such, including ** +%% ** renaming them and changing author support contact information. ** +%%************************************************************************* + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% DEFAULTS FOR THE CONTROLS OF THE BST STYLE %% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% These are the defaults for the user adjustable controls. The values used +% here can be overridden by the user via IEEEtranBSTCTL entry type. + +% NOTE: The recommended LaTeX command to invoke a control entry type is: +% +%\makeatletter +%\def\bstctlcite{\@ifnextchar[{\@bstctlcite}{\@bstctlcite[@auxout]}} +%\def\@bstctlcite[#1]#2{\@bsphack +% \@for\@citeb:=#2\do{% +% \edef\@citeb{\expandafter\@firstofone\@citeb}% +% \if@filesw\immediate\write\csname #1\endcsname{\string\citation{\@citeb}}\fi}% +% \@esphack} +%\makeatother +% +% It is called at the start of the document, before the first \cite, like: +% \bstctlcite{IEEEexample:BSTcontrol} +% +% IEEEtran.cls V1.6 and later does provide this command. + + + +% #0 turns off the display of the number for articles. +% #1 enables +FUNCTION {default.is.use.number.for.article} { #1 } + + +% #0 turns off the display of the paper and type fields in @inproceedings. +% #1 enables +FUNCTION {default.is.use.paper} { #1 } + + +% #0 turns off the display of urls +% #1 enables +FUNCTION {default.is.use.url} { #1 } + + +% #0 turns off the forced use of "et al." +% #1 enables +% When there are more than 6 authors, force et al. usage. +FUNCTION {default.is.forced.et.al} { #1 } + + +% The maximum number of names that can be present beyond which an "et al." +% usage is forced. Be sure that num.names.shown.with.forced.et.al (below) +% is not greater than this value! +% List up to 6 authors; if more, use the primary author + et al. +FUNCTION {default.max.num.names.before.forced.et.al} { #6 } + + +% The number of names that will be shown with a forced "et al.". +% Must be less than or equal to max.num.names.before.forced.et.al +% Show only the first author followed by "et al." +FUNCTION {default.num.names.shown.with.forced.et.al} { #1 } + + +% The maximum number of editor names that can appear before "et al." is forced. +% IEEE style allows up to 3 editors; if more, the first editor + et al. is used. +FUNCTION {default.max.num.editors.before.forced.et.al} { #3 } + + +% #0 turns off the alternate interword spacing for entries with URLs. +% #1 enables +% Disabled by default: the legacy x4 inter-word stretch produced visibly +% loose lines in entries that carry long URLs (blog/news/social-media +% references in particular). Long URLs are still broken safely by the +% \url{} command from the url/hyperref package. +FUNCTION {default.is.use.alt.interword.spacing} { #0 } + + +% If alternate interword spacing for entries with URLs is enabled, this is +% the interword spacing stretch factor that will be used. For example, the +% default "4" here means that the interword spacing in entries with URLs can +% stretch to four times normal. Does not have to be an integer. Note that +% the value specified here can be overridden by the user in their LaTeX +% code via a command such as: +% "\providecommand\BIBentryALTinterwordstretchfactor{1.5}" in addition to +% that via the IEEEtranBSTCTL entry type. +FUNCTION {default.ALTinterwordstretchfactor} { "1.5" } + + +% #0 turns off the "dashification" of repeated (i.e., identical to those +% of the previous entry) names. The IEEE normally does this. +% #1 enables +FUNCTION {default.is.dash.repeated.names} { #0 } + + +% The default name format control string. +FUNCTION {default.name.format.string}{ "{f.~}{vv~}{ll}{, jj}" } + + +% The default LaTeX font command for the names. +FUNCTION {default.name.latex.cmd}{ "" } + + +% The default URL prefix. +% NOTE: The leading "[Online]." (or "[Online Video].", etc.) is emitted by +% the format.online.marker function so that the medium can vary per entry +% type (videos, datasets, etc.). The prefix here therefore contains only +% the "Available:" portion that follows the medium marker. +FUNCTION {default.name.url.prefix}{ "Available:" } + + +% Other controls that cannot be accessed via IEEEtranBSTCTL entry type. + +% #0 turns off the terminal startup banner/completed message so as to +% operate more quietly. +% #1 enables +FUNCTION {is.print.banners.to.terminal} { #1 } + + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% FILE VERSION AND BANNER %% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +FUNCTION{bst.file.version} { "1.14" } +FUNCTION{bst.file.date} { "2015/08/26" } +FUNCTION{bst.file.website} { "http://www.michaelshell.org/tex/ieeetran/bibtex/" } + +FUNCTION {banner.message} +{ is.print.banners.to.terminal + { "-- IEEEtran.bst version" " " * bst.file.version * + " (" * bst.file.date * ") " * "by Michael Shell." * + top$ + "-- " bst.file.website * + top$ + "-- See the " quote$ * "IEEEtran_bst_HOWTO.pdf" * quote$ * " manual for usage information." * + top$ + } + { skip$ } + if$ +} + +FUNCTION {completed.message} +{ is.print.banners.to.terminal + { "" + top$ + "Done." + top$ + } + { skip$ } + if$ +} + + + + +%%%%%%%%%%%%%%%%%%%%%% +%% STRING CONSTANTS %% +%%%%%%%%%%%%%%%%%%%%%% + +FUNCTION {bbl.and}{ "and" } +FUNCTION {bbl.etal}{ "et~al." } +FUNCTION {bbl.editors}{ "Eds." } +FUNCTION {bbl.editor}{ "Ed." } +FUNCTION {bbl.edition}{ "ed." } +FUNCTION {bbl.volume}{ "vol." } +FUNCTION {bbl.of}{ "of" } +FUNCTION {bbl.number}{ "no." } +FUNCTION {bbl.in}{ "in" } +FUNCTION {bbl.pages}{ "pp." } +FUNCTION {bbl.page}{ "p." } +FUNCTION {bbl.chapter}{ "ch." } +FUNCTION {bbl.paper}{ "paper" } +FUNCTION {bbl.part}{ "pt." } +FUNCTION {bbl.patent}{ "Patent" } +FUNCTION {bbl.patentUS}{ "U.S." } +FUNCTION {bbl.revision}{ "Rev." } +FUNCTION {bbl.series}{ "ser." } +FUNCTION {bbl.standard}{ "Standard" } +FUNCTION {bbl.techrep}{ "Tech. Rep." } +FUNCTION {bbl.mthesis}{ "M.S. thesis" } +FUNCTION {bbl.phdthesis}{ "Ph.D. dissertation" } +FUNCTION {bbl.translator}{ "trans." } +FUNCTION {bbl.accessed}{ "Accessed:" } +FUNCTION {bbl.online}{ "[Online]." } +FUNCTION {bbl.onlinevideo}{ "[Online Video]." } +FUNCTION {bbl.available}{ "Available:" } +FUNCTION {bbl.article.no}{ "Art. no." } +FUNCTION {bbl.presented}{ "presented at" } +FUNCTION {bbl.arxiv}{ "arXiv:" } +FUNCTION {bbl.section}{ "sect." } +FUNCTION {bbl.st}{ "st" } +FUNCTION {bbl.nd}{ "nd" } +FUNCTION {bbl.rd}{ "rd" } +FUNCTION {bbl.th}{ "th" } + + +% This is the LaTeX spacer that is used when a larger than normal space +% is called for (such as just before the address:publisher). +FUNCTION {large.space} { "\hskip 1em plus 0.5em minus 0.4em\relax " } + +% The LaTeX code for dashes that are used to represent repeated names. +% Note: Some older IEEE journals used something like +% "\rule{0.275in}{0.5pt}\," which is fairly thick and runs right along +% the baseline. However, the IEEE now uses a thinner, above baseline, +% six dash long sequence. +FUNCTION {repeated.name.dashes} { "------" } + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% PREDEFINED STRING MACROS %% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +MACRO {jan} {"Jan."} +MACRO {feb} {"Feb."} +MACRO {mar} {"Mar."} +MACRO {apr} {"Apr."} +MACRO {may} {"May"} +MACRO {jun} {"Jun."} +MACRO {jul} {"Jul."} +MACRO {aug} {"Aug."} +MACRO {sep} {"Sep."} +MACRO {oct} {"Oct."} +MACRO {nov} {"Nov."} +MACRO {dec} {"Dec."} + + + +%%%%%%%%%%%%%%%%%% +%% ENTRY FIELDS %% +%%%%%%%%%%%%%%%%%% + +ENTRY + { address + assignee + author + articleno + booktitle + chapter + day + dayfiled + edition + editor + eprint + eprinttype + howpublished + inlanguage + institution + intype + journal + key + language + medium + month + monthfiled + nationality + note + number + organization + pages + paper + publisher + repository + school + section + series + revision + title + titleraw + translator + type + url + urldate + doi + version + volume + year + yearfiled + CTLuse_article_number + CTLuse_paper + CTLuse_url + CTLuse_forced_etal + CTLmax_names_forced_etal + CTLnames_show_etal + CTLuse_alt_spacing + CTLalt_stretch_factor + CTLdash_repeated_names + CTLname_format_string + CTLname_latex_cmd + CTLname_url_prefix + } + {} + { label } + + + + +%%%%%%%%%%%%%%%%%%%%%%% +%% INTEGER VARIABLES %% +%%%%%%%%%%%%%%%%%%%%%%% + +INTEGERS { prev.status.punct this.status.punct punct.std + punct.no punct.comma punct.period + prev.status.space this.status.space space.std + space.no space.normal space.large + prev.status.quote this.status.quote quote.std + quote.no quote.close + prev.status.nline this.status.nline nline.std + nline.no nline.newblock + status.cap cap.std + cap.no cap.yes} + +INTEGERS { longest.label.width multiresult nameptr namesleft number.label numnames } + +INTEGERS { is.use.number.for.article + is.use.paper + is.use.url + is.forced.et.al + max.num.names.before.forced.et.al + max.num.editors.before.forced.et.al + num.names.shown.with.forced.et.al + is.use.alt.interword.spacing + is.dash.repeated.names} + + +%%%%%%%%%%%%%%%%%%%%%% +%% STRING VARIABLES %% +%%%%%%%%%%%%%%%%%%%%%% + +STRINGS { bibinfo + longest.label + oldname + s + t + ALTinterwordstretchfactor + name.format.string + name.latex.cmd + name.url.prefix} + +% String / integer scratch space for parsing the urldate field into +% (year, month-numeric, day) components. See parse.urldate below. +STRINGS { ud.y ud.m ud.d ud.tmp ud.parsed } +INTEGERS { ud.idx ud.len ud.space.pos } + + + + +%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOW LEVEL FUNCTIONS %% +%%%%%%%%%%%%%%%%%%%%%%%%% + +FUNCTION {initialize.controls} +{ default.is.use.number.for.article 'is.use.number.for.article := + default.is.use.paper 'is.use.paper := + default.is.use.url 'is.use.url := + default.is.forced.et.al 'is.forced.et.al := + default.max.num.names.before.forced.et.al 'max.num.names.before.forced.et.al := + default.max.num.editors.before.forced.et.al 'max.num.editors.before.forced.et.al := + default.num.names.shown.with.forced.et.al 'num.names.shown.with.forced.et.al := + default.is.use.alt.interword.spacing 'is.use.alt.interword.spacing := + default.is.dash.repeated.names 'is.dash.repeated.names := + default.ALTinterwordstretchfactor 'ALTinterwordstretchfactor := + default.name.format.string 'name.format.string := + default.name.latex.cmd 'name.latex.cmd := + default.name.url.prefix 'name.url.prefix := +} + + +% This IEEEtran.bst features a very powerful and flexible mechanism for +% controlling the capitalization, punctuation, spacing, quotation, and +% newlines of the formatted entry fields. (Note: IEEEtran.bst does not need +% or use the newline/newblock feature, but it has been implemented for +% possible future use.) The output states of IEEEtran.bst consist of +% multiple independent attributes and, as such, can be thought of as being +% vectors, rather than the simple scalar values ("before.all", +% "mid.sentence", etc.) used in most other .bst files. +% +% The more flexible and complex design used here was motivated in part by +% the IEEE's rather unusual bibliography style. For example, the IEEE ends the +% previous field item with a period and large space prior to the publisher +% address; the @electronic entry types use periods as inter-item punctuation +% rather than the commas used by the other entry types; and URLs are never +% followed by periods even though they are the last item in the entry. +% Although it is possible to accommodate these features with the conventional +% output state system, the seemingly endless exceptions make for convoluted, +% unreliable and difficult to maintain code. +% +% IEEEtran.bst's output state system can be easily understood via a simple +% illustration of two most recently formatted entry fields (on the stack): +% +% CURRENT_ITEM +% "PREVIOUS_ITEM" +% +% which, in this example, is to eventually appear in the bibliography as: +% +% "PREVIOUS_ITEM," CURRENT_ITEM +% +% It is the job of the output routine to take the previous item off of the +% stack (while leaving the current item at the top of the stack), apply its +% trailing punctuation (including closing quote marks) and spacing, and then +% to write the result to BibTeX's output buffer: +% +% "PREVIOUS_ITEM," +% +% Punctuation (and spacing) between items is often determined by both of the +% items rather than just the first one. The presence of quotation marks +% further complicates the situation because, in standard English, trailing +% punctuation marks are supposed to be contained within the quotes. +% +% IEEEtran.bst maintains two output state (aka "status") vectors which +% correspond to the previous and current (aka "this") items. Each vector +% consists of several independent attributes which track punctuation, +% spacing, quotation, and newlines. Capitalization status is handled by a +% separate scalar because the format routines, not the output routine, +% handle capitalization and, therefore, there is no need to maintain the +% capitalization attribute for both the "previous" and "this" items. +% +% When a format routine adds a new item, it copies the current output status +% vector to the previous output status vector and (usually) resets the +% current (this) output status vector to a "standard status" vector. Using a +% "standard status" vector in this way allows us to redefine what we mean by +% "standard status" at the start of each entry handler and reuse the same +% format routines under the various inter-item separation schemes. For +% example, the standard status vector for the @book entry type may use +% commas for item separators, while the @electronic type may use periods, +% yet both entry handlers exploit many of the exact same format routines. +% +% Because format routines have write access to the output status vector of +% the previous item, they can override the punctuation choices of the +% previous format routine! Therefore, it becomes trivial to implement rules +% such as "Always use a period and a large space before the publisher." By +% pushing the generation of the closing quote mark to the output routine, we +% avoid all the problems caused by having to close a quote before having all +% the information required to determine what the punctuation should be. +% +% The IEEEtran.bst output state system can easily be expanded if needed. +% For instance, it is easy to add a "space.tie" attribute value if the +% bibliography rules mandate that two items have to be joined with an +% unbreakable space. + +FUNCTION {initialize.status.constants} +{ #0 'punct.no := + #1 'punct.comma := + #2 'punct.period := + #0 'space.no := + #1 'space.normal := + #2 'space.large := + #0 'quote.no := + #1 'quote.close := + #0 'cap.no := + #1 'cap.yes := + #0 'nline.no := + #1 'nline.newblock := +} + +FUNCTION {std.status.using.comma} +{ punct.comma 'punct.std := + space.normal 'space.std := + quote.no 'quote.std := + nline.no 'nline.std := + cap.no 'cap.std := +} + +FUNCTION {std.status.using.period} +{ punct.period 'punct.std := + space.normal 'space.std := + quote.no 'quote.std := + nline.no 'nline.std := + cap.yes 'cap.std := +} + +FUNCTION {initialize.prev.this.status} +{ punct.no 'prev.status.punct := + space.no 'prev.status.space := + quote.no 'prev.status.quote := + nline.no 'prev.status.nline := + punct.no 'this.status.punct := + space.no 'this.status.space := + quote.no 'this.status.quote := + nline.no 'this.status.nline := + cap.yes 'status.cap := +} + +FUNCTION {this.status.std} +{ punct.std 'this.status.punct := + space.std 'this.status.space := + quote.std 'this.status.quote := + nline.std 'this.status.nline := +} + +FUNCTION {cap.status.std}{ cap.std 'status.cap := } + +FUNCTION {this.to.prev.status} +{ this.status.punct 'prev.status.punct := + this.status.space 'prev.status.space := + this.status.quote 'prev.status.quote := + this.status.nline 'prev.status.nline := +} + + +FUNCTION {not} +{ { #0 } + { #1 } + if$ +} + +FUNCTION {and} +{ { skip$ } + { pop$ #0 } + if$ +} + +FUNCTION {or} +{ { pop$ #1 } + { skip$ } + if$ +} + + +% convert the strings "yes" or "no" to #1 or #0 respectively +FUNCTION {yes.no.to.int} +{ "l" change.case$ duplicate$ + "yes" = + { pop$ #1 } + { duplicate$ "no" = + { pop$ #0 } + { "unknown boolean " quote$ * swap$ * quote$ * + " in " * cite$ * warning$ + #0 + } + if$ + } + if$ +} + + +% pushes true if the single char string on the stack is in the +% range of "0" to "9" +FUNCTION {is.num} +{ chr.to.int$ + duplicate$ "0" chr.to.int$ < not + swap$ "9" chr.to.int$ > not and +} + +% multiplies the integer on the stack by a factor of 10 +FUNCTION {bump.int.mag} +{ #0 'multiresult := + { duplicate$ #0 > } + { #1 - + multiresult #10 + + 'multiresult := + } + while$ +pop$ +multiresult +} + +% converts a single character string on the stack to an integer +FUNCTION {char.to.integer} +{ duplicate$ + is.num + { chr.to.int$ "0" chr.to.int$ - } + {"noninteger character " quote$ * swap$ * quote$ * + " in integer field of " * cite$ * warning$ + #0 + } + if$ +} + +% converts a string on the stack to an integer +FUNCTION {string.to.integer} +{ duplicate$ text.length$ 'namesleft := + #1 'nameptr := + #0 'numnames := + { nameptr namesleft > not } + { duplicate$ nameptr #1 substring$ + char.to.integer numnames bump.int.mag + + 'numnames := + nameptr #1 + + 'nameptr := + } + while$ +pop$ +numnames +} + + + + +% The output routines write out the *next* to the top (previous) item on the +% stack, adding punctuation and such as needed. Since IEEEtran.bst maintains +% the output status for the top two items on the stack, these output +% routines have to consider the previous output status (which corresponds to +% the item that is being output). Full independent control of punctuation, +% closing quote marks, spacing, and newblock is provided. +% +% "output.nonnull" does not check for the presence of a previous empty +% item. +% +% "output" does check for the presence of a previous empty item and will +% remove an empty item rather than outputing it. +% +% "output.warn" is like "output", but will issue a warning if it detects +% an empty item. + +FUNCTION {output.nonnull} +{ swap$ + prev.status.punct punct.comma = + { "," * } + { skip$ } + if$ + prev.status.punct punct.period = + { add.period$ } + { skip$ } + if$ + prev.status.quote quote.close = + { "''" * } + { skip$ } + if$ + prev.status.space space.normal = + { " " * } + { skip$ } + if$ + prev.status.space space.large = + { large.space * } + { skip$ } + if$ + write$ + prev.status.nline nline.newblock = + { newline$ "\newblock " write$ } + { skip$ } + if$ +} + +FUNCTION {output} +{ duplicate$ empty$ + 'pop$ + 'output.nonnull + if$ +} + +FUNCTION {output.warn} +{ 't := + duplicate$ empty$ + { pop$ "empty " t * " in " * cite$ * warning$ } + 'output.nonnull + if$ +} + +% "fin.entry" is the output routine that handles the last item of the entry +% (which will be on the top of the stack when "fin.entry" is called). + +FUNCTION {fin.entry} +{ this.status.punct punct.no = + { skip$ } + { add.period$ } + if$ + this.status.quote quote.close = + { "''" * } + { skip$ } + if$ +write$ +newline$ +} + + +FUNCTION {is.last.char.not.punct} +{ duplicate$ + "}" * add.period$ + #-1 #1 substring$ "." = +} + +FUNCTION {is.multiple.pages} +{ 't := + #0 'multiresult := + { multiresult not + t empty$ not + and + } + { t #1 #1 substring$ + duplicate$ "-" = + swap$ duplicate$ "," = + swap$ "+" = + or or + { #1 'multiresult := } + { t #2 global.max$ substring$ 't := } + if$ + } + while$ + multiresult +} + +FUNCTION {capitalize}{ "u" change.case$ "t" change.case$ } + +FUNCTION {emphasize} +{ duplicate$ empty$ + { pop$ "" } + { "\emph{" swap$ * "}" * } + if$ +} + +FUNCTION {do.name.latex.cmd} +{ name.latex.cmd + empty$ + { skip$ } + { name.latex.cmd "{" * swap$ * "}" * } + if$ +} + +% IEEEtran.bst uses its own \BIBforeignlanguage command which directly +% invokes the TeX hyphenation patterns without the need of the Babel +% package. Babel does a lot more than switch hyphenation patterns and +% its loading can cause unintended effects in many class files (such as +% IEEEtran.cls). +FUNCTION {select.language} +{ duplicate$ empty$ 'pop$ + { language empty$ 'skip$ + { "\BIBforeignlanguage{" language * "}{" * swap$ * "}" * } + if$ + } + if$ +} + +FUNCTION {tie.or.space.prefix} +{ duplicate$ text.length$ #3 < + { "~" } + { " " } + if$ + swap$ +} + +FUNCTION {get.bbl.editor} +{ editor num.names$ #1 > 'bbl.editors 'bbl.editor if$ } + +FUNCTION {space.word}{ " " swap$ * " " * } + + +% Field Conditioners, Converters, Checkers and External Interfaces + +FUNCTION {empty.field.to.null.string} +{ duplicate$ empty$ + { pop$ "" } + { skip$ } + if$ +} + +FUNCTION {either.or.check} +{ empty$ + { pop$ } + { "can't use both " swap$ * " fields in " * cite$ * warning$ } + if$ +} + +FUNCTION {empty.entry.warn} +{ author empty$ title empty$ howpublished empty$ + month empty$ year empty$ note empty$ url empty$ + and and and and and and + { "all relevant fields are empty in " cite$ * warning$ } + 'skip$ + if$ +} + + +% The bibinfo system provides a way for the electronic parsing/acquisition +% of a bibliography's contents as is done by ReVTeX. For example, a field +% could be entered into the bibliography as: +% \bibinfo{volume}{2} +% Only the "2" would show up in the document, but the LaTeX \bibinfo command +% could do additional things with the information. IEEEtran.bst does provide +% a \bibinfo command via "\providecommand{\bibinfo}[2]{#2}". However, it is +% currently not used as the bogus bibinfo functions defined here output the +% entry values directly without the \bibinfo wrapper. The bibinfo functions +% themselves (and the calls to them) are retained for possible future use. +% +% bibinfo.check avoids acting on missing fields while bibinfo.warn will +% issue a warning message if a missing field is detected. Prior to calling +% the bibinfo functions, the user should push the field value and then its +% name string, in that order. + +FUNCTION {bibinfo.check} +{ swap$ duplicate$ missing$ + { pop$ pop$ "" } + { duplicate$ empty$ + { swap$ pop$ } + { swap$ pop$ } + if$ + } + if$ +} + +FUNCTION {bibinfo.warn} +{ swap$ duplicate$ missing$ + { swap$ "missing " swap$ * " in " * cite$ * warning$ pop$ "" } + { duplicate$ empty$ + { swap$ "empty " swap$ * " in " * cite$ * warning$ } + { swap$ pop$ } + if$ + } + if$ +} + + +% The IEEE separates large numbers with more than 4 digits into groups of +% three. The IEEE uses a small space to separate these number groups. +% Typical applications include patent and page numbers. + +% number of consecutive digits required to trigger the group separation. +FUNCTION {large.number.trigger}{ #5 } + +% For numbers longer than the trigger, this is the blocksize of the groups. +% The blocksize must be less than the trigger threshold, and 2 * blocksize +% must be greater than the trigger threshold (can't do more than one +% separation on the initial trigger). +FUNCTION {large.number.blocksize}{ #3 } + +% What is actually inserted between the number groups. +FUNCTION {large.number.separator}{ "\," } + +% So as to save on integer variables by reusing existing ones, numnames +% holds the current number of consecutive digits read and nameptr holds +% the number that will trigger an inserted space. +FUNCTION {large.number.separate} +{ 't := + "" + #0 'numnames := + large.number.trigger 'nameptr := + { t empty$ not } + { t #-1 #1 substring$ is.num + { numnames #1 + 'numnames := } + { #0 'numnames := + large.number.trigger 'nameptr := + } + if$ + t #-1 #1 substring$ swap$ * + t #-2 global.max$ substring$ 't := + numnames nameptr = + { duplicate$ #1 nameptr large.number.blocksize - substring$ swap$ + nameptr large.number.blocksize - #1 + global.max$ substring$ + large.number.separator swap$ * * + nameptr large.number.blocksize - 'numnames := + large.number.blocksize #1 + 'nameptr := + } + { skip$ } + if$ + } + while$ +} + +% Converts all single dashes "-" to double dashes "--". +FUNCTION {n.dashify} +{ large.number.separate + 't := + "" + { t empty$ not } + { t #1 #1 substring$ "-" = + { t #1 #2 substring$ "--" = not + { "--" * + t #2 global.max$ substring$ 't := + } + { { t #1 #1 substring$ "-" = } + { "-" * + t #2 global.max$ substring$ 't := + } + while$ + } + if$ + } + { t #1 #1 substring$ * + t #2 global.max$ substring$ 't := + } + if$ + } + while$ +} + + +% This function detects entries with names that are identical to that of +% the previous entry and replaces the repeated names with dashes (if the +% "is.dash.repeated.names" user control is nonzero). +FUNCTION {name.or.dash} +{ 's := + oldname empty$ + { s 'oldname := s } + { s oldname = + { is.dash.repeated.names + { repeated.name.dashes } + { s 'oldname := s } + if$ + } + { s 'oldname := s } + if$ + } + if$ +} + +% Converts the number string on the top of the stack to +% "numerical ordinal form" (e.g., "7" to "7th"). There is +% no artificial limit to the upper bound of the numbers as the +% two least significant digits determine the ordinal form. +FUNCTION {num.to.ordinal} +{ duplicate$ #-2 #1 substring$ "1" = + { bbl.th * } + { duplicate$ #-1 #1 substring$ "1" = + { bbl.st * } + { duplicate$ #-1 #1 substring$ "2" = + { bbl.nd * } + { duplicate$ #-1 #1 substring$ "3" = + { bbl.rd * } + { bbl.th * } + if$ + } + if$ + } + if$ + } + if$ +} + +% If the string on the top of the stack begins with a number, +% (e.g., 11th) then replace the string with the leading number +% it contains. Otherwise retain the string as-is. s holds the +% extracted number, t holds the part of the string that remains +% to be scanned. +FUNCTION {extract.num} +{ duplicate$ 't := + "" 's := + { t empty$ not } + { t #1 #1 substring$ + t #2 global.max$ substring$ 't := + duplicate$ is.num + { s swap$ * 's := } + { pop$ "" 't := } + if$ + } + while$ + s empty$ + 'skip$ + { pop$ s } + if$ +} + +% Converts the word number string on the top of the stack to +% Arabic string form. Will be successful up to "tenth". +FUNCTION {word.to.num} +{ duplicate$ "l" change.case$ 's := + s "first" = + { pop$ "1" } + { skip$ } + if$ + s "second" = + { pop$ "2" } + { skip$ } + if$ + s "third" = + { pop$ "3" } + { skip$ } + if$ + s "fourth" = + { pop$ "4" } + { skip$ } + if$ + s "fifth" = + { pop$ "5" } + { skip$ } + if$ + s "sixth" = + { pop$ "6" } + { skip$ } + if$ + s "seventh" = + { pop$ "7" } + { skip$ } + if$ + s "eighth" = + { pop$ "8" } + { skip$ } + if$ + s "ninth" = + { pop$ "9" } + { skip$ } + if$ + s "tenth" = + { pop$ "10" } + { skip$ } + if$ +} + + +% Converts the string on the top of the stack to numerical +% ordinal (e.g., "11th") form. +FUNCTION {convert.edition} +{ duplicate$ empty$ 'skip$ + { duplicate$ #1 #1 substring$ is.num + { extract.num + num.to.ordinal + } + { word.to.num + duplicate$ #1 #1 substring$ is.num + { num.to.ordinal } + { "edition ordinal word " quote$ * edition * quote$ * + " may be too high (or improper) for conversion" * " in " * cite$ * warning$ + } + if$ + } + if$ + } + if$ +} + + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LATEX BIBLIOGRAPHY CODE %% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +FUNCTION {start.entry} +{ newline$ + "\bibitem{" write$ + cite$ write$ + "}" write$ + newline$ + "" + initialize.prev.this.status +} + +% Here we write out all the LaTeX code that we will need. The most involved +% code sequences are those that control the alternate interword spacing and +% foreign language hyphenation patterns. The heavy use of \providecommand +% gives users a way to override the defaults. Special thanks to Javier Bezos, +% Johannes Braams, Robin Fairbairns, Heiko Oberdiek, Donald Arseneau and all +% the other gurus on comp.text.tex for their help and advice on the topic of +% \selectlanguage, Babel and BibTeX. +FUNCTION {begin.bib} +{ "% Generated by IEEEtran.bst, version: " bst.file.version * " (" * bst.file.date * ")" * + write$ newline$ + preamble$ empty$ 'skip$ + { preamble$ write$ newline$ } + if$ + "\begin{thebibliography}{" longest.label * "}" * + write$ newline$ + "\providecommand{\url}[1]{#1}" + write$ newline$ + "\csname url@samestyle\endcsname" + write$ newline$ + "\providecommand{\newblock}{\relax}" + write$ newline$ + "\providecommand{\bibinfo}[2]{#2}" + write$ newline$ + % User-configurable appearance hooks. Defaults match the historic + % IEEE.bst look (\small font, single line spacing, -5pt itemsep). + % Override from the document preamble, e.g.: + % \renewcommand{\bibfontsize}{\footnotesize} + % \renewcommand{\biblinespread}{1.1} + % \renewcommand{\bibitemsep}{0pt} + "\providecommand{\bibfontsize}{\small}" + write$ newline$ + "\providecommand{\biblinespread}{1.0}" + write$ newline$ + "\providecommand{\bibitemsep}{-5pt}" + write$ newline$ + "\bibfontsize\linespread{\biblinespread}\selectfont" + write$ newline$ + "\setlength{\itemsep}{\bibitemsep}" + write$ newline$ + "\providecommand{\BIBentrySTDinterwordspacing}{\spaceskip=0pt\relax}" + write$ newline$ + "\providecommand{\BIBentryALTinterwordstretchfactor}{" + ALTinterwordstretchfactor * "}" * + write$ newline$ + "\providecommand{\BIBentryALTinterwordspacing}{\spaceskip=\fontdimen2\font plus " + write$ newline$ + "\BIBentryALTinterwordstretchfactor\fontdimen3\font minus \fontdimen4\font\relax}" + write$ newline$ + "\providecommand{\BIBforeignlanguage}[2]{{%" + write$ newline$ + "\expandafter\ifx\csname l@#1\endcsname\relax" + write$ newline$ + "\typeout{** WARNING: IEEEtran.bst: No hyphenation pattern has been}%" + write$ newline$ + "\typeout{** loaded for the language `#1'. Using the pattern for}%" + write$ newline$ + "\typeout{** the default language instead.}%" + write$ newline$ + "\else" + write$ newline$ + "\language=\csname l@#1\endcsname" + write$ newline$ + "\fi" + write$ newline$ + "#2}}" + write$ newline$ + "\providecommand{\BIBdecl}{\relax}" + write$ newline$ + "\BIBdecl" + write$ newline$ +} + +FUNCTION {end.bib} +{ newline$ "\end{thebibliography}" write$ newline$ } + +FUNCTION {if.url.alt.interword.spacing} +{ is.use.alt.interword.spacing + { is.use.url + { url empty$ 'skip$ {"\BIBentryALTinterwordspacing" write$ newline$} if$ } + { skip$ } + if$ + } + { skip$ } + if$ +} + +FUNCTION {if.url.std.interword.spacing} +{ is.use.alt.interword.spacing + { is.use.url + { url empty$ 'skip$ {"\BIBentrySTDinterwordspacing" write$ newline$} if$ } + { skip$ } + if$ + } + { skip$ } + if$ +} + + + + +%%%%%%%%%%%%%%%%%%%%%%%% +%% LONGEST LABEL PASS %% +%%%%%%%%%%%%%%%%%%%%%%%% + +FUNCTION {initialize.longest.label} +{ "" 'longest.label := + #1 'number.label := + #0 'longest.label.width := +} + +FUNCTION {longest.label.pass} +{ type$ "ieeetranbstctl" = + { skip$ } + { number.label int.to.str$ 'label := + number.label #1 + 'number.label := + label width$ longest.label.width > + { label 'longest.label := + label width$ 'longest.label.width := + } + { skip$ } + if$ + } + if$ +} + + + + +%%%%%%%%%%%%%%%%%%%%% +%% FORMAT HANDLERS %% +%%%%%%%%%%%%%%%%%%%%% + +%% Lower Level Formats (used by higher level formats) + +FUNCTION {format.address.org.or.pub.date} +{ 't := + "" + year empty$ + { "empty year in " cite$ * warning$ } + { skip$ } + if$ + address empty$ t empty$ and + year empty$ and month empty$ and + { skip$ } + { this.to.prev.status + this.status.std + cap.status.std + address "address" bibinfo.check * + t empty$ + { skip$ } + { punct.period 'prev.status.punct := + space.normal 'prev.status.space := + address empty$ + { skip$ } + { ": " * } + if$ + t * + } + if$ + % For foreign-language books / proceedings, the + % marker "(in Language)" is inserted between the publisher and the + % year, e.g. "Tokyo: Nihon Keizai Hyoronsha (in Japanese), 2000.". + inlanguage empty$ + { skip$ } + { " (in " * inlanguage "inlanguage" bibinfo.check * ")" * } + if$ + year empty$ month empty$ and + { skip$ } + { t empty$ address empty$ and + { skip$ } + { ", " * } + if$ + month empty$ + { year empty$ + { skip$ } + { year "year" bibinfo.check * } + if$ + } + { month "month" bibinfo.check * + % when both month and day are present (typical for + % conference proceedings), the date reads "Month Day, Year", + % e.g. "Jun. 2--6, 2003". Without a day it stays "Month Year". + day empty$ + { skip$ } + { " " * day "day" bibinfo.check * } + if$ + year empty$ + { skip$ } + { day empty$ + { " " * year "year" bibinfo.check * } + { ", " * year "year" bibinfo.check * } + if$ + } + if$ + } + if$ + } + if$ + } + if$ +} + + +FUNCTION {format.names} +{ 'bibinfo := + duplicate$ empty$ 'skip$ { + this.to.prev.status + this.status.std + 's := + "" 't := + #1 'nameptr := + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { s nameptr + name.format.string + format.name$ + bibinfo bibinfo.check + 't := + nameptr #1 > + { nameptr num.names.shown.with.forced.et.al #1 + = + bibinfo "editor" = + { numnames max.num.editors.before.forced.et.al > } + { numnames max.num.names.before.forced.et.al > } + if$ + is.forced.et.al and and + { "others" 't := + #1 'namesleft := + } + { skip$ } + if$ + namesleft #1 > + { ", " * t do.name.latex.cmd * } + { s nameptr "{ll}" format.name$ duplicate$ "others" = + { 't := } + { pop$ } + if$ + t "others" = + { " " * bbl.etal emphasize * } + { numnames #2 > + { "," * } + { skip$ } + if$ + bbl.and + space.word * t do.name.latex.cmd * + } + if$ + } + if$ + } + { t do.name.latex.cmd } + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ + cap.status.std + } if$ +} + + + + +%% Higher Level Formats + +%% addresses/locations + +FUNCTION {format.address} +{ address duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + } + if$ +} + + +FUNCTION {format.doi} +{ doi empty$ + { "" } + { this.to.prev.status + this.status.std + "doi:\mylinkurl{" doi * "}" * + cap.status.std + } + if$ +} + + +%% author/editor names + +FUNCTION {format.authors} +{ author "author" format.names + author empty$ editor empty$ or + 'skip$ + { author editor = + { ", " * + editor num.names$ #1 > + 'bbl.editors + 'bbl.editor + if$ + * + } + 'skip$ + if$ + } + if$ +} + +FUNCTION {format.editors} +{ editor "editor" format.names duplicate$ empty$ 'skip$ + { ", " * + get.bbl.editor + capitalize + * + } + if$ +} + + + +%% date + +FUNCTION {format.date} +{ + month "month" bibinfo.check duplicate$ empty$ + year "year" bibinfo.check duplicate$ empty$ + { swap$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + "there's a month but no year in " cite$ * warning$ } + if$ + * + } + { this.to.prev.status + this.status.std + cap.status.std + swap$ 'skip$ + { + % If day is supplied, format as "Month Day, Year"; otherwise "Month Year". + day empty$ + { swap$ + " " * swap$ + } + { swap$ + " " * day * ", " * swap$ + } + if$ + } + if$ + * + } + if$ +} + +FUNCTION {format.date.electronic} +{ month "month" bibinfo.check duplicate$ empty$ + year "year" bibinfo.check duplicate$ empty$ + { swap$ + { pop$ } + { "there's a month but no year in " cite$ * warning$ + pop$ ")" * "(" swap$ * + this.to.prev.status + % The "(Date)" cluster is followed by a sentence + % separator (period in period-style entries, comma in + % comma-style entries). Inherit punct.std rather than + % suppressing it with punct.no. + punct.std 'this.status.punct := + space.normal 'this.status.space := + quote.no 'this.status.quote := + cap.yes 'status.cap := + } + if$ + } + { swap$ + { swap$ pop$ ")" * "(" swap$ * } + { % Render electronic dates as "(Month Day, Year)" when + % a day is available (e.g., online video, online manual), or as + % "(Month Year)" otherwise (e.g., online conference paper). + % Stack on entry: [month_val, year_val] (year on top). + day empty$ + { swap$ "(" swap$ * " " * swap$ * ")" * } + { swap$ "(" swap$ * " " * day * ", " * swap$ * ")" * } + if$ + } + if$ + this.to.prev.status + % "(Date)" is followed by a sentence separator inherited + % from the entry's std punctuation (period for online references, + % comma elsewhere). + punct.std 'this.status.punct := + space.normal 'this.status.space := + quote.no 'this.status.quote := + cap.yes 'status.cap := + } + if$ +} + + + +%% edition/title + +% Note: The IEEE considers the edition to be closely associated with +% the title of a book. So, in IEEEtran.bst the edition is normally handled +% within the formatting of the title. The format.edition function is +% retained here for possible future use. +FUNCTION {format.edition} +{ edition duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + convert.edition + status.cap + { "t" } + { "l" } + if$ change.case$ + "edition" bibinfo.check + "~" * bbl.edition * + cap.status.std + } + if$ +} + +% This is used to format the booktitle of a conference proceedings. +% Here we use the "intype" field to provide the user a way to +% override the word "in" (e.g., with things like "presented at") +% Use of intype stops the emphasis of the booktitle to indicate that +% we no longer mean the written conference proceedings, but the +% conference itself. +FUNCTION {format.in.booktitle} +{ booktitle "booktitle" bibinfo.check duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + select.language + intype missing$ + { emphasize + bbl.in " " * + } + { intype " " * } + if$ + swap$ * + cap.status.std + } + if$ +} + +% This is used to format the booktitle of collection. +% Here the "intype" field is not supported, but "edition" is. +FUNCTION {format.in.booktitle.edition} +{ booktitle "booktitle" bibinfo.check duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + select.language + emphasize + edition empty$ 'skip$ + { ", " * + edition + convert.edition + "l" change.case$ + * "~" * bbl.edition * + } + if$ + bbl.in " " * swap$ * + cap.status.std + } + if$ +} + + +FUNCTION {format.article.title} +{ title duplicate$ empty$ 'skip$ + { "t" change.case$ } + if$ + "title" bibinfo.check + titleraw empty$ + { skip$ } + { titleraw "t" change.case$ "titleraw" bibinfo.check + emphasize + swap$ " [" swap$ * "]" * * + } + if$ + duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + quote.close 'this.status.quote := + is.last.char.not.punct + { punct.std 'this.status.punct := } + { punct.no 'this.status.punct := } + if$ + select.language + "``" swap$ * + cap.status.std + } + if$ +} + + +FUNCTION {format.article.title.electronic} +{ title duplicate$ empty$ 'skip$ + { "t" change.case$ } + if$ + "title" bibinfo.check + titleraw empty$ + { skip$ } + { titleraw "t" change.case$ "titleraw" bibinfo.check + emphasize + swap$ " [" swap$ * "]" * * + } + if$ + duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + quote.close 'this.status.quote := + is.last.char.not.punct + { punct.std 'this.status.punct := } + { punct.no 'this.status.punct := } + if$ + select.language + "``" swap$ * + cap.status.std + } + if$ +} + + +FUNCTION {format.book.title.edition} +{ title "title" bibinfo.check + titleraw empty$ + { % No transliteration supplied: italicise the title itself. + duplicate$ empty$ 'skip$ 'emphasize if$ + } + { titleraw "titleraw" bibinfo.check + emphasize + swap$ " [" swap$ * "]" * * + } + if$ + duplicate$ empty$ + { "empty title in " cite$ * warning$ } + { this.to.prev.status + this.status.std + select.language + edition empty$ 'skip$ + { ", " * + edition + convert.edition + status.cap + { "t" } + { "l" } + if$ + change.case$ + * "~" * bbl.edition * + } + if$ + cap.status.std + } + if$ +} + + +FUNCTION {format.book.title} +{ title "title" bibinfo.check + titleraw empty$ + { % No transliteration supplied: italicise the title itself. + duplicate$ empty$ 'skip$ 'emphasize if$ + } + { titleraw "titleraw" bibinfo.check + emphasize + swap$ " [" swap$ * "]" * * + } + if$ + duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + select.language + } + if$ +} + + + +%% journal + +FUNCTION {format.journal} +{ journal duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + select.language + emphasize + } + if$ +} + + +%% Plain (un-italicised) variant of format.journal — used for blog +%% references where the blog source title is set in roman type. +FUNCTION {format.journal.plain} +{ journal duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + select.language + } + if$ +} + + + +%% how published + +FUNCTION {format.howpublished} +{ howpublished duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + } + if$ +} + + + +%% institutions/organization/publishers/school + +FUNCTION {format.institution} +{ institution duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + } + if$ +} + +FUNCTION {format.organization} +{ organization duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + } + if$ +} + +FUNCTION {format.address.publisher.date} +{ publisher "publisher" bibinfo.warn format.address.org.or.pub.date } + +FUNCTION {format.address.publisher.date.nowarn} +{ publisher "publisher" bibinfo.check format.address.org.or.pub.date } + +FUNCTION {format.address.organization.date} +{ organization "organization" bibinfo.check format.address.org.or.pub.date } + +FUNCTION {format.school} +{ school duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + } + if$ +} + + + +%% volume/number/series/chapter/pages + +FUNCTION {format.volume} +{ volume empty.field.to.null.string + duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + bbl.volume + status.cap + { capitalize } + { skip$ } + if$ + swap$ tie.or.space.prefix + "volume" bibinfo.check + * * + cap.status.std + } + if$ +} + +FUNCTION {format.number} +{ number empty.field.to.null.string + duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + status.cap + { bbl.number capitalize } + { bbl.number } + if$ + swap$ tie.or.space.prefix + "number" bibinfo.check + * * + cap.status.std + } + if$ +} + +FUNCTION {format.number.if.use.for.article} +{ is.use.number.for.article + { format.number } + { "" } + if$ +} + +% The series title (and any series volume number) is treated +% as an extension of the book/proceedings title and is enclosed in +% parentheses immediately after it, e.g. "Title (Series Title, 67)". +% We deliberately bind the parenthesised series to the previous item +% (the title) with a space rather than a comma so the parenthesis sits +% flush against the title in the rendered bibliography. +% This is the BOOK style. See format.series.in for the conference style. +FUNCTION {format.series} +{ series empty$ + { "" } + { this.to.prev.status + this.status.std + punct.no 'prev.status.punct := + space.normal 'prev.status.space := + "(" series "series" bibinfo.check * ")" * + cap.status.std + } + if$ +} + + +%% Series formatter for CONFERENCE PROCEEDINGS. +%% Conference Proceedings With Series Title: +%% "in Abbreviated Name of Conf., in Series Title, vol. X, X ed., ..." +%% The series here is rendered in roman type (no italics) and prefixed +%% with "in ", not wrapped in parentheses as it is for books. +FUNCTION {format.series.in} +{ series empty$ + { "" } + { this.to.prev.status + this.status.std + bbl.in " " * + series "series" bibinfo.check * + cap.status.std + } + if$ +} + + +FUNCTION {format.chapter} +{ chapter empty$ + { "" } + { this.to.prev.status + this.status.std + type empty$ + { bbl.chapter } + { type "l" change.case$ + "type" bibinfo.check + } + if$ + chapter tie.or.space.prefix + "chapter" bibinfo.check + * * + cap.status.std + } + if$ +} + + +% The intended use of format.paper is for paper numbers of inproceedings. +% The paper type can be overridden via the type field. +% We allow the type to be displayed even if the paper number is absent +% for things like "postdeadline paper" +FUNCTION {format.paper} +{ is.use.paper + { paper empty$ + { type empty$ + { "" } + { this.to.prev.status + this.status.std + type "type" bibinfo.check + cap.status.std + } + if$ + } + { this.to.prev.status + this.status.std + type empty$ + { bbl.paper } + { type "type" bibinfo.check } + if$ + " " * paper + "paper" bibinfo.check + * + cap.status.std + } + if$ + } + { "" } + if$ +} + + +FUNCTION {format.pages} +{ pages duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + duplicate$ is.multiple.pages + { + bbl.pages swap$ + n.dashify + } + { + bbl.page swap$ + } + if$ + tie.or.space.prefix + "pages" bibinfo.check + * * + cap.status.std + } + if$ +} + + + +%% technical report number + +FUNCTION {format.tech.report.number} +{ number "number" bibinfo.check + this.to.prev.status + this.status.std + cap.status.std + type duplicate$ empty$ + { pop$ + bbl.techrep + } + { skip$ } + if$ + "type" bibinfo.check + swap$ duplicate$ empty$ + { pop$ } + { tie.or.space.prefix * * } + if$ +} + + + +%% note + +FUNCTION {format.note} +{ note empty$ + { "" } + { this.to.prev.status + this.status.std + punct.period 'this.status.punct := + note #1 #1 substring$ + duplicate$ "{" = + { skip$ } + { status.cap + { "u" } + { "l" } + if$ + change.case$ + } + if$ + note #2 global.max$ substring$ * + "(" swap$ * ")" * % <-- ADDED: wraps note in parentheses + "note" bibinfo.check + cap.yes 'status.cap := + } + if$ +} + + + +%% patent + +FUNCTION {format.patent.date} +{ this.to.prev.status + this.status.std + year empty$ + { monthfiled duplicate$ empty$ + { "monthfiled" bibinfo.check pop$ "" } + { "monthfiled" bibinfo.check } + if$ + dayfiled duplicate$ empty$ + { "dayfiled" bibinfo.check pop$ " " * } + { "dayfiled" bibinfo.check + monthfiled empty$ + { "dayfiled without a monthfiled in " cite$ * warning$ + * + } + { " " swap$ * * } + if$ + } + if$ + yearfiled empty$ + { "no year or yearfiled in " cite$ * warning$ } + { yearfiled "yearfiled" bibinfo.check + swap$ + duplicate$ empty$ + { pop$ } + { ", " * swap$ * } + if$ + } + if$ + } + { month duplicate$ empty$ + { "month" bibinfo.check pop$ "" } + { "month" bibinfo.check } + if$ + day duplicate$ empty$ + { "day" bibinfo.check pop$ "" * } + { "day" bibinfo.check + month empty$ + { "day without a month in " cite$ * warning$ + * + } + { " " swap$ * * } + if$ + } + if$ + year "year" bibinfo.check + swap$ + duplicate$ empty$ + { pop$ } + { ", " * swap$ * } + if$ + } + if$ + cap.status.std +} + +FUNCTION {format.patent.nationality.type.number} +{ this.to.prev.status + this.status.std + nationality duplicate$ empty$ + { "nationality" bibinfo.warn pop$ "" } + { "nationality" bibinfo.check + duplicate$ "l" change.case$ "united states" = + { pop$ bbl.patentUS } + { skip$ } + if$ + " " * + } + if$ + type empty$ + { bbl.patent "type" bibinfo.check } + { type "type" bibinfo.check } + if$ + * + number duplicate$ empty$ + { "number" bibinfo.warn pop$ } + { "number" bibinfo.check + large.number.separate + swap$ " " * swap$ * + } + if$ + cap.status.std +} + + + +%% standard + +FUNCTION {format.organization.institution.standard.type.number} +{ this.to.prev.status + this.status.std + organization duplicate$ empty$ + { pop$ + institution duplicate$ empty$ + { "institution" bibinfo.warn } + { "institution" bibinfo.warn " " * } + if$ + } + { "organization" bibinfo.warn " " * } + if$ + type empty$ + { bbl.standard "type" bibinfo.check } + { type "type" bibinfo.check } + if$ + * + number duplicate$ empty$ + { "number" bibinfo.check pop$ } + { "number" bibinfo.check + large.number.separate + swap$ " " * swap$ * + } + if$ + cap.status.std +} + +FUNCTION {format.revision} +{ revision empty$ + { "" } + { this.to.prev.status + this.status.std + bbl.revision + revision tie.or.space.prefix + "revision" bibinfo.check + * * + cap.status.std + } + if$ +} + + +%% thesis + +FUNCTION {format.master.thesis.type} +{ this.to.prev.status + this.status.std + type empty$ + { + bbl.mthesis + } + { + type "type" bibinfo.check + } + if$ +cap.status.std +} + +FUNCTION {format.phd.thesis.type} +{ this.to.prev.status + this.status.std + type empty$ + { + bbl.phdthesis + } + { + type "type" bibinfo.check + } + if$ +cap.status.std +} + + + +%% URL +%% A reference may carry both a DOI and a URL; in that +%% case the DOI is rendered first, terminated by a period, and the URL +%% follows. Earlier versions of IEEEtran.bst suppressed the URL whenever +%% a DOI was present — we drop that suppression so both fields render. +FUNCTION {format.url} +{ is.use.url + { url empty$ + { "" } + { this.to.prev.status + this.status.std + cap.yes 'status.cap := + name.url.prefix " " * + "\url{" * url * "}" * + punct.no 'this.status.punct := + punct.period 'prev.status.punct := + space.normal 'this.status.space := + space.normal 'prev.status.space := + quote.no 'this.status.quote := + } + if$ + } + { "" } + if$ +} + + +%% "(in Language)" marker — placed immediately after the article/paper +%% title for non-English publications ("Periodical +%% in Other Language" and "Manual" online). Output form: +%% "(in German)", "(in Russian)" etc. Reads from the `inlanguage` +%% field (kept distinct from `language`, which is consumed by +%% \BIBforeignlanguage for hyphenation only). +%% +%% IEEE convention: the marker is ALWAYS followed by a comma, but the +%% punctuation BEFORE it depends on the entry type: +%% - period before "(in Lang)" --> Video, Lecture +%% e.g. "Title of Video. (in Language), (Release date)." +%% - comma before "(in Lang)" --> Article, Manual, Book +%% e.g. "Title, (in Language), x ed. (Year)." +%% +%% format.in.language therefore leaves prev.status.punct alone (so it +%% inherits whatever the previous format function set, typically the +%% entry-level std punctuation) and forces this.status.punct to comma +%% so the following item is joined with a comma. +%% Handlers that want a comma BEFORE "(in Lang)" in a period-style +%% entry (e.g. @manual online) override this.status.punct := comma on +%% the title BEFORE calling format.in.language. +FUNCTION {format.in.language} +{ inlanguage duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + punct.comma 'this.status.punct := + space.normal 'this.status.space := + "inlanguage" bibinfo.check + "(in " swap$ * ")" * + cap.status.std + } + if$ +} + + +%% translator (used for translated books, conference proceedings, etc.) +%% Output form: "trans. J. K. Translator" +FUNCTION {format.translator} +{ translator duplicate$ empty$ 'skip$ + { pop$ + translator "translator" format.names + duplicate$ empty$ 'skip$ + { bbl.translator " " * swap$ * } + if$ + } + if$ +} + +% The `urldate` field in the .bib can be written in any of the three +% popular formats; this section parses it and reformats to IEEE +% "Mon. DD, YYYY" before it ever reaches the output. Inputs: +% * ISO "YYYY-MM-DD" e.g. 2026-04-06 +% * GOST "DD.MM.YYYY" e.g. 06.04.2026 +% * IEEE "Mon. DD, YYYY" (also accepts "Month DD, YYYY") e.g. Apr. 6, 2026 +FUNCTION {ud.unpad} +{ duplicate$ text.length$ #2 = + { duplicate$ #1 #1 substring$ "0" = + { #2 #1 substring$ } + { skip$ } + if$ + } + { skip$ } + if$ +} + +FUNCTION {ud.month.num.to.abbrev} +{ duplicate$ "01" = { pop$ "Jan." } { + duplicate$ "02" = { pop$ "Feb." } { + duplicate$ "03" = { pop$ "Mar." } { + duplicate$ "04" = { pop$ "Apr." } { + duplicate$ "05" = { pop$ "May" } { + duplicate$ "06" = { pop$ "Jun." } { + duplicate$ "07" = { pop$ "Jul." } { + duplicate$ "08" = { pop$ "Aug." } { + duplicate$ "09" = { pop$ "Sep." } { + duplicate$ "10" = { pop$ "Oct." } { + duplicate$ "11" = { pop$ "Nov." } { + duplicate$ "12" = { pop$ "Dec." } { + skip$ + } if$ } if$ } if$ } if$ } if$ } if$ } if$ } if$ } if$ } if$ } if$ } if$ +} + +FUNCTION {ud.month.name.to.num} +{ duplicate$ #1 #3 substring$ "l" change.case$ 'ud.tmp := + ud.tmp "jan" = + { pop$ "01" } + { ud.tmp "feb" = + { pop$ "02" } + { ud.tmp "mar" = + { pop$ "03" } + { ud.tmp "apr" = + { pop$ "04" } + { ud.tmp "may" = + { pop$ "05" } + { ud.tmp "jun" = + { pop$ "06" } + { ud.tmp "jul" = + { pop$ "07" } + { ud.tmp "aug" = + { pop$ "08" } + { ud.tmp "sep" = + { pop$ "09" } + { ud.tmp "oct" = + { pop$ "10" } + { ud.tmp "nov" = + { pop$ "11" } + { ud.tmp "dec" = + { pop$ "12" } + { skip$ } + if$ + } + if$ + } + if$ + } + if$ + } + if$ + } + if$ + } + if$ + } + if$ + } + if$ + } + if$ + } + if$ + } + if$ +} + +FUNCTION {parse.urldate} +{ "no" 'ud.parsed := + "" 'ud.y := "" 'ud.m := "" 'ud.d := + urldate empty$ 'skip$ + { urldate text.length$ 'ud.len := + ud.len #10 = + { % ISO YYYY-MM-DD? + urldate #5 #1 substring$ "-" = + urldate #8 #1 substring$ "-" = and + { urldate #1 #4 substring$ 'ud.y := + urldate #6 #2 substring$ 'ud.m := + urldate #9 #2 substring$ 'ud.d := + "yes" 'ud.parsed := + } + { % GOST DD.MM.YYYY? + urldate #3 #1 substring$ "." = + urldate #6 #1 substring$ "." = and + { urldate #1 #2 substring$ 'ud.d := + urldate #4 #2 substring$ 'ud.m := + urldate #7 #4 substring$ 'ud.y := + "yes" 'ud.parsed := + } + { skip$ } + if$ + } + if$ + } + { skip$ } + if$ + ud.parsed "no" = + { ud.len #7 > + { urldate ud.len #3 - #4 substring$ 'ud.y := + urldate ud.len #4 - #1 substring$ " " = + urldate ud.len #5 - #1 substring$ "," = and + { % Pre-year (positions 1..len-6) = "Mon[.] DD". + % Find first space to separate month from day. + #1 'ud.idx := + #0 'ud.space.pos := + { ud.idx ud.len #5 - < + ud.space.pos #0 = and + } + { urldate ud.idx #1 substring$ " " = + { ud.idx 'ud.space.pos := } + { skip$ } + if$ + ud.idx #1 + 'ud.idx := + } + while$ + ud.space.pos #0 > + { urldate #1 ud.space.pos #1 - substring$ + ud.month.name.to.num 'ud.m := + urldate ud.space.pos #1 + + ud.len #6 - ud.space.pos - + substring$ 'ud.d := + "yes" 'ud.parsed := + } + { skip$ } + if$ + } + { skip$ } + if$ + } + { skip$ } + if$ + } + { skip$ } + if$ + } + if$ +} + +FUNCTION {urldate.in.ieee.style} +{ parse.urldate + ud.parsed "yes" = + { ud.m ud.month.num.to.abbrev " " * ud.d ud.unpad * ", " * ud.y * } + { urldate } + if$ +} + + +%% accessed date (used for online references) +%% Output form: "Accessed: Month Day, Year" +%% IEEE: the accessed-date phrase is preceded by a period (not a comma), +%% even inside comma-style entries. +FUNCTION {format.urldate} +{ urldate duplicate$ empty$ 'skip$ + { pop$ + this.to.prev.status + this.status.std + punct.period 'prev.status.punct := + space.normal 'prev.status.space := + urldate.in.ieee.style + "urldate" bibinfo.check + bbl.accessed " " * swap$ * + cap.yes 'status.cap := + } + if$ +} + + +%% Social-media variant of format.urldate — omits the colon after +%% "Accessed" to match the social-media layout +%% ("Accessed Apr. 19, 2021" instead of "Accessed: Apr. 19, 2021"). +FUNCTION {format.urldate.social} +{ urldate duplicate$ empty$ 'skip$ + { pop$ + this.to.prev.status + this.status.std + punct.period 'prev.status.punct := + space.normal 'prev.status.space := + urldate.in.ieee.style + "urldate" bibinfo.check + "Accessed " swap$ * + cap.yes 'status.cap := + } + if$ +} + + +%% [Online]. / [Online Video]. marker +%% IEEE style: the preceding field is terminated with a period before the +%% medium marker, regardless of whether the entry uses comma- or +%% period-style internal separators. We override prev.status.punct to +%% period but leave prev.status.quote intact so that a quoted title that +%% immediately precedes the marker still gets its closing "''" written. +FUNCTION {format.online.marker} +{ url empty$ + { "" } + { this.to.prev.status + this.status.std + punct.period 'prev.status.punct := + space.normal 'prev.status.space := + medium empty$ + { bbl.online } + { "[" medium * "]." * } + if$ + punct.no 'this.status.punct := + space.normal 'this.status.space := + cap.yes 'status.cap := + } + if$ +} + + +%% Article ID (Art. no. XXX) for periodicals identified by article number +FUNCTION {format.articleno} +{ articleno duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + "articleno" bibinfo.check + bbl.article.no " " * swap$ * + cap.status.std + } + if$ +} + + +%% arXiv preprint: "arXiv:XXXX.XXXXX" +FUNCTION {format.eprint} +{ eprint duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + "eprint" bibinfo.check + eprinttype empty$ + { bbl.arxiv swap$ * emphasize } + { eprinttype "l" change.case$ "arxiv" = + { bbl.arxiv swap$ * emphasize } + { eprinttype ":" * swap$ * emphasize } + if$ + } + if$ + cap.status.std + } + if$ +} + + +%% Software version (for @software entries) +FUNCTION {format.version} +{ version duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + "version" bibinfo.check + "(" swap$ * ")" * + cap.status.std + } + if$ +} + + +%% Repository / archive name (for @software entries) +FUNCTION {format.repository} +{ repository duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + "repository" bibinfo.check + cap.status.std + } + if$ +} + + +%% Section (sect. x) used in books/chapters +FUNCTION {format.section} +{ section duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + "section" bibinfo.check + bbl.section swap$ tie.or.space.prefix * * + cap.status.std + } + if$ +} + + + + +%%%%%%%%%%%%%%%%%%%% +%% ENTRY HANDLERS %% +%%%%%%%%%%%%%%%%%%%% + + +% Note: In many journals, the IEEE (or the authors) tend not to show the number +% for articles, so the display of the number is controlled here by the +% switch "is.use.number.for.article" +FUNCTION {article} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.in.language output + format.journal "journal" bibinfo.check "journal" output.warn + format.volume output + format.number.if.use.for.article output + articleno empty$ + { format.pages output } + { skip$ } + if$ + format.date "year" output.warn + format.articleno output + format.note output + format.doi output + format.urldate output + format.online.marker output + format.url output + fin.entry + if.url.std.interword.spacing +} + + +FUNCTION {book} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + author empty$ + { format.editors "author and editor" output.warn } + { format.authors output.nonnull } + if$ + name.or.dash + format.book.title.edition output + format.series output + author empty$ + { skip$ } + { format.editors output } + if$ + format.translator output + format.address.publisher.date output + format.volume output + format.number output + format.chapter output + format.section output + format.pages output + format.note output + format.doi output + format.urldate output + format.online.marker output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {booklet} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.article.title "title" output.warn + format.howpublished "howpublished" bibinfo.check output + format.organization "organization" bibinfo.check output + format.address "address" bibinfo.check output + format.date output + format.note output + format.doi output + format.url output + fin.entry + if.url.std.interword.spacing +} + +%% @electronic — generic online reference (also the target of the +%% @online / @website / @socialmedia / @webpage / @internet / @www +%% aliases). "Websites" prescribes a roman +%% (non-italicised) website / source title: +%% J. K. Author. "Page Title." Website Title. Accessed: Date. +%% [Online]. Available: URL +%% We therefore render the `journal` field through format.journal.plain +%% rather than the italicising format.journal used by periodicals. +FUNCTION {electronic} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.date.electronic output + format.article.title.electronic output + format.journal.plain output + format.howpublished "howpublished" bibinfo.check output + format.organization "organization" bibinfo.check output + format.address "address" bibinfo.check output + format.note output + format.doi output + format.urldate output + format.online.marker output + format.url output + fin.entry + empty.entry.warn + if.url.std.interword.spacing +} + +FUNCTION {inbook} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + author empty$ + { format.editors "author and editor" output.warn } + { format.authors output.nonnull } + if$ + name.or.dash + format.book.title.edition output + format.series output + author empty$ + { skip$ } + { format.editors output } + if$ + format.translator output + format.address.publisher.date output + format.volume output + format.number output + format.chapter output + format.section output + format.pages output + format.note output + format.doi output + format.urldate output + format.online.marker output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {incollection} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + % NOTE: for books/chapters the "(in Language)" marker is placed between + % the publisher and the year by format.address.publisher.date — NOT + % after the chapter title. We therefore do NOT call format.in.language + % here. + format.in.booktitle "booktitle" output.warn + format.series output + format.editors output + format.translator output + % the edition is placed AFTER editors and translator, + % immediately before the address/publisher block, e.g. + % "in BookTitle, X. Editor, Ed., trans. T. Translator, 3rd ed. City: ..." + format.edition output + format.address.publisher.date.nowarn output + format.volume output + format.number output + format.chapter output + format.section output + format.pages output + format.note output + format.doi output + format.urldate output + format.online.marker output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {inproceedings} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + % "(in Language)" goes right after the closing quote of the + % paper title, before "in Abbreviated Name of Conf.". + format.in.language output + format.in.booktitle "booktitle" output.warn + % Series for conference proceedings: prefixed with "in ", roman type + % (NOT parenthesised — that is the book layout). + format.series.in output + format.editors output + format.volume output + format.number output + % Edition comes after vol./no., immediately before the date block + % ("Conference Proceedings With Series Title, Volume Title, + % and Edition": "... vol. X, X ed., Jul. 2006, pp. 4301-4304."). + format.edition output + publisher empty$ + { format.address.organization.date output } + { format.organization "organization" bibinfo.check output + format.address.publisher.date output + } + if$ + format.paper output + format.pages output + format.note output + format.doi output + format.urldate output + format.online.marker output + format.url output + fin.entry + if.url.std.interword.spacing +} + +%% @manual covers two layouts: +%% +%% Print Handbook / Manual: +%% Name of Manual/Handbook, (in Language), x ed., Abbrev. Name of Co., +%% City of Co., State, Year, pp. xxx--xxx. +%% +%% Manual/Handbook (Online): +%% J. K. Author (or Abbrev. Name of Co., City, State, Country). +%% Name of Manual/Handbook, (in Language), x ed. (Year). +%% Accessed: Month Day, Year. [Online]. Available: URL +%% +%% The presence of a url or urldate field switches the entry to the +%% online layout: period-style separators and a parenthesised "(Year)". +FUNCTION {manual} +{ url empty$ urldate empty$ and + { std.status.using.comma } + { std.status.using.period } + if$ + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.book.title "title" output.warn + % Manual (Online) renders "Title, (in Language), x ed. + % (Year)." with commas around "(in Lang)" and "x ed." even though + % the surrounding entry is period-style. Override the title's + % trailing punctuation here so that "(in Lang)" / "x ed." are + % comma-joined to the title. + url empty$ urldate empty$ and + { skip$ } + { punct.comma 'this.status.punct := + space.normal 'this.status.space := + } + if$ + format.in.language output + format.edition output + url empty$ urldate empty$ and + { % Print manual: organization, address, plain year, pages. + format.organization "organization" bibinfo.check output + format.address "address" bibinfo.check output + format.date output + format.pages output + } + { % Online manual: "(Year)." then "Accessed: ..." then [Online]/URL. + format.organization "organization" bibinfo.check output + format.address "address" bibinfo.check output + format.date.electronic output + format.pages output + } + if$ + format.howpublished "howpublished" bibinfo.check output + format.note output + format.doi output + format.urldate output + format.online.marker output + format.url output + fin.entry + if.url.std.interword.spacing +} + +%% Master's thesis (Q. Theses and Dissertations). +%% Basic Format: +%% J. K. Author, "Title of thesis," (in Language), M.S. thesis, +%% Abbrev. Dept., Abbrev. Univ., City, Abbrev. State, Year. +%% [Online]. Available: URL +FUNCTION {mastersthesis} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.in.language output + format.master.thesis.type output.nonnull + format.school "school" bibinfo.warn output + format.address "address" bibinfo.check output + format.date "year" output.warn + format.note output + format.doi output + format.urldate output + format.online.marker output + format.url output + fin.entry + if.url.std.interword.spacing +} + +%% @misc — generic fallback handler, also used as the target of the +%% @preprint / @arxiv aliases. "Preprint arXiv" +%% prescribes: +%% J. K. Author, "Title of paper," (in Language), Year, arXiv:number. +%% The "(in Language)" marker is therefore inserted right after the +%% quoted title; the eprint cluster prints "arXiv:NNNN" via +%% format.eprint. +FUNCTION {misc} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.article.title "title" output.warn + format.in.language output + format.howpublished "howpublished" bibinfo.check output + format.organization "organization" bibinfo.check output + format.address "address" bibinfo.check output + format.pages output + format.date output + format.eprint output + format.note output + format.doi output + format.urldate output + format.online.marker output + format.url output + fin.entry + empty.entry.warn + if.url.std.interword.spacing +} + +%% Year-first electronic date — "(Year, Month Day)" or "(Year)". +%% Used by the @government and @patentonline layouts where the IEEE +%% prescribes year-first parenthesised dates (distinct from the +%% month-first format produced by format.date.electronic). +FUNCTION {format.date.year.first.electronic} +{ month "month" bibinfo.check duplicate$ empty$ + year "year" bibinfo.check duplicate$ empty$ + { swap$ + { pop$ } + { "there's a month but no year in " cite$ * warning$ + pop$ ")" * "(" swap$ * + this.to.prev.status + punct.std 'this.status.punct := + space.normal 'this.status.space := + quote.no 'this.status.quote := + cap.yes 'status.cap := + } + if$ + } + { swap$ + { swap$ pop$ ")" * "(" swap$ * } + { % Both month and year present. Render as "(Year, Month Day)" + % when day is set, or "(Year, Month)" otherwise. + % Stack on entry: [month_val, year_val] (year on top). + day empty$ + { "(" swap$ * ", " * swap$ * ")" * } + { "(" swap$ * ", " * swap$ * " " * day * ")" * } + if$ + } + if$ + this.to.prev.status + punct.std 'this.status.punct := + space.normal 'this.status.space := + quote.no 'this.status.quote := + cap.yes 'status.cap := + } + if$ +} + + +%% Patent inventor formatter — "by Author1 and Author2". +%% Joined to the preceding (title) field with a comma: +%% "Screwless clip mounted computer drive, by D. Williams." +FUNCTION {format.patent.invented.by} +{ author duplicate$ empty$ 'skip$ + { pop$ + author "author" format.names + duplicate$ empty$ 'skip$ + { punct.comma 'prev.status.punct := + space.normal 'prev.status.space := + "by " swap$ * + } + if$ + } + if$ +} + + +%% Patent (L. Patent) +%% Basic Format: +%% J. K. Author, "Title of patent," (in Language), Country Patent xxx, +%% Month Day, Year. +%% The "(in Language)" marker (when supplied) is inserted between the +%% quoted patent title and the "Country Patent xxx" cluster. +FUNCTION {patent} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.article.title output + format.in.language output + format.patent.nationality.type.number output + format.patent.date output + format.note output + format.doi output + format.urldate output + format.online.marker output + format.url output + fin.entry + empty.entry.warn + if.url.std.interword.spacing +} + +FUNCTION {periodical} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.editors output + name.or.dash + format.book.title "title" output.warn + format.series output + format.volume output + format.number output + format.organization "organization" bibinfo.check output + format.date "year" output.warn + format.note output + format.doi output + format.url output + fin.entry + if.url.std.interword.spacing +} + +%% Ph.D. dissertation (Q. Theses and Dissertations). +%% Basic Format: +%% J. K. Author, "Title of dissertation," (in Language), Ph.D. +%% dissertation, Abbrev. Dept., Abbrev. Univ., City, Abbrev. State, +%% Year. [Online]. Available: URL +FUNCTION {phdthesis} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.in.language output + format.phd.thesis.type output.nonnull + format.school "school" bibinfo.warn output + format.address "address" bibinfo.check output + format.date "year" output.warn + format.note output + format.doi output + format.urldate output + format.online.marker output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {proceedings} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.editors output + name.or.dash + format.book.title "title" output.warn + format.series output + format.volume output + format.number output + publisher empty$ + { format.address.organization.date output } + { format.organization "organization" bibinfo.check output + format.address.publisher.date output + } + if$ + format.note output + format.doi output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {standard} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.book.title "title" output.warn + format.howpublished "howpublished" bibinfo.check output + format.organization.institution.standard.type.number output + format.address "address" bibinfo.check output + format.revision output + format.date output + format.note output + format.doi output + format.urldate output + format.online.marker output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {techreport} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.howpublished "howpublished" bibinfo.check output + format.institution "institution" bibinfo.warn output + format.address "address" bibinfo.check output + format.tech.report.number output.nonnull + format.date "year" output.warn + format.note output + format.doi output + format.urldate output + format.online.marker output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {unpublished} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.date output + format.eprint output + format.note "note" output.warn + format.doi output + format.urldate output + format.online.marker output + format.url output + fin.entry + if.url.std.interword.spacing +} + + +%% Social media (T. Websites — "For social media +%% websites (Twitter etc.)"): +%% Basic Format: +%% J. K. Author, "Post Title." Media Title. Accessed Date Accessed. +%% [Online.] Available: URL +%% Three quirks vs. plain @website/@electronic: +%% * a COMMA (not a period) follows the author block, +%% * "Accessed" is NOT followed by a colon, +%% * the period is INSIDE the bracket: "[Online.]" not "[Online].". +FUNCTION {socialmedia} +{ std.status.using.period + start.entry + if.url.alt.interword.spacing + format.authors output + punct.comma 'this.status.punct := + space.normal 'this.status.space := + name.or.dash + format.article.title.electronic output + format.journal.plain output + format.howpublished "howpublished" bibinfo.check output + format.note output + format.urldate.social output + format.online.marker output + format.url output + fin.entry + empty.entry.warn + if.url.std.interword.spacing +} + + +%% Blog (A. Blogs) +%% Basic Format: +%% J. K. Author, "Title of the post," Title of the Blog, Month Day, +%% Year. [Online]. Available: URL +%% Differs from @article only in that the blog source title (journal +%% field) is rendered in roman type, NOT italics. +FUNCTION {blog} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.in.language output + format.journal.plain "journal" bibinfo.check "journal" output.warn + format.volume output + format.number.if.use.for.article output + articleno empty$ + { format.pages output } + { skip$ } + if$ + format.date "year" output.warn + format.articleno output + format.note output + format.doi output + format.urldate output + format.online.marker output + format.url output + fin.entry + if.url.std.interword.spacing +} + + +%% Software (O. Software) +%% Basic Format: +%% J. K. Author. Title of Software. Date Repository or Archive. +%% (version or Year). Publisher Name. Accessed: Date. +%% [Type of Medium]. Global Persistent Identifier. Available: URL +%% Example: +%% D. W. Arning et al. Mixed Mode--Mixed Level Circuit Simulator. +%% (2011). Ngspice. Accessed: Jan. 11, 2019. [Online]. +%% doi:10.5281/zenodo.1234567. Available: http://ngspice.sourceforge.net +%% The (Year) cluster precedes the publisher; the DOI / persistent +%% identifier (read from the `doi` field) is rendered AFTER "[Online]." +%% and BEFORE "Available: URL". +FUNCTION {software} +{ std.status.using.period + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.book.title "title" output.warn + format.repository output + format.version output + format.date.electronic output + format.organization "organization" bibinfo.check output + format.howpublished "howpublished" bibinfo.check output + format.address "address" bibinfo.check output + format.note output + format.urldate output + format.online.marker output + format.doi output + format.url output + fin.entry + empty.entry.warn + if.url.std.interword.spacing +} + + +%% Dataset (E. Datasets) +%% Basic Format: +%% Author, Date, "Title of Dataset," Source. [Online]. Available: URL +%% (or doi: xxx if DOI is used) +FUNCTION {dataset} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.date output + format.article.title "title" output.warn + format.howpublished "howpublished" bibinfo.check output + format.organization "organization" bibinfo.check output + format.address "address" bibinfo.check output + format.note output + format.doi output + format.urldate output + format.online.marker output + format.url output + fin.entry + empty.entry.warn + if.url.std.interword.spacing +} + + +%% Plain (un-quoted, italicised) title used for electronic references +%% whose title is treated as a book/work title rather than as a short +%% piece (websites, social-media posts). Output form: "\emph{Title}". +FUNCTION {format.book.title.electronic} +{ title "title" bibinfo.check + titleraw empty$ + { duplicate$ empty$ 'skip$ 'emphasize if$ } + { titleraw "titleraw" bibinfo.check + emphasize + swap$ " [" swap$ * "]" * * + } + if$ + duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + select.language + } + if$ +} + + +%% Plain title formatter — no quotation marks, no italics. Used for the +%% Conference Paper Online layout where the paper title is set in roman +%% type and terminated by a period (e.g. Taylor's "Assessment: ..."). +FUNCTION {format.title.plain} +{ title "title" bibinfo.check duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + select.language + } + if$ +} + + +%% Conference-name formatter with the leading word "Presented" given a +%% capital "P". Used by @confonline entries where the conference name +%% follows a sentence-ending period: "Title. Presented at .". +%% The location of the conference (address field) is then joined to +%% the conference name with a COMMA, matching +%% "Presented at ., , ." pattern. +FUNCTION {format.presented.booktitle.cap} +{ booktitle "booktitle" bibinfo.check duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + select.language + "Presented at " swap$ * + punct.comma 'this.status.punct := + space.normal 'this.status.space := + cap.status.std + } + if$ +} + + +%% Lecture title formatter — plain text (no italics, no quotes), with +%% the lecture medium type appended in square brackets as part of the +%% title cluster, e.g. "Documenting literature [PowerPoint slides]". +FUNCTION {format.lecture.title} +{ title "title" bibinfo.check duplicate$ empty$ 'skip$ + { medium empty$ + { skip$ } + { " [" * medium * "]" * } + if$ + this.to.prev.status + this.status.std + cap.status.std + select.language + } + if$ +} + + +%% Online video / YouTube (K. Online Video) +%% Basic Format: +%% Video Owner/Creator, Location. Title of Video. (in Language), +%% (Release date). Accessed: Date. [Online Video]. Available: URL +%% Notes: +%% - The video owner/creator is joined to the optional location with +%% a COMMA ("mtaOnline1, Fazi Mosque, U.K.") even though the rest +%% of the entry uses period separators prescribes this +%% mixed style. +%% - The "(in Language)" marker, when supplied, sits between the +%% italicised title and the parenthesised release date. +FUNCTION {video} +{ std.status.using.period + start.entry + if.url.alt.interword.spacing + format.authors output + % Force a comma between Owner/Creator and Location (rather than the + % default period set by std.status.using.period). + punct.comma 'this.status.punct := + space.normal 'this.status.space := + name.or.dash + format.address "address" bibinfo.check output + format.book.title.electronic output + format.in.language output + format.date.electronic output + format.note output + format.urldate output + format.online.marker output + format.url output + fin.entry + empty.entry.warn + if.url.std.interword.spacing +} + + +%% Patent Online (L. Patent — "Patent Online") +%% Basic Format: +%% Name of the invention, by inventor's name. (Year, Month Day). +%% Patent Number. [Online]. Available: URL +%% Example: +%% Screwless clip mounted computer drive, by D. Williams. +%% (2005, Apr. 26). U.S. Patent 6,885,550. [Online]. +%% Available: http://patft.uspto.gov/netacgi/6,885,550 +%% This is a period-style layout: the invention name (plain roman type, +%% no quotes / no italics) leads the entry, followed by the inventor +%% prefixed with "by", a year-first parenthesised date, the patent +%% nationality+number cluster, and finally the [Online]/URL block. +FUNCTION {patentonline} +{ std.status.using.period + start.entry + if.url.alt.interword.spacing + format.title.plain output + format.patent.invented.by output + name.or.dash + format.date.year.first.electronic output + format.patent.nationality.type.number output + format.note output + format.doi output + format.urldate output + format.online.marker output + format.url output + fin.entry + empty.entry.warn + if.url.std.interword.spacing +} + + +%% Conference Paper Online (C. Conference Paper Online) +%% Basic Format: +%% J. K. Author. (Date). Title. (in Language). Presented at Abbreviated +%% Conf. Title. [Online]. Available: URL +%% Period-style separators; the paper title is set in plain roman type +%% (NOT quoted, NOT italicised), and the conference name is preceded by +%% the capitalised phrase "Presented at" rather than the lowercase +%% "presented at the" used by the in-person @presentation type. +FUNCTION {confonline} +{ std.status.using.period + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.date.electronic output + format.title.plain output + format.in.language output + format.presented.booktitle.cap output + format.address "address" bibinfo.check output + format.organization "organization" bibinfo.check output + format.note output + format.doi output + format.urldate output + format.online.marker output + format.url output + fin.entry + empty.entry.warn + if.url.std.interword.spacing +} + + +%% Lecture notes / Lecture online (G. Lectures) +%% Basic Format: +%% J. K. Author. (Year). Title of lecture [Type of Medium]. (in Language), +%% Available: URL +%% Note: IEEE prints the medium marker INSIDE the title cluster (e.g., +%% "[PowerPoint slides]") and omits the leading "[Online]." entirely. +%% We therefore deliberately skip format.online.marker here. The +%% "(in Language)" marker, when supplied, is inserted between the +%% title+medium cluster and "Available: URL", and is always set off by +%% commas (handled inside format.in.language). +FUNCTION {lecture} +{ std.status.using.period + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.date.electronic output + format.lecture.title output + format.in.language output + format.organization "organization" bibinfo.check output + format.note output + format.urldate output + format.url output + fin.entry + empty.entry.warn + if.url.std.interword.spacing +} + + +%% U.S. Government documents (R. U.S. Government Documents) +%% Basic Format: +%% Legislative body. Number of Congress, Session. (Year, Month Day). +%% Title. [Online]. Available: URL +%% The title is italicised (treated as a publication title). The date +%% block uses the YEAR-FIRST parenthesised form "(Year, Month Day)" as +%% prescribed. Distinct from the month-first form used by +%% other electronic types. +FUNCTION {government} +{ std.status.using.period + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.howpublished "howpublished" bibinfo.check output + format.date.year.first.electronic output + format.book.title.electronic "title" output.warn + format.note output + format.urldate output + format.online.marker output + format.url output + fin.entry + empty.entry.warn + if.url.std.interword.spacing +} + + +%% Booktitle formatter for "presented at" conference references. +%% Note: when a paper is *presented* (rather than appearing in proceedings), +%% the conference name is set in roman (not italic). The lead-in word is +%% taken from the user-supplied intype field if present, otherwise from +%% bbl.presented ("presented at"). +FUNCTION {format.presented.booktitle} +{ booktitle "booktitle" bibinfo.check duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + select.language + intype missing$ + { bbl.presented " " * } + { intype " " * } + if$ + swap$ * + cap.status.std + } + if$ +} + + +%% Conference paper PRESENTED at a conference ( +%% Conferences and Conference Proceedings — Conference Paper). +%% Basic Format: +%% J. K. Author, "Title of paper," presented at the Abbreviated Name of +%% Conf., City of Conf., State, Country, Month d--d, Year, Paper number. +FUNCTION {presentation} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.presented.booktitle output + format.series output + format.editors output + format.volume output + format.number output + format.address "address" bibinfo.check output + format.organization "organization" bibinfo.check output + format.date "year" output.warn + format.paper output + format.pages output + format.note output + format.doi output + format.urldate output + format.online.marker output + format.url output + fin.entry + if.url.std.interword.spacing +} + + +% The special entry type which provides the user interface to the +% BST controls +FUNCTION {IEEEtranBSTCTL} +{ is.print.banners.to.terminal + { "** IEEEtran BST control entry " quote$ * cite$ * quote$ * " detected." * + top$ + } + { skip$ } + if$ + CTLuse_article_number + empty$ + { skip$ } + { CTLuse_article_number + yes.no.to.int + 'is.use.number.for.article := + } + if$ + CTLuse_paper + empty$ + { skip$ } + { CTLuse_paper + yes.no.to.int + 'is.use.paper := + } + if$ + CTLuse_url + empty$ + { skip$ } + { CTLuse_url + yes.no.to.int + 'is.use.url := + } + if$ + CTLuse_forced_etal + empty$ + { skip$ } + { CTLuse_forced_etal + yes.no.to.int + 'is.forced.et.al := + } + if$ + CTLmax_names_forced_etal + empty$ + { skip$ } + { CTLmax_names_forced_etal + string.to.integer + 'max.num.names.before.forced.et.al := + } + if$ + CTLnames_show_etal + empty$ + { skip$ } + { CTLnames_show_etal + string.to.integer + 'num.names.shown.with.forced.et.al := + } + if$ + CTLuse_alt_spacing + empty$ + { skip$ } + { CTLuse_alt_spacing + yes.no.to.int + 'is.use.alt.interword.spacing := + } + if$ + CTLalt_stretch_factor + empty$ + { skip$ } + { CTLalt_stretch_factor + 'ALTinterwordstretchfactor := + "\renewcommand{\BIBentryALTinterwordstretchfactor}{" + ALTinterwordstretchfactor * "}" * + write$ newline$ + } + if$ + CTLdash_repeated_names + empty$ + { skip$ } + { CTLdash_repeated_names + yes.no.to.int + 'is.dash.repeated.names := + } + if$ + CTLname_format_string + empty$ + { skip$ } + { CTLname_format_string + 'name.format.string := + } + if$ + CTLname_latex_cmd + empty$ + { skip$ } + { CTLname_latex_cmd + 'name.latex.cmd := + } + if$ + CTLname_url_prefix + missing$ + { skip$ } + { CTLname_url_prefix + 'name.url.prefix := + } + if$ + + + num.names.shown.with.forced.et.al max.num.names.before.forced.et.al > + { "CTLnames_show_etal cannot be greater than CTLmax_names_forced_etal in " cite$ * warning$ + max.num.names.before.forced.et.al 'num.names.shown.with.forced.et.al := + } + { skip$ } + if$ +} + + +%%%%%%%%%%%%%%%%%%% +%% ENTRY ALIASES %% +%%%%%%%%%%%%%%%%%%% +FUNCTION {conference}{inproceedings} +% A conference paper available only online — period-style layout with +% "Presented at ." (capital P). Distinct from @presentation, which +% is the in-person comma-style "presented at the , City, Date" form. +FUNCTION {confpaperonline}{confonline} +FUNCTION {conferenceonline}{confonline} +FUNCTION {online}{electronic} +FUNCTION {internet}{electronic} +FUNCTION {webpage}{electronic} +FUNCTION {website}{electronic} +% NOTE: @socialmedia has its own dedicated handler (defined above) — do +% NOT alias it to @electronic here. +FUNCTION {www}{electronic} +% News articles share the periodical-style layout of @article +% (author, title, source title, date, [Online]. Available: URL). +FUNCTION {news}{article} +FUNCTION {newsarticle}{article} +% A preprint (e.g., arXiv) is rendered through @misc using the +% eprint / eprinttype fields handled by format.eprint. +FUNCTION {preprint}{misc} +FUNCTION {arxiv}{misc} +% Theses with non-IEEE @thesis tag fall back to the doctoral handler; +% users may also use @mastersthesis or @phdthesis directly. +FUNCTION {thesis}{phdthesis} +FUNCTION {dissertation}{phdthesis} +FUNCTION {default.type}{misc} + + + +%%%%%%%%%%%%%%%%%% +%% MAIN PROGRAM %% +%%%%%%%%%%%%%%%%%% + +READ + +EXECUTE {initialize.controls} +EXECUTE {initialize.status.constants} +EXECUTE {banner.message} + +EXECUTE {initialize.longest.label} +ITERATE {longest.label.pass} + +EXECUTE {begin.bib} +ITERATE {call.type$} +EXECUTE {end.bib} + +EXECUTE{completed.message} + + +%% That's all folks, mds. \ No newline at end of file diff --git a/InProgress/StackGraphs_to_CFL_Reachability/article_body.tex b/InProgress/StackGraphs_to_CFL_Reachability/article_body.tex new file mode 100644 index 00000000..18a172f4 --- /dev/null +++ b/InProgress/StackGraphs_to_CFL_Reachability/article_body.tex @@ -0,0 +1,304 @@ +\section{Введение}\label{sec:introduction} + +Разрешение имён -- ключевая функция фронт-энда компилятора и современных сред разработки (IDE). Она применяется для перехода к определению, поддержки рефакторинга, семантической подсветки~\cite{Neron2015,vanAntwerpen2018}. На практике большинство реализаций остаётся привязано к конкретным языкам и носит характер ad hoc решений. Это затрудняет переносимость инструментов и построение формальных доказательств их корректности~\cite{vanAntwerpen2018,Zwaan2023}. В работах по графам областей видимости (Scope Graphs) предложена модель связывания имён, отделяющая структуру AST от правил построения графа областей видимости (Scope Graph) и семантики разрешения имён. Данная модель стала основой для декларативных спецификаций и реализации разрешения имён в коде~\cite{Neron2015,vanAntwerpen2018,Zwaan2023}. Для больших кодовых баз предложены стековые графы (Stack Graphs) с инкрементальным построением графа по файлам и стековым алгоритмом поиска определений~\cite{Creager2023}. + +С точки зрения формализации и алгоритмов, многие задачи анализа программ сводимы к задаче КС-достижимости, лежащей в основе ряда межпроцедурных и иных анализов~\cite{RepsHorwitzSagiv1995,Hellings2015,HeLuXue2024}. Задача КС-достижимости состоит в поиске всех пар вершин в графе с метками на рёбрах, между которыми существует такой путь, что слово составленное из меток его рёбер принадлежит заданному контекстно-свободному языку. Есть основания полагать, что часть шаблонов разрешения имён также может быть сведена к задаче достижимости с контекстно-свободными ограничениями. Целью данной работы является повышение эффективности (выражаемой в меньших затратах по времени и по памяти) механизмов разрешения имён за счёт теоретического и практического исследования сводимости стековых графов к КС-достижимости. + +\section{Стековые графы и КС-достижимость}\label{sec:models} + +В качестве примера рассматривается следующий код на языке программирования Java: + +\begin{figure}[htb] +\centering +\begin{minipage}[t]{0.44\textwidth} +\begin{Verbatim}[fontsize=\small] +# other.java +class Y { + public int x; + public Y() { this.x = 0; } +} +\end{Verbatim} +\end{minipage} +\hfill +\begin{minipage}[t]{0.50\textwidth} +\begin{Verbatim}[fontsize=\small] +# main.java +class HelloWorld { + public static void main() { + Y y; + y.x; + } +} +\end{Verbatim} +\end{minipage} +\caption*{\textbf{Листинг 1.} Пример исходного кода} +\label{lst:java-example} +\end{figure} + +Пусть требуется разрешить ссылку на символ \(x\) в выражении \(y.x\) в \emph{main.java}. \(x\) является полем объекта \(y\), следовательно, необходимо сначала разрешить ссылку \(y\). Определение находится строкой выше и указывает, что \(y\) имеет тип \(Y\). Необходимо разрешить ссылку на символ \(Y\). Определение \(Y\) находится в файле \emph{other.java} и содержит определение \(x\), которое и является решением задачи. + +Для формального обоснования предлагаемого метода вводятся определения стековых графов и задачи КС-достижимости. + +\subsection{Стековые графы}\label{sec:stack-graphs} + +Для решения задачи разрешения имён может применяться модель стековых графов. + +Стековый граф \(G\) является представлением программы \(P\). Программа \(P\) состоит из множества файлов исходного кода \(F_{i}\). Каждый файл исходного кода представим в виде множества синтаксических вершин (вершин синтаксического древа). В данном множестве синтаксических вершин можно выделить два подмножества (возможно пересекающихся): подмножество вершин, отражающих определения, и подмножество вершин, отражающих ссылки в исходном коде. + +Пусть символ \(x\) -- идентификатор из исходного кода, отражающий имя некой сущности в программе (или часть такого имени), либо символ оператора (например, оператор доступа к члену объекта \(.\) или оператор вызова \(()\)). + +Каждая вершина стекового графа \(G\) принадлежит к одному из четырёх типов: + +\begin{enumerate} +\def\labelenumi{\arabic{enumi}.} +\item + Вершина области видимости (Scope node); +\item + Корневая вершина (Root node); +\item + Вершина добавления символа \(x\) на стек (Push node, далее вершина добавления); +\item + Вершина удаления символа \(x\) со стека (Pop node, далее вершина удаления). +\end{enumerate} + +Дополнительно, каждая вершина \(N_{i}\) кроме корневой относится ровно к одному файлу исходного кода \(F_{i}\). Часть вершин стекового графа \(G\) относится к конкретным синтаксическим вершинам данного файла \(F_{i}\). Вершина добавления \(N_{i}\) называется вершиной ссылки, если она относится к синтаксической вершине, отражающей ссылку. Вершина удаления \(N_{i}\) называется вершиной определения, если она относится к синтаксической вершине, отражающей определение. + +Пусть \(E_{G}\) -- множество рёбер стекового графа \(G_{i}\). Каждое ребро стекового графа направлено и соединяет входную вершину \(N_{i}\) с выходной вершиной \(N_{i}'\). Рёбра могут соединять только вершины, принадлежащие одному файлу исходного кода \(F_{i}\)~\cite{Creager2023}. + +Путь \(p\) в стековом графе \(G\) состоит из начальной вершины \(N_{i}\), конечной вершины \(N_{i}'\) и стека символов \(\widehat{x}\). Путь называется завершённым, если начальная вершина пути является вершиной ссылки, конечная вершина пути является вершиной определения и стек символов пути пуст. Каждое разрешение имени в программе \(P\) выразимо в виде завершённого пути в соответствующем данной программе стековом графе \(G\)~\cite{Creager2023}. + +Пустым путём называется путь, не содержащий рёбер. Такой путь создаётся путём поднятия вершины стекового графа. Поднятие вершины добавления кладёт соответствующий ей символ \(x\) на стек символов. Вершина удаления не может быть поднята. Другие вершины дают пустой путь с пустым символьным стеком. + +Любой путь \(p\) может быть расширен путём добавления к нему ребра \(E_{i}\), исходящего из конечной вершины данного пути \(p\). Выходная вершина \(N_{i}'\) этого ребра \(E_{i}\) становится новой конечной вершиной пути \(p\). Символьный стек пути \(p\) меняется в зависимости от новой конечной вершины \(N_{i}'\). Если вершина \(N_{i}'\) является корневой вершиной или вершиной области видимости, то стек символов \(\widehat{x}\) не меняется. Если вершина \(N_{i}'\) является вершиной добавления, то соответствующий ей символ \(x\) кладётся на стек символов \(\widehat{x}\). Если вершина \(N_{i}'\) является вершиной удаления, то расширение пути возможно только в том случае, когда стек символов \(\widehat{x}\) не пуст и на его вершине лежит символ \(x\), которому вершина удаления \(N_{i}'\) соответствует. В таком случае этот символ \(x\) снимается с вершины стека символов \(\widehat{x}\). + +Если конечная вершина пути является корневой вершиной, то данный путь можно расширить до корневой вершины в подграфе любого другого файла (можно сказать, что корневая вершина принадлежит одновременно всем файлам). Это единственный способ проложить путь из одного файла в другой~\cite{Creager2023}. + +На основе определения завершённого пути, способов создания пустого пути и способов расширения пути можно построить алгоритм разрешения имён в стековом графе. + +Пусть дана программа \(P\) и ссылка в данной программе. Требуется найти все определения в программе \(P\), соответствующие данной ссылке. + +Строится стековый граф \(G\), соответствующий программе \(P\). Пустой путь \(p\) создаётся поднятием вершины, соответствующей данной ссылке. Затем от этой вершины выполняется обход в ширину. Очередь ожидающих путей изначально содержит только \(p\). На каждом шаге следующий путь извлекается из очереди, после чего к нему поочерёдно добавляются рёбра, исходящие из его конечной вершины. Если добавление допустимо по описанным выше правилам, новый путь помещается в очередь. Если найденный путь завершён, его конечная вершина соответствует искомому определению~\cite{Creager2023}. + +На рис.~\ref{fig:stack-graph} показан стековый граф для кода из листинга 1. Вершины помещения (\(push\)) и извлечения (\(pop\)) обозначают соответственно добавление указанного символа на вершину стека и снятие верхнего символа при совпадении. Вершины областей видимости (\(scope\)) представляют области видимости. Корневая вершина (\(root\)) обеспечивает переход между файловыми подграфами. Ориентированные рёбра задают допустимые продолжения пути. Символы «.» и «:» введены правилами построения графа для Java: «.» моделирует обращение к члену объекта, а «:» обозначает запрос типа выражения. Зелёным выделен завершённый путь, связывающий ссылку \(x\) в выражении \emph{y.x} с определением поля \(x\) класса \(Y\). + +\begin{figure}[htb] +\centering +\includegraphics[width=0.72\textwidth]{figure1.png} +\caption{Пример стекового графа} +\label{fig:stack-graph} +\end{figure} + +Граф строится из локальных фрагментов, создаваемых по правилам для синтаксических конструкций анализируемого языка (в нашем случае, для Java). Рёбра связывают эти фрагменты через вершины областей видимости в соответствии с правилами разрешения и вложенностью областей. Ссылка \(x\) в выражении \emph{y.x} образует начальную вершину \({push}_{x}\). Доступ к члену объекта добавляет внутреннюю вершину \({push}_{.}\) и направляет поиск к типу объекта \(y\). Для получения типа идентификатора правила Java создают переход через \({push}_{:}\) к ссылке \({push}_{y}\). Объявление \emph{Y y} представлено фрагментом \({pop}_{y}\ \rightarrow \ {pop}_{:}\ \rightarrow \ {push}_{Y}\). Вершина \({pop}_{y}\) сопоставляет ссылку с объявлением переменной, \({pop}_{:}\) завершает запрос её типа, а \({push}_{Y}\) начинает разрешение имени объявленного типа. Через области видимости файла \emph{main.java} и корневую вершину путь переходит в подграф файла \emph{other.java}, где \({pop}_{Y}\) сопоставляет имя типа с объявлением класса. Затем путь входит в область видимости членов класса: \({pop}_{.}\) снимает маркер обращения к члену, а \({pop}_{x}\) сопоставляет исходную ссылку с определением поля. + +Зелёный путь показывает последовательность разрешения. Если вершину стека располагать слева, состояния символьного стека после операций \(push\) и \(pop\) имеют следующий вид: +\[ +\begin{aligned} +\lbrack x\rbrack &\to \lbrack.,x\rbrack \to \lbrack:,.,x\rbrack + \to \lbrack y,:,.,x\rbrack \to \lbrack:,.,x\rbrack \\ +&\to \lbrack.,x\rbrack \to \lbrack Y,.,x\rbrack + \to \lbrack.,x\rbrack \to \lbrack x\rbrack \to \lbrack\rbrack . +\end{aligned} +\] + +Вершины областей видимости и корневая вершина стек не изменяют. Пустой стек после прохождения конечной вершины \({pop}_{x}\) показывает, что путь завершён и связывает ссылку \(x\) с определением поля \(x\) класса \(Y\). + +Числа в вершинах областей видимости являются идентификаторами областей видимости данного файла. Граф на рис.~\ref{fig:stack-graph} визуально сокращён: на схеме показана часть вершин и рёбер полного графа, достаточная для разбора выделенного пути. Полный граф существенно больше из-за дополнительных вершин областей видимости и ответвлений. + +\subsection{Задача КС-достижимости}\label{sec:cfl-reachability} + +Задача КС-достижимости определяется тремя объектами: граф \(G\), алфавит \(\Sigma\) и контекстно-свободный язык \(L\), заданный над алфавитом \(\Sigma\). + +Граф \(G\) состоит из множества вершин \(V\) и множества рёбер \(E\), где \(E\ \subseteq \ V\ \times \ (\Sigma\ \cup \ \{\varepsilon\})\ \times \ V\). Рёбра ориентированы и размечены символами алфавита \(\Sigma\) или меткой \(\varepsilon\). Символы алфавита далее называются терминалами. + +Путь \(p\) в графе представлен последовательностью рёбер \(E_{1}\ \ldots\ E_{n}\). Пути \(p\) соответствует слово \(w_{p}\), образованное последовательной записью меток этих рёбер. Метка \(\varepsilon\) не добавляет символа в слово. + +Пара вершин \((u,\ v)\) графа \(G\) называется КС-достижимой, если существует путь \(p\) из \(u\) в \(v\), слово которого принадлежит языку \(L\). + +Решение задачи КС-достижимости сводится к нахождению всех КС-достижимых пар вершин \((u,\ v)\) графа \(G\)~\cite{MuravevGrigorev2025}. + +\section{Сведение стековых графов к КС-достижимости}\label{sec:conversion} + +В разделе дано формальное описание разработанного метода сведения, указана область его применимости и описано программное средство, созданное для демонстрации метода. + +\subsection{Теоретическое описание сведения}\label{sec:conversion-theory} + +Рассматривается конечный путь \(p_{S}\) = \((N_{1},\ \ldots,\ N_{n})\) в стековом графе \(G_{S}\). Операция, соответствующая начальной вершине, входит в слово пути. Если начальная вершина является вершиной-ссылкой, соответствующий символ помещается на стек. + +Далее рассматривается модель, в которой допустимость пути определяется символьным стеком. Вершины областей видимости и корневая вершина этот стек не изменяют. Корневая вершина обеспечивает переход между файловыми подграфами. + +Множество символов стекового графа обозначается \(X\ = \ \{ x_{i}\ |\ i\ \in \ I\}\). Вершине помещения символа \(x_{i}\) сопоставляется терминал \({push}_{i}\), а вершине извлечения того же символа сопоставляется терминал \({pop}_{i}\). Операция \({push}_{i}\) добавляет \(x_{i}\) к текущему стеку. Операция \({pop}_{i}\) допустима только при наличии \(x_{i}\) на вершине стека и удаляет этот символ. Слово пути образуется последовательностью этих операций. Нейтральные вершины не добавляют символов в слово пути. + +Слова фрагментов пути, оставляющих символьный стек неизменным, описывает нетерминал \(S\): + +\[S \to \varepsilon \mid S\,S \mid {push}_{i}\,S\,{pop}_{i},\qquad i \in I.\] + +Для запросов разрешения имён, рассматриваемых далее, используется стартовый нетерминал \(Q\): + +\[Q \to {push}_{i}\,S\,{pop}_{i},\qquad i \in I.\] + +Эти правила задают контекстно-свободный язык \(L_{S}\). Правило \(S\ \rightarrow \ S\ S\) допускает произвольное число последовательных согласованных фрагментов, а правило с одинаковым индексом \(i\) обеспечивает правильную вложенность операций. К терминалам относятся только \({push}_{i}\) и \({pop}_{i}\). Обозначения \(S\) и \(Q\) являются нетерминалами, а \(\varepsilon\) обозначает пустое слово. + +Пусть \(R\) и \(D\) обозначают множества вершин-ссылок и вершин-определений. При сведении каждой вершине \(r\ \in \ R\) сопоставляется вход \(r_{in}\). Каждой вершине \(d\ \in \ D\) сопоставляется выход \(d_{out}\). В построенной задаче КС-достижимости пара \((r,\ d)\) считается результатом запроса, если существует путь из \(r_{in}\) в \(d_{out}\), слово которого выводится из стартового нетерминала \(Q\). + +В математической записи \(\varepsilon\) обозначает пустое слово. Ребро с меткой \(\varepsilon\) является нейтральным. Прохождение такого ребра не добавляет терминала в слово пути и не изменяет символьный стек. + +При преобразовании обозначения \({push}_{i}\) и \({pop}_{i}\) переносятся с вершин на рёбра. Преобразование выполняется следующим образом. + +\begin{enumerate} +\def\labelenumi{\arabic{enumi}.} +\item + Вершинам помещения и извлечения сопоставляются метки \({push}_{i}\) и \({pop}_{i}\). Вершины областей видимости и корневая вершина остаются нейтральными. +\item + На промежуточном этапе метки могут находиться как на вершинах, так и на рёбрах графа. Нейтральные элементы не добавляют символов в слово пути. +\item + Все исходные рёбра получают нейтральную метку \(\varepsilon\). Прохождение такого ребра не изменяет слово пути. +\item + Нейтральные метки удаляются с вершин областей видимости и с корневой вершины. Удаление этих меток не изменяет слова путей. +\item + Каждая вершина с меткой \({push}_{i}\) заменяется парой вершин без меток \(N_{in}\) и \(N_{out}\). Входящие рёбра перенаправляются в \(N_{in}\). Исходящие рёбра перенаправляются из \(N_{out}\). Между \(N_{in}\) и \(N_{out}\) добавляется ребро с меткой \({push}_{i}\). Каждому исходному пути через заменяемую вершину соответствует единственный путь через созданную пару с той же операцией в той же позиции слова. Если исходная вершина была вершиной ссылки, \(N_{in}\) становится соответствующим входом \(r_{in}\). +\item + Аналогично заменяются вершины с меткой \({pop}_{i}\). Если исходный путь заканчивался в вершине-определении, преобразованный путь заканчивается в соответствующей вершине \(N_{out}\), которая служит выходом \(d_{out}\). +\end{enumerate} + +После преобразования обозначения \({push}_{i}\) и \({pop}_{i}\) существуют только как метки рёбер. Нейтральные рёбра имеют метку \(\varepsilon\). Алфавит терминалов состоит из \({push}_{i}\) и \({pop}_{i}\). Время построения графа составляет \(O(|V|\ + \ |E|)\), поскольку каждая вершина и каждое ребро обрабатываются постоянное число раз. + +Псевдокод описанного алгоритма: + +\begin{Verbatim}[fontsize=\small] +fn stack_graph_to_cfl(G: Graph) -> Graph: + for node in G.nodes: + # Push(x) -> push_x, Pop(x) -> pop_x, + # Root and Scope -> epsilon + node.label = make_node_label(node) + for edge in G.edges: + edge.label = epsilon + for node in G.nodes where node.label == epsilon: + delete node.label + for node in G.nodes where node.label is push_*: + let (N_in, N_out) = G.create_nodes_pair() + redirect_incoming_edges(old_dest: node, new_dest: N_in) + redirect_outgoing_edges(old_src: node, new_src: N_out) + G.create_edge(N_in, N_out, label: node.label) + if G.start_node == node: + G.start_node = N_in + G.delete_node(node) + # То же самое для pop-вершин + return G +\end{Verbatim} + +Пример замены вершины помещения приведён на рис.~\ref{fig:push-before} и~\ref{fig:push-after}. + +\setcounter{figure}{2} +\begin{figure}[htb] +\centering +\begin{minipage}[t]{0.46\textwidth} +\centering +\includegraphics[width=\linewidth]{figure3.png} +\captionof{figure}{Вершина помещения до преобразования} +\label{fig:push-before} +\end{minipage} +\hfill +\begin{minipage}[t]{0.48\textwidth} +\centering +\includegraphics[width=\linewidth]{figure4.png} +\captionof{figure}{Вершина помещения после преобразования} +\label{fig:push-after} +\end{minipage} +\end{figure} + +При разрешении всех ссылок рассматриваются входы \(r_{in}\), соответствующие вершинам-ссылкам. В результат включаются все пары \((r,\ d)\), для которых существует путь из \(r_{in}\) в \(d_{out}\), слово которого выводится из стартового нетерминала \(Q\). + +На рис.~\ref{fig:converted-graph} показан результат сведения графа с рис.~\ref{fig:stack-graph}. Каждая вершина помещения или извлечения заменяется парой вершин \(N_{in}\) и \(N_{out}\) без меток, соединённых ребром с меткой соответствующей операции. Входящие рёбра перенаправляются в \(N_{in}\). Исходящие рёбра перенаправляются из \(N_{out}\). Вершины областей видимости и корневая вершина сохраняются, а исходные рёбра стекового графа получают нейтральную метку \(\varepsilon\). Преобразование сохраняет разветвления, порядок прохождения и последовательность операций пути. + +\begin{figure}[htb] +\centering +\includegraphics[width=0.90\textwidth]{figure5.png} +\caption{Результат сведения стекового графа из рис.~\ref{fig:stack-graph}} +\label{fig:converted-graph} +\end{figure} + +Зелёный путь на рис.~\ref{fig:converted-graph} соответствует зелёному пути на рис.~\ref{fig:stack-graph}. Если опустить нейтральные рёбра, его слово имеет вид + +\[ +\begin{aligned} +{push}_{x} &\to {push}_{.} \to {push}_{:} \to {push}_{y} \to {pop}_{y} \\ +&\to {pop}_{:} \to {push}_{Y} \to {pop}_{Y} \to {pop}_{.} \to {pop}_{x}. +\end{aligned} +\] + +Операции вложены и попарно согласованы: каждая операция \(pop\) снимает верхний совпадающий символ, поэтому слово выводится из \(Q\). Вершина \(N_{in}\) пары, заменившей \({push}_{x}\), соответствует исходной ссылке, а вершина \(N_{out}\) пары, заменившей \({pop}_{x}\), соответствует определению. Тем самым сведение сохраняет связь ссылки \(x\) в выражении \emph{y.x} с определением поля \(x\) класса \(Y\). + +\subsection{Программное средство StackGraphExporter}\label{sec:exporter} + +Для практической реализации описанного выше сведения стековых графов к задаче КС-достижимости разработана утилита командной строки StackGraphExporter~\cite{CoreJustStackGraphExporter} на языке Rust. Программное средство строит стековые графы по файлам исходного кода, выполняет запросы разрешения на стековом графе, сводит стековые графы к задаче КС-достижимости, при необходимости упрощает граф в процессе сведения и создаёт артефакты для последующего запуска внешних решателей. + +В экспериментах библиотека stack-graphs 0.14.1 используется как эталонная реализация. Перед выполнением запросов библиотека для каждого файла строит минимальный набор частичных путей и помещает его в базу. Частичный путь представляет собой фрагмент пути разрешения, который можно состыковать с другими фрагментами. При разрешении ссылки библиотека объединяет совместимые частичные пути в полные пути от ссылки к определениям. + +\section{Результаты экспериментов}\label{sec:experiments} + +Для проверки корректности реализации сведения и измерения эффективности разработанного программного средства проведена серия экспериментов. В разделе приведены постановка экспериментов и результаты. + +\subsection{Постановка экспериментов}\label{sec:experiment-setup} + +В эксперименте отобраны четыре проекта на Java с платформы GitHub: libgdx~\cite{LibGDX}, Shattered Pixel Dungeon~\cite{ShatteredPixelDungeon}, JsonPath~\cite{JaywayJsonPath} и JiaoZi Video Player~\cite{JiaoZiVideoPlayer}. В качестве внешнего решателя использовался CFG\_bench. В рамках каждого эксперимента выполнено 10 запусков. Средние значения времени запроса и потребляемой памяти рассчитаны средствами решателя. Для stack-graphs перед измерениями выполнялись два разогревочных запуска, а среднее значение рассчитывалось по пяти последующим запускам. Пиковое потребление ОЗУ в таблице приведено отдельно для stack-graphs и CFG\_bench. Показатель для stack-graphs измерялся с помощью библиотеки peak\_alloc. В каждом случае выполнялось разрешение всех ссылок в графе. Техническое окружение: ноутбук под управлением Windows 11 Pro, процессор AMD Ryzen 9 8940HX, 32 ГБ ОЗУ DDR5 SDRAM. + +\subsection{Проверка корректности}\label{sec:correctness} + +Для проверки корректности реализации сведения стекового графа к задаче КС-достижимости использовался решатель CFG\_bench. В результате решения задачи КС-достижимости определялось количество найденных пар вершин. Полученное значение сравнивалось с количеством пар, найденных при запросах в стековом графе. + +\subsection{Результаты для запроса всех ссылок в графе}\label{sec:all-references} + +Результаты экспериментов приведены в табл.~\ref{tab:results}. + +\begin{table}[H] +\centering +\caption{Результаты выполнения запросов для всех пар} +\label{tab:results} +\scriptsize +\begin{tblr}{ + width=\textwidth, + colspec={X[2.05,l] X[0.95,c] X[1.10,c] X[0.95,c] X[1.10,c]}, + hlines, vlines, + row{1}={font=\bfseries,halign=c,valign=m}, + column{1}={font=\bfseries,valign=m}, + cells={valign=m}, + rowsep=2pt, + colsep=3pt, +} +Проект & libgdx & Shattered Pixel Dungeon & JsonPath & JiaoZi Video Player \\ +Время, стековый граф & 278 с & -- & 2,6 с & 1,13 с \\ +Память, стековый граф & 27 ГБ & -- & 3,7 ГБ & 2,1 ГБ \\ +Время построения КС-графа & 8 с & 3,8 с & 39 мс & 18 мс \\ +Время построения КС-графа с упрощением & 38 с & 31 с & 0,34 с & 28 мс \\ +Время, CFG\_bench & -- & -- & 6,9 с & 1,67 с \\ +Время, CFG\_bench с упрощением & 7 с & 1,3 с & 0,28 с & 28 мс \\ +Память, CFG\_bench & -- & -- & 1,3 ГБ & 239 МБ \\ +Память, CFG\_bench с упрощением & 1,23 ГБ & 227 МБ & 38 МБ & 14 МБ +\end{tblr} +\end{table} + +Примечания к табл.~\ref{tab:results}. + +\begin{enumerate} +\def\labelenumi{\arabic{enumi}.} +\item + Пропуски в таблице обозначают неудавшиеся запуски измерений. Как правило, решателю не хватало доступной оперативной памяти. +\item + Для реализации stack-graphs время указано как сумма времени построения базы частичных путей и времени выполнения запроса после её построения. +\item + Для проекта libgdx запрос в стековом графе был разбит на части по 32 768 начальных вершин. Без разбиения большинство запусков завершалось ошибкой выделения памяти. В нескольких успешных запусках время выполнения без разбиения превышало время выполнения с разбиением на 30--40\%. Для Shattered Pixel Dungeon запрос всех пар (ссылка, определение) не удалось завершить даже при обработке по одной начальной вершине. +\end{enumerate} + +Совместное использование упрощения и CFG\_bench при разрешении всех ссылок сократило время выполнения запросов. Для Shattered Pixel Dungeon все ссылки удалось разрешить только при использовании CFG\_bench с упрощением. Для остальных трёх проектов суммарное время выполнения уменьшилось на 76--95\% по сравнению со stack-graphs. Пиковое потребление памяти при использовании CFG\_bench было на 95--99\% ниже, чем при использовании stack-graphs. + +\section{Выводы и направления дальнейших исследований}\label{sec:conclusion} + +В рамках работы обоснована перспективность применения КС-достижимости к задаче абстрактного разрешения имён. КС-достижимость применяется в смежных областях, в том числе в межпроцедурном анализе указателей. Для КС-достижимости получены теоретические результаты и разработаны оптимизированные реализации. Выбор стековых графов в качестве основы сведения обусловлен сходством двух моделей: в обоих случаях выполняется поиск путей в графе с ограничениями. + +Формально выведен способ сведения стековых графов, в которых ограничения пути задаются символьным стеком, к задаче КС-достижимости. Сложность сведения составляет \(O(|V|\ + \ |E|)\), где \(|V|\) обозначает число вершин, а \(|E|\) обозначает число рёбер стекового графа. Как показано в разд. 3.2, преобразование сохраняет концы и слово каждого конечного пути. + +Разработан и реализован программный инструмент StackGraphExporter, позволяющий автоматически строить стековые графы по исходному коду на Java, выполнять запросы разрешения, преобразовывать стековый граф в задачу КС-достижимости, применять эвристики упрощения в процессе сведения и создавать артефакты для запуска внешнего решателя CFG\_bench. + +В рамках разработанного программного инструмента экспериментально проверена корректность сведения и исследована эффективность предложенных эвристик упрощения графа. Максимальное сокращение составило 79\% для вершин КС-графа и 32\% для рёбер. Для трёх проектов совместное использование упрощения и CFG\_bench при разрешении всех ссылок сократило суммарное время выполнения на 76--95\% и пиковое потребление памяти на 95--99\% по сравнению со stack-graphs. + +К направлениям дальнейших исследований относятся разработка инкрементального обновления задачи КС-достижимости при изменении части файлов исходного кода, исследование возможности переиспользования результатов запросов и предвычисления путей для подграфов на уровне решателя КС-достижимости. Также представляют интерес разработка модели использования КС-достижимости без промежуточного стекового графа и оптимизация решателей КС-достижимости для разрешения имён. diff --git a/InProgress/StackGraphs_to_CFL_Reachability/figure1.png b/InProgress/StackGraphs_to_CFL_Reachability/figure1.png new file mode 100644 index 00000000..7b41110d Binary files /dev/null and b/InProgress/StackGraphs_to_CFL_Reachability/figure1.png differ diff --git a/InProgress/StackGraphs_to_CFL_Reachability/figure3.png b/InProgress/StackGraphs_to_CFL_Reachability/figure3.png new file mode 100644 index 00000000..472261a0 Binary files /dev/null and b/InProgress/StackGraphs_to_CFL_Reachability/figure3.png differ diff --git a/InProgress/StackGraphs_to_CFL_Reachability/figure4.png b/InProgress/StackGraphs_to_CFL_Reachability/figure4.png new file mode 100644 index 00000000..67859fcf Binary files /dev/null and b/InProgress/StackGraphs_to_CFL_Reachability/figure4.png differ diff --git a/InProgress/StackGraphs_to_CFL_Reachability/figure5.png b/InProgress/StackGraphs_to_CFL_Reachability/figure5.png new file mode 100644 index 00000000..0d089c01 Binary files /dev/null and b/InProgress/StackGraphs_to_CFL_Reachability/figure5.png differ diff --git a/InProgress/StackGraphs_to_CFL_Reachability/images/cc-by.png b/InProgress/StackGraphs_to_CFL_Reachability/images/cc-by.png new file mode 100644 index 00000000..c8473a24 Binary files /dev/null and b/InProgress/StackGraphs_to_CFL_Reachability/images/cc-by.png differ diff --git a/InProgress/StackGraphs_to_CFL_Reachability/kioj6.cls b/InProgress/StackGraphs_to_CFL_Reachability/kioj6.cls new file mode 100644 index 00000000..5cbbfd6a --- /dev/null +++ b/InProgress/StackGraphs_to_CFL_Reachability/kioj6.cls @@ -0,0 +1,1510 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% %%% +%%% Document class for preparing an article for publication %%% +%%% in the Computer Tools in Education journal , %%% +%%% http://cte.eltech.ru/ojs %%% +%%% using LaTeX2e %%% +%%% %%% +%%% Copyright (C) 2026 by the center for informatization of Education %%% +%%% "KIO", all rights reserved. %%% +%%% %%% +%%% This file can be redistributed and/or modified under the terms %%% +%%% of the LaTeX Project Public License (lppl). %%% +%%% %%% +%%% The work is based on the Style for the journal Condensed %%% +%%% Matter Physics (https://ctan.org/pkg/cmpj) %%% +%%% %%% +%%% Please report errors to: Maksim Subbotin %%% +%%% mosubbotin@etu.ru %%% +%%% %%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\NeedsTeXFormat{LaTeX2e} + +% А. Б. Иванов1, должность, orcid (если есть) +% Б. П. Петров1,2, должность, orcid (если есть) +% 1. Полное наименование организации, адрес, город, индекс, страна +% 2. Полное наименование организации, адрес, город, индекс, страна +% Цифры 1 и 2 - это верхние индексы, как у нас и было. Если автор один, индекс также нужен. +% +\RequirePackage{iftex} +\ProvidesClass{kioj6}[2026/04/07 The KIO and CAM journals class] +\def\filename{kioj6.cls} +\def\fileversion{5.00} +\def\filedate{2026/04/07} +\immediate\write32{This is '\filename' v\fileversion \space <\filedate> ^^J% + the KIO and CTE journals class} +\newif\if@firstpage +\@firstpagetrue + +\ifpdftex + \RequirePackage{cmap} % pdf copy\paste + search package +\fi + +% Options ==== + +%eqsecnum: new numbering of formulae in each section +\def\eqsecnum{% + \@addtoreset{equation}{section} % + \def\theequation{\ifnum \c@section>\z@ \thesection.\fi \@arabic\c@equation}% +} + +\DeclareOption{eqsecnum}{\eqsecnum} + +\DeclareOption{noimages}{\def\@noimages{}} + +\newif\if@englishversion +\@englishversionfalse + +% Открытый флаг (без @) — доступен из main.tex как \ifenglishpaper. Зеркалит \if@englishversion. +\newif\ifenglishpaper +\englishpaperfalse + +\newcommand{\englishversion}{% + \@englishversiontrue\englishpapertrue + \renewcommand{\refname}{References}% + \renewcommand{\bibname}{References}% +} +\newcommand{\russianversion}{% + \@englishversionfalse\englishpaperfalse + \renewcommand{\refname}{Список литературы}% + \renewcommand{\bibname}{Список литературы}% +} + +% Переключение языка отрисовки на противоположный (используется в translatedpart). +% Меняется ТОЛЬКО \if@englishversion (текущий контекст рендера). +% \ifenglishpaper остаётся равным выбранному пользователем языку статьи — +% это нужно колонтитулам, которые должны быть постоянны на всех страницах. +\def\@flip@englishversion{% + \if@englishversion + \@englishversionfalse + \else + \@englishversiontrue + \fi +} + +% font options + +\def\kio@sf{cmss} + +\def\lat@sf{\kio@sf} +\def\cyr@sf{\kio@sf} +\def\Hv@scale{0.889} +\def\Pr@scale{0.889} +\def\cmpj@sf{} + +\def\cmpj@sf@helvet{ + %P%\IfFileExists{t1phv.fd}{ + \IfFileExists{t2aphv.fd}{ + \def\lat@sf{phv} + }{ + \def\lat@sf{\kio@sf} + } + \IfFileExists{t2appr.fd}{ + \def\cyr@sf{ppr} + }{ + \def\cyr@sf{\kio@sf} + } +} + +\def\cmpj@sf@droid{ +\ifpdftex +\RequirePackage{fourier} +\fi +\ifxetex +\RequirePackage{fourier-otf} +\fi + +%\RequirePackage{txfonts} +%\IfFileExists{omltxmi.fd}{\re@DeclareMathSymbol{\varkappa}{\mathord}{AMSb}{123}}{} +\RequirePackage[default,scale=0.86]{droidserif} +\RequirePackage[defaultsans,scale=0.86]{droidsans} +\RequirePackage[defaultmono,scale=0.86]{droidsansmono} +\def\lat@sf{droidsans} +\def\cyr@sf{droidsans} +} + +\DeclareOption{droid}{\let\cmpj@sf\cmpj@sf@droid} + +\DeclareOption{helvet}{\let\cmpj@sf\cmpj@sf@helvet} + +\DeclareOption{cm}{\def\cmpj@sf{}} + +%Two languages +% \@lang{}{} и \@langrev — отдают вариант для текущего языка отрисовки. +% \if@englishversion инвертируется в \translatedpart, поэтому одна проверка покрывает все случаи. + +\newcommand\@lang[2]{\if@englishversion#2\else#1\fi} +\newcommand\@langrev[2]{\if@englishversion#2\else#1\fi} +\newcommand\@unreverselang[1]{#1} + +\DeclareOption{english}{ + \def\@english{} + \@englishversiontrue + \englishpapertrue +} +\DeclareOption{authorsinfo}{ + \def\need@authors@info{} +} + +% nocopyright option + +\def\@@copyright{\copyright} +\def\copyright@size{\small} +\def\copyright@author{\@author\cp@issue@year} +\def\copyright@journal{\@unreverselang{\copyright\space\MakeTextUppercase{\journal@type}. \textnumero\issue@number, \issue@year}\@lang{ \space г.}{}} +\def\authorcopyright{\@ifnextchar[ + \iauthorcopyright{\iauthorcopyright[\small]}} +\def\iauthorcopyright[#1]#2{\gdef\copyright@size{#1} + \gdef\copyright@author{#2}} + +\DeclareOption{nocopyright}{\def\@@copyright{}\authorcopyright{}} + +% Forward unknown options to the underlying article class. +\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}} + +\ExecuteOptions{droid} + +\ProcessOptions\relax + +% Load article with our enforced defaults. Any options the user passed to +% \documentclass (e.g. eqsecnum, authorsinfo) that are NOT among the local +% options above were forwarded to article by \DeclareOption*. +\LoadClass[intlimits,twoside,a4paper,11pt]{article} + +\ifpdftex + \RequirePackage[T2A]{fontenc} +\fi +\@lang{ + \RequirePackage[english,russian]{babel} +}{ + \RequirePackage[russian,english]{babel} +} +\RequirePackage{fancyhdr} +\RequirePackage{graphicx} +\@ifundefined{@noimages}{}{\renewcommand{\includegraphics}[2][]{\fbox{\detokenize{#2}}}} +\RequirePackage{ifthen} +\RequirePackage{textcase} +\RequirePackage{setspace} +\RequirePackage{varwidth} +\RequirePackage[pdfstartview=FitH,colorlinks=true,urlcolor=Blue,citecolor=Green,linkcolor=red]{hyperref} +\RequirePackage{url} +%\RequirePackage{doi} +\RequirePackage[dvipsnames]{xcolor} % +\RequirePackage{float} +\RequirePackage[tableposition=top,labelfont={bf,sf,small},font=small,skip=4mm,labelsep=period]{caption} +\RequirePackage{subcaption} +\RequirePackage[misc]{ifsym} +\RequirePackage{microtype} +\RequirePackage[resetlabels]{multibib} + +\def\asbuk#1{\expandafter\@asbuk\csname c@#1\endcsname} +\def\@asbuk#1{\ifcase#1\or а\or б\or в\or г\or д\or е\or ё\or ж\or з\or и\or й\or к\or л\or м\or н\or о\or п\or р\or с\or т\or у\or ф\or х\or ц\or ч\or ш\or щ\or ъ\or ы\or ь\or э\or ю\or я\fi} + +% Подписи рисунков, таблиц и нумерация подрисунков — выбираются по языку отрисовки. +\renewcommand\thesubfigure{\@lang{\asbuk{subfigure}}{\alph{subfigure}}} +\AtBeginDocument{% + \renewcommand{\figurename}{\@lang{Рис.}{Fig.}}% + \renewcommand{\tablename}{\@lang{Табл.}{Table}}% +} + +\newcommand\kioabstractname{\@langrev{Аннотация}{Abstract}} +\newcommand\keywordsname{\@langrev{Ключевые слова}{Keywords}} +\newcommand\citationname{\@langrev{Цитирование}{Citation}} +\newcommand\acknowledgementsname{\@langrev{Благодарности}{Acknowledgements}} + +\urlstyle{same} + +\cmpj@sf + +\def\hv@sf{\sffamily\upshape} + +% remove lists spacing + +\def\remove@lists@spacings{ + \let\oldenumerate\enumerate + \renewcommand{\enumerate}{ + \oldenumerate + \setlength{\itemsep}{0pt} + \setlength{\parskip}{0pt} + \setlength{\parsep}{0pt} + \setlength{\topsep}{0pt} + \setlength{\partopsep}{0pt} + } + + \let\olditemize\itemize + \renewcommand{\itemize}{ + \olditemize + \setlength{\topsep}{0pt} + \setlength{\itemsep}{0pt} + \setlength{\parskip}{0pt} + \setlength{\parsep}{0pt} + \setlength{\partopsep}{0pt} + } +} +\remove@lists@spacings + +%% Настройка заголовка %% + + +\renewcommand\section{\@startsection {section}{1}{\z@}% + {-3.5ex \@plus -1ex \@minus -.2ex}% + {2.3ex \@plus.2ex}% + {\normalfont\large\hv@sf\bfseries\mathversion{bold}\centering\MakeUppercase}} +\renewcommand\subsection{\@startsection{subsection}{2}{\z@}% + {-3.25ex\@plus -1ex \@minus -.2ex}% + {1.5ex \@plus .2ex}% + {\normalfont\large\hv@sf\bfseries\mathversion{bold}}} +\renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}% + {-3.25ex\@plus -1ex \@minus -.2ex}% + {1.5ex \@plus .2ex}% + {\normalfont\normalsize\hv@sf\bfseries\mathversion{bold}}} +\renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}% + {3.25ex \@plus1ex \@minus.2ex}% + {-1em}% + {\normalfont\normalsize\hv@sf\bfseries\mathversion{bold}}} +\renewcommand\subparagraph{\@startsection{subparagraph}{5}{\parindent}% + {3.25ex \@plus1ex \@minus .2ex}% + {-1em}% + {\normalfont\normalsize\hv@sf\bfseries\mathversion{bold}}} + +\def\@seccntformat#1{\csname the#1\endcsname.\hspace{0.5em}} + +%% penalties + +\widowpenalty=0 +\clubpenalty=0 +\emergencystretch=3em + +\def\relax@with@arg#1{\relax} +\def\@affil#1{\textsuperscript{#1}} +\let\affil\@affil +\def\affiliation@footnotes{} +\def\affiliation#1#2{\g@addto@macro\affiliation@footnotes{ +\textsuperscript{#1}#2\par +}} + +% Английские аффилиации +\def\affiliationen#1#2{\g@addto@macro\affiliation@footnotes@en{ + \textsuperscript{#1}#2\par +}} + +% Переменная для английских аффилиации +\def\affiliation@footnotes@en{} + +%% Generic helpers for iterating over authors 1..10 (\author@i holds the index). + +\def\@author@indices{1,2,3,4,5,6,7,8,9,10} + +% \@authors@iter{}{}: run for every author that is defined. +\long\def\@authors@iter#1#2{% + \@for\author@i:=\@author@indices\do{% + \ifcsname author\author@i#1\endcsname#2\fi% + }% +} + +% Comma-separated list of \csname author\endcsname. +% Expandable (safe inside \edef): walks indices 1..10 carrying the current separator. +\def\@authors@split@by@comma#1{\@authors@walk{1}{#1}{}} +\def\@authors@walk#1#2#3{% + \ifnum#1>10 \else + \@ifundefined{author#1#2}% + {\expandafter\@authors@walk\expandafter{\the\numexpr#1+1\relax}{#2}{#3}}% + {#3\csname author#1#2\endcsname\expandafter\@authors@walk\expandafter{\the\numexpr#1+1\relax}{#2}{, }}% + \fi +} + +\def\@authors@truncated#1#2#3#4{% + \count@\z@ + \@authors@iter{#3}{\advance\count@\@ne}% + \edef\@authors@truncated@total{\the\count@}% + \ifnum\@authors@truncated@total>#1 + \@tempcnta#2\relax + \else + \@tempcnta\@authors@truncated@total\relax + \fi + \count@\z@\let\@author@sep\@empty + \@authors@iter{#3}{% + \advance\count@\@ne + \ifnum\count@>\@tempcnta\else + \@author@sep + \csname author\author@i#3\endcsname + \def\@author@sep{, }% + \fi + }% + \ifnum\@authors@truncated@total>#1 #4\fi +} + +\def\authors@short@split@by@comma{\@authors@split@by@comma{@short}} +\def\authors@short@first@lang@split@by@comma{\@authors@split@by@comma{@short@first@lang}} +\def\authors@short@first@lang@split@by@comma@remove@affil{% +\global\let\@@affil\affil% +\global\let\affil\relax@with@arg% +\authors@short@first@lang@split@by@comma% +\global\let\affil\@@affil% +} + +\def\authors@short@en@split@by@comma{\@authors@split@by@comma{@short@en}} +\def\authors@short@truncated{\@authors@truncated{4}{3}{@short}{\ и~др.}} +\def\authors@short@en@truncated{\@authors@truncated{4}{3}{@short@en}{\ et al.}} + +\def\@Letter{{\footnotesize \Letter}} + +%% Authors information +\def\authors@all@info{% + \def\authorinfo##1{ + \setstretch{0.9} + \if@englishversion + \csname author##1@short@en\endcsname% + \else + \csname author##1@short\endcsname% + \fi + \ifcsname author##1@email\endcsname% + \hspace{0.25em}% + \ifcsname author##1@email@recepient\endcsname% + \hspace{0.25em}\@Letter\ % <-- Добавлен пробел после конвертика + \fi% + \hspace{0.25em}\href{mailto:\csname author##1@email\endcsname}{\csname author##1@email\endcsname}% + \fi + \ifcsname author##1@orcid\endcsname% + , \href{https://\csname author##1@orcid\endcsname}{\csname author##1@orcid\endcsname}% + \fi + } + \@authors@iter{@short}{\authorinfo{\author@i}\par}% +} + +% Верхний колонтитул + +% Для русских авторов +\def\authors@names@only@ru{% + \begingroup + \def\affil##1{}% + \@authors@truncated{4}{3}{@short}{\ и~др.}% + \endgroup +} + +% Для английских авторов +\def\authors@names@only@en{% + \begingroup + \def\affil##1{}% + \ifcsname author1@short@en\endcsname + \@authors@truncated{4}{3}{@short@en}{\ et al.}% + \else + \@authors@truncated{4}{3}{@short}{\ et al.}% + \fi + \endgroup +} + + +% Title + +\newcommand\firstpage{\label{first@page}} +\newcommand\lastpage{\label{last@page}} + +% Сноска без маркера на первой странице — выходные данные на «противоположном» +% языке (английская статья → русская сноска, русская статья → английская сноска). +% Три строки: авторы, полное название, журнал/год/номер/страницы. +\def\@firstpage@translation@citation{% + \begingroup + \def\@thefnmark{}% + \def\@makefnmark{}% + \long\def\@makefntext##1{\noindent##1}% + \@footnotetext{% + \if@englishversion + % Английская статья → русская сноска. + \temp@authors\\ + \@title.\\ + \copyright\ \journal@type@ru, \issue@year. № \issue@number. С. \pages@span.% + \else + % Русская статья → английская сноска. + \temp@authors@en\\ + \@title@en.\\ + \copyright\ \journal@type@en, \issue@year. No \issue@number. P. \pages@span.% + \fi + }% + \endgroup +} + +\renewcommand\maketitle{\par + \@firstpagetrue % Устанавливаем флаг первой страницы + \gdef\@author{\mbox\authors@short@split@by@comma} + + \ifcsname fancy@title\endcsname + \setarticleheader{\fancy@title}{\fancy@title@en} + \else + \setarticleheader{\@title}{\@title@en} + \fi + + \gdef\temp@authors{\begingroup\let\affil\@gobble\authors@short@truncated\endgroup} + \gdef\temp@authors@en{\begingroup\let\affil\@gobble\authors@short@en@truncated\endgroup} + + % разные авторы для русского и английского + \setauthorsheader{\authors@names@only@ru}{\authors@names@only@en} + + \begingroup + \renewcommand\thefootnote{\@fnsymbol\c@footnote}% + \def\@makefnmark{\rlap{\@textsuperscript{\normalfont\@thefnmark}}}% + \long\def\@makefntext##1{\parindent 1em\noindent + \hb@xt@1.8em{% + \hss\@textsuperscript{\normalfont\@thefnmark}}##1}% + \global\@topnum\z@ % Prevents figures from going at top of page + \@maketitle + \@firstpage@translation@citation % выходные данные на противоположном языке + \thispagestyle{firstpagestyle} % Специальный стиль для первой страницы + \global\@firstpagefalse % Сбрасываем флаг + \pagestyle{mainstyle} % Устанавливаем основной стиль для следующих страниц + \@thanks + \endgroup + \setcounter{footnote}{0}% +% \global\let\affil\relax@with@arg + \global\let\thanks\relax +% \global\let\maketitle\relax + \global\let\@thanks\@empty + \firstpage + \@firstpagefalse % После создания титульной страницы сбрасываем флаг +} + \setcounter{footnote}{0}% + % \global\let\affil\relax@with@arg + \global\let\thanks\relax +% \global\let\maketitle\relax + \global\let\@thanks\@empty +% \firstpage + +\def\@title{} +\def\@author{} +\def\@address{} +\def\fancy@header@title{FANCY@HEADER@TITLE} +\def\journal@type{} +\def\issue@year{????}% +\def\issue@number{?}% +\def\journal@section@img{kio-logo-col.png} +\def\journal@section@name{????} +\def\cp@issue@year{} +\expandafter\def\csname author1@short\endcsname{???} +\expandafter\def\csname author1@full\endcsname{????} +\expandafter\def\csname author1@addr\endcsname{??????} +\expandafter\def\csname author1@email\endcsname{???@???} +\def\journal@type@ru{????} +\def\journal@type@en{????} + +\def\issue#1#2#3{ + \def\issue@year{#1}% + \def\cp@issue@year{,\space#1}% + \def\issue@number{#2}% + \def\@section@image@path@prefix{"images/"} + \ifthenelse{\equal{edu}{#3}}{% + \def\journal@type{\@langrev{Компьютерные инструменты в образовании}{Computer Tools in Education}}% + \def\journal@type@ru{{\selectlanguage{russian}Компьютерные инструменты в образовании}}% + \def\journal@type@en{Computer Tools in Education}% + }{% + \ifthenelse{\equal{cam}{#3}}{% + \def\journal@type{\@langrev{Компьютерная математика}{Computer Assisted Mathematics}}% + \def\journal@type@ru{{\selectlanguage{russian}Компьютерная математика}}% + \def\journal@type@en{Computer Assisted Mathematics}% + \def\@section@image@path@prefix{cam-}% + }{% + \def\journal@type{\@langrev{Компьютерные инструменты в школе}{Computer Tools at Schools}}% + }% + }% + \ifthenelse{\equal{cam}{#3}}{% + \definecolor{rulercolor}{RGB}{32,63,153} + }{% + \definecolor{rulercolor}{RGB}{145,56,40} + }% +} + +\newif\if@in@translatedpart +\@in@translatedpartfalse + +% Текущий тип статьи: язык определяется флагом \if@englishversion. +% Внутри \translatedpart флаг инвертируется, поэтому проверка одна. +\def\article@type@current{% + \if@englishversion\article@type@en\else\article@type@ru\fi% +} + +\def\article@type@ru{{\selectlanguage{russian}Оригинальное исследование}} +\def\article@type@en{Research article} + +\newcommand{\articletr}[2]{% + \gdef\article@type@ru{#1}% + \gdef\article@type@en{#2}% +} +% Команда для выбора типа статьи +\newcommand{\articletype}[1]{% + \ifcase#1\relax + \or % 1 + \gdef\article@type@ru{{\selectlanguage{russian}Оригинальное исследование}}% + \gdef\article@type@en{Research article}% + \or % 2 + \gdef\article@type@ru{{\selectlanguage{russian}Обзорная статья}}% + \gdef\article@type@en{Review article}% + \or % 3 + \gdef\article@type@ru{{\selectlanguage{russian}Материалы конференции}}% + \gdef\article@type@en{Conference paper}% + \or % 4 + \gdef\article@type@ru{{\selectlanguage{russian}Редакционная статья}}% + \gdef\article@type@en{Editorial article}% + \or % 5 + \gdef\article@type@ru{{\selectlanguage{russian}Дискуссионная статья}}% + \gdef\article@type@en{Discussion article}% + \or % 6 + \gdef\article@type@ru{{\selectlanguage{russian}Краткое сообщение}}% + \gdef\article@type@en{Short Communication}% + \fi +} + +%\def\article@type{} +%\def\articletype#1{\def\article@type{#1}} +\def\kio@page{\bf \arabic{page}} +\def\doinumber#1{\def\doi@number{#1}} +% Лицензия не подключена +\def\license#1{\def\@license{#1}} +\def\@license{CC~BY~4.0} +\def\udknumber#1{\def\udk@number{#1}} + +\def\bibdoi{\doi} +\def\arxiv#1{\href{http://arxiv.org/abs/#1}{arXiv:#1}} + +\def\journalsection#1{% + \def\@sectionwithimage{true} % Флаг, что раздел С изображением + \def\journal@section@id{#1} + \ifthenelse{\equal{informatics}{#1}}{% + \def\journal@section@name{\@lang{ИНФОРМАТИКА}{COMPUTER SCIENCE}}% + \setsectionheader{{\selectlanguage{russian}ИНФОРМАТИКА}}{COMPUTER SCIENCE}% <-- ДОБАВИТЬ + }{% + \ifthenelse{\equal{information-systems}{#1}}{% + \def\journal@section@name{\@lang{ИНФОРМАЦИОННЫЕ СИСТЕМЫ}{INFORMATION SYSTEMS}}% + \setsectionheader{{\selectlanguage{russian}ИНФОРМАЦИОННЫЕ СИСТЕМЫ}}{INFORMATION SYSTEMS}% <-- ДОБАВИТЬ + }{% + \ifthenelse{\equal{software-engineering}{#1}}{% + \def\journal@section@name{\@lang{ИНЖЕНЕРИЯ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ}{SOFTWARE ENGINEERING}}% + \setsectionheader{{\selectlanguage{russian}ИНЖЕНЕРИЯ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ}}{SOFTWARE ENGINEERING}% <-- ДОБАВИТЬ + }{% + \ifthenelse{\equal{computer-in-education}{#1}}{% + \def\journal@section@name{\@lang{КОМПЬЮТЕР В УЧЕБНОМ ПРОЦЕССЕ}{COMPUTER IN EDUCATION}}% + \setsectionheader{{\selectlanguage{russian}КОМПЬЮТЕР В УЧЕБНОМ ПРОЦЕССЕ}}{COMPUTER IN EDUCATION}% <-- ДОБАВИТЬ + }{% + \ifthenelse{\equal{popular-science-articles}{#1}}{% + \def\journal@section@name{\@lang{НАУЧНО-ПОПУЛЯРНЫЕ СТАТЬИ}{POPULAR-SCIENCE ARTICLES}}% + \setsectionheader{{\selectlanguage{russian}НАУЧНО-ПОПУЛЯРНЫЕ СТАТЬИ}}{POPULAR-SCIENCE ARTICLES}% <-- ДОБАВИТЬ + }{% + \ifthenelse{\equal{programming-practice}{#1}}{% + \def\journal@section@name{\@lang{ПРАКТИКА ПРОГРАММИРОВАНИЯ}{PROGRAMMING PRACTICE}}% + \setsectionheader{{\selectlanguage{russian}ПРАКТИКА ПРОГРАММИРОВАНИЯ}}{PROGRAMMING PRACTICE}% <-- ДОБАВИТЬ + }{% + \ifthenelse{\equal{editorial-column}{#1}}{% + \def\journal@section@name{\@lang{КОЛОНКА РЕДАКТОРА}{EDITORIAL COLUMN}}% + \setsectionheader{{\selectlanguage{russian}КОЛОНКА РЕДАКТОРА}}{EDITORIAL COLUMN}% <-- ДОБАВИТЬ + }{% + \ifthenelse{\equal{specialists-training-new-teaching-methods}{#1}}{% + \def\journal@section@name{\@lang{ПОДГОТОВКА СПЕЦИАЛИСТОВ: новые методы обучения}{SPECIALISTS TRAINING: new teaching methods}}% + \setsectionheader{{\selectlanguage{russian}ПОДГОТОВКА СПЕЦИАЛИСТОВ: новые методы обучения}}{SPECIALISTS TRAINING: new teaching methods}% <-- ДОБАВИТЬ + }{% + \ifthenelse{\equal{specialists-training-training-programs}{#1}}{% + \def\journal@section@name{\@lang{ПОДГОТОВКА СПЕЦИАЛИСТОВ: программы обучения}{SPECIALISTS TRAINING: training programs}}% + \setsectionheader{{\selectlanguage{russian}ПОДГОТОВКА СПЕЦИАЛИСТОВ: программы обучения}}{SPECIALISTS TRAINING: training programs}% + }{% + \ifthenelse{\equal{specialists-training-professional-standards}{#1}}{% + \def\journal@section@name{\@lang{ПОДГОТОВКА СПЕЦИАЛИСТОВ: профессиональные стандарты}{SPECIALISTS TRAINING: professional standards}}% + \setsectionheader{{\selectlanguage{russian}ПОДГОТОВКА СПЕЦИАЛИСТОВ: профессиональные стандарты}}{SPECIALISTS TRAINING: professional standards}% + }{% + \ifthenelse{\equal{algorithmic-mathematics}{#1}}{% + \def\journal@section@name{\@lang{АЛГОРИТМИЧЕСКАЯ МАТЕМАТИКА И МАТЕМАТИЧЕСКОЕ МОДЕЛИРОВАНИЕ}{ALGORITHMIC MATHEMATIC AND MATHEMATICAL MODELING}}% + \setsectionheader{{\selectlanguage{russian}АЛГОРИТМИЧЕСКАЯ МАТЕМАТИКА И МАТЕМАТИЧЕСКОЕ МОДЕЛИРОВАНИЕ}}{ALGORITHMIC MATHEMATIC AND MATHEMATICAL MODELING}% <-- ДОБАВИТЬ + }{% + \ifthenelse{\equal{mathematical-modeling}{#1}}{% + \def\journal@section@name{\@lang{МАТЕМАТИЧЕСКОЕ МОДЕЛИРОВАНИЕ}{MATHEMATICAL MODELING}}% + \setsectionheader{{\selectlanguage{russian}МАТЕМАТИЧЕСКОЕ МОДЕЛИРОВАНИЕ}}{MATHEMATICAL MODELING}% <-- ДОБАВИТЬ + }{% + \ifthenelse{\equal{open-problems-for-young-scientists}{#1}}{% + \def\journal@section@name{\@lang{НЕРЕШЕННЫЕ ЗАДАЧИ ДЛЯ МОЛОДЫХ УЧЕНЫХ}{OPEN PROBLEMS FOR YOUNG SCIENTISTS}}% + \setsectionheader{{\selectlanguage{russian}НЕРЕШЕННЫЕ ЗАДАЧИ ДЛЯ МОЛОДЫХ УЧЕНЫХ}}{OPEN PROBLEMS FOR YOUNG SCIENTISTS}% <-- ДОБАВИТЬ + }{% + \ifthenelse{\equal{new-section}{#1}}{% + \def\journal@section@name{\@lang{НОВЫЙ РАЗДЕЛ}{A NEW SECTION}}% + \setsectionheader{{\selectlanguage{russian}НОВЫЙ РАЗДЕЛ}}{A NEW SECTION}% <-- ДОБАВИТЬ + }{% + \ifthenelse{\equal{artificial-intelligence}{#1}}{% + \def\journal@section@name{\@lang{ИСКУССТВЕННЫЙ ИНТЕЛЛЕКТ И МАШИННОЕ ОБУЧЕНИЕ}{ARTIFICIAL INTELLIGENCE AND MACHINE LEARNING}}% + \setsectionheader{{\selectlanguage{russian}ИСКУССТВЕННЫЙ ИНТЕЛЛЕКТ И МАШИННОЕ ОБУЧЕНИЕ}}{ARTIFICIAL INTELLIGENCE AND MACHINE LEARNING}% <-- ДОБАВИТЬ + }{% + \ifthenelse{\equal{empty}{#1}}{% + \def\journal@section@name{}% + \def\journal@section@img{}% + \setsectionheader{}{}% <-- ДОБАВИТЬ (пустые значения) + }{% + \def\journal@section@name{\@lang{раздел не указан или неизвестен}{section not specified or unknown} #1}% + \setsectionheader{{\selectlanguage{russian}раздел не указан или неизвестен #1}}{section not specified or unknown #1}% <-- ДОБАВИТЬ + }% + }% + }% + }% + }% + }% + }% + }% + }% + }% + }% + }% + }% + }% + }% + }% +} +\def\journalsectionnoimage#1{% + \def\@sectionwithimage{false} % Флаг, что раздел БЕЗ изображения + \journalsection{#1}% + \def\no@section@image{}% +}% + +\def\print@title{{\LARGE \hv@sf\bfseries\mathversion{bold} \MakeUppercase{\@title} \par}} +\def\print@author{% + \vskip 1.5em% + {\hv@sf + \lineskip .5em% + \large\upshape + \begin{varwidth}{\textwidth}\raggedright\authors@all@info\end{varwidth}% + \par} + } +\def\print@address{\vskip 0.5em + \small\hv@sf\upshape\@address\par + } + +% title + +\def\pages@span{% +\ifthenelse{\equal{\pageref*{first@page}}{\pageref*{last@page}}}% + {\pageref*{last@page}}% + {\pageref*{first@page}--\pageref*{last@page}}% +} + +\newcommand\print@doi{\href{https://doi.org/\doi@number}{doi:\doi@number}} +\newcommand\print@doi@full{\url{https://doi.org/\doi@number}} + +% Ширина блока с метаданными (тип статьи, выпуск, УДК, URL, DOI). +% Меньшая ширина → блок сдвигается вправо за счёт \hfill между картинкой и блоком. +% Должно хватать на самую длинную строку — обычно DOI (например, +% «doi:10.32603/2071-2340-2026-4-113-129»). +\def\title@full@article@info@width{5.52cm} +\def\title@full@article@info{% + \begin{minipage}{\title@full@article@info@width} +% \fbox{% ← Рамка + \parbox{\linewidth}{% ← Вложенный parbox для точности; текст внутри выровнен влево + \small\hv@sf + % ТИП СТАТЬИ ЖИРНЫМ ШРИФТОМ — язык согласно \article@type@current + \textbf{\article@type@current}\\ [0.6ex] + №~\issue@number:\space + \pages@span% + \@ifundefined{udk@number}{}{\\[0.6ex]\@langrev{УДК}{UDC}:\space\udk@number}% + \\[0.6ex]\href{http://cte.eltech.ru}{http://cte.eltech.ru}% + \@ifundefined{doi@number}{}{\\[0.6ex]\print@doi}% + } +% } + \end{minipage}% +} + \def\title@section@image{% + \begin{minipage}{7cm} + \@ifundefined{no@section@image}{% + \includegraphics[width=7cm]{\@section@image@path@prefix\journal@section@id\@lang{}{-en}.png}% + }{% + % \hskip 7cm% + } + \end{minipage}% + }% + +\def\@maketitle{% + + %---------------------------- + \ifthenelse{\isodd{\value{page}}}{% + % Нечетные страницы: метаданные слева, картинка справа + \noindent\title@full@article@info\hfill\title@section@image% +}{% + % Четные страницы: картинка слева, метаданные справа + \noindent\title@section@image\hfill\title@full@article@info% +}% + % + %---------------------------- + %ruler below title + %\par\vskip3pt\noindent\textcolor{rulercolor}{\hrulefill} + {%\raggedright% + \centering + \let \footnote \thanks + \vskip 2cm + \if@englishversion + \@ifundefined{@title@en}{}{\let\@title\@title@en\print@title}% + \else + \@ifundefined{@title}{}{\print@title}% + \fi + \@ifundefined{@author}{}{\print@author}% + \@ifundefined{@address}{}{\print@address}% + \if@englishversion\affiliation@footnotes@en\else\affiliation@footnotes\fi + }% + \par + \vskip 1.5em% +} + +\renewenvironment{abstract}{% +% \setcounter{page}{\start@page}\label{first@page} +% \setcounter{page}{1}\label{first@page} + \if@twocolumn + %\section*{Аннотация}% + \else + \everypar{\parskip 3pt plus1pt minus2pt + \parindent=0pt% \hangindent=\@titleindent + \hangafter=0% + \leftskip=\@titleindent% + \rightskip=\@titleindent} + \noindent\small\hv@sf\upshape\ignorespaces + \fi + {\centering\textbf{\kioabstractname}\par}} + {\if@twocolumn\else\vskip 1.5em plus 0.2em \fi\upshape} + +\newcommand\abstract@section[2]{\par\vskip 1ex + \noindent% + \raggedright% + \leftskip=\@titleindent% + \rightskip=\@titleindent% + \upshape{\hv@sf\bfseries #1:}#2\space} + +\newcommand\keywords{\par\vskip 0.5ex + \noindent% + \raggedright% + \leftskip=\@titleindent% + \rightskip=\@titleindent% + \upshape{\hv@sf\bfseries \keywordsname: }\slshape} + + +\newcommand\acknowledgements[1]{\par\vskip 1ex\noindent\textbf{\acknowledgementsname: }\textit{#1}} + +% --- Хелперы для IEEE-стилизации списка авторов ---------------------------- + +% Перестановка «Lastname I.~I.» → «I.~I. Lastname» (по первому пробелу). +% Перед вызовом полезно сделать \let\affil\@gobble, чтобы убрать аффилиации. +\def\@kio@swap@author#1 #2\@@nil{#2 #1} + +% Печать всех авторов в IEEE-стиле: +% 1 author : «I. I. X» +% 2 authors: «I. I. X and J. J. Y» +% 3 : «I. I. X, J. J. Y, and K. K. Z» (Oxford comma) +% 4+ : «I. I. X, J. J. Y, K. K. Z, et al.» (truncate to first 3) +\newcommand{\@kio@ieee@authors}{% + \count@\z@ + \@authors@iter{@short@en}{\advance\count@\@ne}% + \edef\@kio@total{\the\count@}% + \ifnum\@kio@total>4 + \@kio@ieee@authors@truncated + \else + \@kio@ieee@authors@full + \fi +} + +% Полный список авторов (n<=4) +\newcommand{\@kio@ieee@authors@full}{% + \count@\z@ + \@authors@iter{@short@en}{% + \advance\count@\@ne + \ifnum\count@>\@ne + \ifnum\count@=\@kio@total\relax + \ifnum\@kio@total=\tw@\space and\space\else, and\space\fi + \else + , % + \fi + \fi + \edef\@kio@cur{\csname author\author@i @short@en\endcsname}% + \expandafter\@kio@swap@author\@kio@cur\@@nil + }% +} + +% Усечённый список (n>4): первые три автора через запятую и затем «, et al.». +\newcommand{\@kio@ieee@authors@truncated}{% + \count@\z@ + \@authors@iter{@short@en}{% + \advance\count@\@ne + \ifnum\count@>3\else + \ifnum\count@>\@ne, \fi + \edef\@kio@cur{\csname author\author@i @short@en\endcsname}% + \expandafter\@kio@swap@author\@kio@cur\@@nil + \fi + }% + , et~al.% +} + +% «p.» для одной страницы, «pp.» для диапазона — определяется через метки first/last@page. +\newcommand{\@kio@pages@prefix}{% + \ifthenelse{\equal{\pageref*{first@page}}{\pageref*{last@page}}}{p.}{pp.}% +} + +% --- Автогенерируемое цитирование ------------------------------------------ +% \autocitation — печатает ярлык «Цитирование/Citation» и автоматически +% собранный пример цитирования. +% • Русская версия — стиль ГОСТ Р 7.0.100-2018: «Авторы. Название // Журнал. +% Год. № Номер. С. Страницы. doi:…». +% • Английская версия — IEEE-стиль: «I. I. Author1, …, and I. I. AuthorN, +% “Title,” Journal, no. N, pp. P–Q, Year, doi:…». +% Используются полные названия (\@title / \@title@en). +\newcommand\autocitation{% + \par\vskip 1ex\noindent\textbf{\citationname: }% + \begingroup + \let\affil\@gobble % в цитировании не нужны индексы аффилиаций + \@langrev{% + % Русский / ГОСТ + \authors@short@truncated\space\@title\space// + \space\journal@type. \issue@year. № \issue@number. С.~\pages@span.% + \@ifundefined{doi@number}{}{\space\print@doi.}% + }{% + % English / IEEE + \@kio@ieee@authors, ``\@title@en,''\space + \journal@type@en, no.~\issue@number, \@kio@pages@prefix~\pages@span, \issue@year% + \@ifundefined{doi@number}{}{, \print@doi}.% + }% + \endgroup +} + +% --- Ручное цитирование --- +% \manualcitation{<текст>} — печатает ярлык «Цитирование/Citation» и далее +% переданный пользователем текст. Пример: +% \manualcitation{Andreev A.~A., Borisov B.~B. Article title. Journal, 2026.} +\newcommand{\manualcitation}[1]{% + \par\vskip 1ex\noindent\textbf{\citationname: }#1% +} + +\newcommand\pacs{\par\vskip 1ex + \noindent\raggedright\upshape{\hv@sf\bfseries PACS:}\slshape\space} + +% ========================================================================= +% Generic author API: \author{N}[short]{full}, \authoren{N}[short]{full}, +% \authorinfo{N}{...}, \authorinfoen{N}{...}, +% \authoremail{N}{...}, \authoremailEnvelope{N}{...}, \authororcid{N}{...}. +% N is an Arabic numeral; it is used directly as the key inside \csname...\endcsname. +% ========================================================================= + +% \author{N}[short]{full} +\def\author#1{\@dblarg{\make@author{#1}}} +\long\def\make@author#1[#2]#3{% + \expandafter\gdef\csname author#1@short\endcsname{#2}% + \expandafter\gdef\csname author#1@full\endcsname{#3}% + % English defaults (overridden by \authoren{N}[...]{...} if used) + \expandafter\gdef\csname author#1@short@en\endcsname{#2}% + \expandafter\gdef\csname author#1@full@en\endcsname{#3}% +} + +% \authoren{N}[short]{full} +\def\authoren#1{\@dblarg{\make@authoren{#1}}} +\long\def\make@authoren#1[#2]#3{% + \expandafter\gdef\csname author#1@short@en\endcsname{#2}% + \expandafter\gdef\csname author#1@full@en\endcsname{#3}% +} + +% \authorinfo{N}{...} / \authorinfoen{N}{...} +\newcommand{\authorinfo}[2]{% + \expandafter\def\csname author#1@info\endcsname{#2}% + \expandafter\def\csname author#1@info@en\endcsname{#2}% +} +\newcommand{\authorinfoen}[2]{% + \expandafter\def\csname author#1@info@en\endcsname{#2}% +} + +% \authoremail{N}{...} / \authoremailEnvelope{N}{...} +\newcommand{\authoremail}[2]{% + \expandafter\def\csname author#1@email\endcsname{#2}% +} +\newcommand{\authoremailEnvelope}[2]{% + \authoremail{#1}{#2}% + \expandafter\def\csname author#1@email@recepient\endcsname{}% +} + +% \authororcid{N}{...} +\newcommand{\authororcid}[2]{% + \expandafter\def\csname author#1@orcid\endcsname{#2}% +} + +\def\title{\@dblarg{\make@title}} +\long\def\make@title[#1]#2{ + \gdef\fancy@title{#1} + \gdef\fancy@header@title{#1} + \gdef\@title{#2} + \gdef\@title@en{#1} % английская версия +} + +% Команда для английского заголовка +\def\titleen{\@dblarg{\make@titleen}} +\long\def\make@titleen[#1]#2{ + \gdef\fancy@title@en{#1} + \gdef\fancy@header@title@en{#1} + \gdef\@title@en{#2} +} + +\def\print@author@en{% + \vskip 1.5em% + {\hv@sf + \lineskip .5em% + \large\upshape + \def\authorinfo##1{ + \setstretch{0.9} + \csname author##1@short@en\endcsname% + \ifcsname author##1@email\endcsname% + \hspace{0.5em}% + \ifcsname author##1@email@recepient\endcsname\@Letter\fi% + \hspace{0.5em}\href{mailto:\csname author##1@email\endcsname}{\csname author##1@email\endcsname}% + \fi + \ifcsname author##1@orcid\endcsname% + , \href{https://\csname author##1@orcid\endcsname}{\csname author##1@orcid\endcsname}% + \fi + } + \@authors@iter{@short@en}{\authorinfo{\author@i}\par}% + \par} +} + +% Команды колонтитулов +\def\@russianarticleheader{} +\def\@englisharticleheader{} +\def\@russianauthorsheader{} +\def\@englishauthorsheader{} +\def\@russiansectionheader{} +\def\@englishsectionheader{} +\def\@sectionwithimage{false} +\newif\iffirstpage +\firstpagetrue + + +% Ключевые слова — печатают свой блок прямо на месте вызова. +% Текст аннотации и дополнительной информации пользователь записывает напрямую +% внутри \begin{abstract} и \additionalinfo{...}. +% Пример цитирования формируется автоматически командой \autocitation. +\newcommand{\keywordsru}[1]{% + \par\vskip 0.5ex\noindent\textbf{Ключевые слова: }\textit{#1}% +} +\newcommand{\keywordsen}[1]{% + \par\vskip 0.5ex\noindent\textbf{Keywords: }\textit{#1}% +} + +% Благодарности / Acknowledgments +\newcommand{\acknowledgmentsru}[1]{% + \par\vskip 1ex\noindent\textbf{Благодарности: }\textit{#1}% +} +\newcommand{\acknowledgmentsen}[1]{% + \par\vskip 1ex\noindent\textbf{Acknowledgments: }\textit{#1}% +} + +% Вклад авторов / Authors' Contributions +\newcommand{\authorscontributionsru}[1]{% + \par\vskip 1ex\noindent\textbf{Вклад авторов: }\textit{#1}% +} +\newcommand{\authorscontributionsen}[1]{% + \par\vskip 1ex\noindent\textbf{Authors' Contributions: }\textit{#1}% +} + +% Финансирование / Funding +\newcommand{\fundingru}[1]{% + \par\vskip 1ex\noindent\textbf{Финансирование: }\textit{#1}% +} +\newcommand{\fundingen}[1]{% + \par\vskip 1ex\noindent\textbf{Funding: }\textit{#1}% +} + +% Конфликт интересов / Conflict of Interest +\newcommand{\conflictofinterestru}[1]{% + \par\vskip 1ex\noindent\textbf{Конфликт интересов: }\textit{#1}% +} +\newcommand{\conflictofinteresten}[1]{% + \par\vskip 1ex\noindent\textbf{Conflict of Interest: }\textit{#1}% +} + +\def\address#1{\gdef\@address{#1}} +\def\addresses#1{\gdef\@address{% + \renewcommand{\labelenumi}{$^{\textsf{\footnotesize\arabic{enumi}}}$} + \setlength{\leftmargini}{0mm} + \setlength{\topsep}{0mm} + \setlength{\partopsep}{0mm} + \setlength{\parskip}{0mm} + \begin{enumerate} + \setlength{\itemsep}{0mm} + \setlength{\itemindent}{0em} + \setlength{\labelsep}{2pt} + #1 + \end{enumerate}}} + +% Настройка колонтитулов +\newcommand{\setarticleheader}[2]{% + \def\@russianarticleheader{{\selectlanguage{russian}#1}}% + \def\@englisharticleheader{#2}% +} + +\newcommand{\setauthorsheader}[2]{% + \def\@russianauthorsheader{{\selectlanguage{russian}#1}}% + \def\@englishauthorsheader{#2}% +} + +\newcommand{\setsectionheader}[2]{% + \def\@russiansectionheader{{\selectlanguage{russian}#1}}% + \def\@englishsectionheader{#2}% +} + +\DeclareRobustCommand\@refad{\@@refadx} +\def\@@refadx#1{% + \let\@@refada\@empty + \@@refad{\@for\@@refadb:=#1\do + {\@@refada\def\@@refada{,\penalty\@m}% + \edef\@@refadb{\expandafter\@firstofone\@@refadb\@empty}% + \@ifundefined{r@\@@refadb}{\mbox{\reset@font\bfseries ?}% + \G@refundefinedtrue + \@latex@warning + {Address reference `\@@refadb' undefined}}% + {\hbox{\ref{\@@refadb}}}}}} +\def\@@refad#1{{#1}} + +%% Floats %% + +%\bibsep=0pt +%\renewcommand{\bibnumfmt}[1]{#1.} +\@ifundefined{bibfont}{\newcommand{\bibfont}{\small}}{\renewcommand{\bibfont}{\small}} + +%% Английская часть %% + +\newcommand\maketranslatedtitle{ + \begingroup + \global\@botnum\z@ % Не разрешаем рисунки внизу страницы. + % Внутри \translatedpart \if@englishversion уже отражает язык перевода. + \if@englishversion\let\@title\@title@en\fi + \@makerutitle + \@thanks + \endgroup + \global\let\thanks\relax + \global\let\makerutitle\relax + \global\let\@makerutitle\relax + \global\let\@thanks\@empty + % \@title и \@title@en НЕ очищаем — они нужны позже для \autocitation. + \global\let\@author\@empty + \global\let\@date\@empty + \global\let\title\relax + \global\let\author\relax + \global\let\date\relax + \global\let\and\relax +} +\def\print@rutitle{{\Large \hv@sf\bfseries\mathversion{bold}{\@title} \par}} + +\def\@makerutitle{% + \par + \vskip 10pt + \noindent\null + \ifthenelse{\isodd{\value{page}}}{% + % Нечетные страницы + \noindent\hfill% + \begin{minipage}[t]{5.5cm} + \raggedleft + \title@full@article@info + \end{minipage} + }{% + % Четные страницы + \noindent\title@full@article@info\hfill% + } + \vskip 1.5em + \noindent\null + \raggedright% + \centering + \let \footnote \thanks + + \if@englishversion + \@ifundefined{@title@en}{}{\def\@title{\@title@en}}% + \fi + \@ifundefined{@title}{}{\print@rutitle}% + \global\let\affil\@affil% + + % Информация об авторах: \print@author уже выбирает язык по \if@englishversion. + \print@author + + \@ifundefined{@address}{}{\print@address}% + % Аффилиации соответствуют языку перевода. + \if@englishversion\affiliation@footnotes@en\else\affiliation@footnotes\fi + \global\let\affil\relax@with@arg% + \par + \vskip 1.5em% +} + +\newenvironment{translatedpart}{% + \def\@has@translated@part{} + \@in@translatedparttrue + \@flip@englishversion % язык переключается на противоположный + \lefthyphenmin=2 \righthyphenmin=2 % disallow x- or -x breaks; -xx OK + \lccode`\'=`\' + \def\@reverse@lang{} + +%% ПРОВЕРКА МЕСТА + + % Сбрасываем штрафы для проверки места + \widowpenalty=0 + \clubpenalty=0 + + % Проверяем, есть ли хотя бы 50% страницы свободно + \@tempdima=\pagegoal \advance\@tempdima-\pagetotal + \@tempdimb=0.5\pagegoal % 50% от высоты страницы + + \ifdim\@tempdima>\@tempdimb + % Есть достаточно места - рисуем линию + \vspace{12pt} + {\color{rulercolor}% + \hrule width\headwidth height\headrulewidth + \vspace{1pt} + \hrule width\headwidth height\headrulewidth} + \vspace{12pt} + \else + % Недостаточно места - новая страница + \newpage + \fi + \@firstpagefalse +}{ + % В КОНЦЕ переведённой части выводим расширенную информацию об авторах + % на языке перевода (\if@englishversion уже инвертирован для translatedpart). + \@ifundefined{need@authors@info}{}{ + \vspace*{1cm} + \par + \addvspace{6pt} + \widowpenalty=0 + \clubpenalty=0 + + \printauthorsinfo + } + \@flip@englishversion % восстанавливаем исходный язык +} + +\newcommand\additionalinfo[1]{ +\begin{center} +{\noindent\small\hv@sf\upshape\ignorespaces #1} +\end{center} +} + +%% General %% + +%\voffset -1in +%\hoffset -1in +\textwidth 150mm +%\textheight 227mm +\textheight 646pt % = 227.0430331mm +\topmargin 30mm +\headheight 15pt +\headsep 10mm +%\footskip 25mm % Добавили отступ для нижнего колонтитула +\addtolength{\topmargin}{-\headheight} +\addtolength{\topmargin}{-\headsep} +\addtolength{\topmargin}{-1in} +\oddsidemargin 35mm +\setlength{\evensidemargin}{210mm} +\addtolength{\evensidemargin}{-\textwidth} +\addtolength{\evensidemargin}{-\oddsidemargin} +\addtolength{\oddsidemargin}{-1in} +\addtolength{\evensidemargin}{-1in} +\baselineskip 15pt +\newlength{\@titlewidth} +\newlength{\@titleindent} +\setlength{\@titlewidth}{\textwidth} +\setlength{\@titleindent}{15mm} +\addtolength{\@titlewidth}{-\@titleindent} +\newlength{\@captionwidth} +%\setlength{\@captionwidth}{\hsize} +%\addtolength{\@captionwidth}{-2\parindent} +%P%\renewcommand{\encodingdefault}{T1} +%\renewcommand{\sfdefault}{phv} +\renewcommand{\sfdefault}{\lat@sf} +\frenchspacing +\let\@afterindentfalse\@afterindenttrue + +\renewcommand\footnoterule{% + \vskip 8\p@ \@plus\z@ \@minus 5\p@ + \color{rulercolor}\hrule height 0.4pt \@width\textwidth + \vskip 12\p@ \@plus\z@ \@minus 3\p@} +\setlength{\skip\footins}{12pt plus 2pt minus 6pt} +\setlength{\footnotesep}{5pt} + +%% Headings %% + +%\def\sf@phv{\fontencoding{T1}\fontfamily{phv}\selectfont\upshape} +%P1%\def\sf@phv{\fontencoding{T1}\fontfamily{\lat@sf}\selectfont\upshape} +\def\sf@phv{\fontfamily{\lat@sf}\selectfont\upshape} +\newcounter{isspage} +\def\issue@page@odd{} +\def\issue@page@even{} +\def\issuepage#1{% + \oddsidemargin 20mm% + \setlength{\evensidemargin}{210mm}% + \addtolength{\evensidemargin}{-\textwidth}% + \addtolength{\evensidemargin}{-\oddsidemargin}% + \addtolength{\oddsidemargin}{-1in} + \addtolength{\evensidemargin}{-1in} + \setcounter{isspage}{#1}% + \addtocounter{isspage}{-1}% + \def\issue@page@odd{% + \stepcounter{isspage}% + {\unitlength1mm% + \begin{picture}(0,0)% +% \put(30,10){\makebox(0,0)[l]{\vrule height 20pt}}% + \put(30.5,10){\makebox(0,0)[l]{\rotatebox{90}{\textsf{\theisspage}}}}% + \end{picture}}% + }% + \def\issue@page@even{% + \stepcounter{isspage}% + {\unitlength1mm% + \begin{picture}(0,0)% +% \put(-30,10){\makebox(0,0)[l]{\vrule height 20pt}}% + \put(-30,10){\makebox(0,0)[r]{\rotatebox{90}{\textsf{\theisspage}}}}% + \end{picture}}% + }% +} + + +\renewcommand{\headrule}{\fancyplain{}{{\color{rulercolor}% + \hrule width\headwidth height\headrulewidth \vskip-\headrulewidth}}} + +\renewcommand{\footrule}{{\color{rulercolor}% + \vskip-\footruleskip\vskip-\footrulewidth% + \hrule width\headwidth height\footrulewidth\vskip\footruleskip}} + +\renewcommand{\headrulewidth}{0.4pt} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\plainheadrulewidth}{0pt} +\renewcommand{\plainfootrulewidth}{0.4pt} + +% Стили страниц + +% КОЛОНТИТУЛЫ ВСЕХ СТРАНИЦ КРОМЕ 1-ОЙ + +\fancypagestyle{mainstyle}{% + \fancyhf{} + \renewcommand{\headrulewidth}{0.4pt} + \renewcommand{\footrulewidth}{0.4pt} + + % Верхние колонтитулы. Используем \ifenglishpaper (постоянный по всему документу), + % чтобы внутри \translatedpart колонтитулы НЕ переключались на другой язык. + \fancyhead[RO]{% + \normalsize\sf@phv\textcolor{rulercolor}{% + \ifenglishpaper\@englisharticleheader\else\@russianarticleheader\fi + }% + } + + \fancyhead[LE]{% + \normalsize\sf@phv\textcolor{rulercolor}{% + \ifenglishpaper\@englishauthorsheader\else\@russianauthorsheader\fi + }% + } + + % НИЖНИЕ КОЛОНТИТУЛЫ С НОМЕРАМИ СТРАНИЦ ВНУТРИ + \fancyfoot[RO]{% + \normalsize\sf@phv\textcolor{rulercolor}{% + \ifenglishpaper + \ \MakeTextUppercase{\journal@type@en}\ \issue@year.\ no.\ \issue@number.\ pp.\ \pages@span + \else + \ \MakeTextUppercase{\journal@type@ru}\ \issue@year.\ {\selectlanguage{russian}№\ \issue@number.\ С.\ \pages@span} + \fi + }% + \hfill + \normalsize\sf@phv\textcolor{black}{\kio@page} + } + + \fancyfoot[LE]{% + \normalsize\sf@phv\textcolor{black}{\kio@page} + \hfill + \normalsize\sf@phv\textcolor{rulercolor}{% + \ifenglishpaper\@englishsectionheader\else\@russiansectionheader\fi + }% + } +} + +% КОЛОНТИТУЛЫ ПЕРВОЙ СТРАНИЦЫ +\fancypagestyle{firstpagestyle}{% + \fancyhf{} + + \renewcommand{\headrulewidth}{0pt} + \renewcommand{\footrulewidth}{0.4pt} + + % Убираем стандартные отступы fancyhdr + \fancyheadoffset{0pt} + \fancyfootoffset{0pt} + + % ПРАВАЯ СТРАНИЦА (нечетная) + \fancyfoot[RO]{% + \footnotesize\sf@phv% + \hspace*{0pt}% Компенсируем левый отступ + % Журнал к левому краю + \begin{minipage}[t]{0.6\textwidth} + \raggedright\sloppy + \hyphenpenalty=10000 + \exhyphenpenalty=10000 + \emergencystretch=0em + \textcolor{rulercolor}{% + \ifenglishpaper + \noindent\copyright\ + \MakeTextUppercase{\journal@type@en}, \issue@year% + \else + \noindent\copyright\ \MakeTextUppercase{\journal@type@ru}, \issue@year% + \fi + } + \end{minipage}% + \hfill% + % Иконка CC BY по центру (файл лежит в каталоге images/) + \raisebox{-3.0ex}{% + \IfFileExists{images/cc-by.png}{% + \includegraphics[height=4.5ex]{images/cc-by.png}% + }{}% + }% +% \hfill% + % Номер страницы к правому краю +% \hspace*{0pt plus 1fill} + \hspace{1em} + \normalsize\textcolor{black}{\kio@page}% + } + + % ЛЕВАЯ СТРАНИЦА (четная) + \fancyfoot[LE]{% + \footnotesize\sf@phv% + \hspace*{0pt}% Компенсируем левый отступ + % Номер страницы к левому краю + \normalsize\textcolor{black}{\kio@page}% + \hspace*{20pt plus 1fill}% + % Иконка CC BY точно по центру (файл лежит в каталоге images/) + \raisebox{-3.0ex}{% + \IfFileExists{images/cc-by.png}{% + \includegraphics[height=4.5ex]{images/cc-by.png}% + }{}% + }% + \hfill% + % Журнал к правому краю + \begin{minipage}[t]{0.75\textwidth} + \raggedleft\sloppy + \hyphenpenalty=10000 + \exhyphenpenalty=10000 + \emergencystretch=2em + \textcolor{rulercolor}{% + \ifenglishpaper + \noindent\copyright\ \MakeTextUppercase{\journal@type@en}, \issue@year% + \else + \noindent\noindent\copyright\ \MakeTextUppercase{\journal@type@ru}, \issue@year% + \fi + } + \end{minipage}% + \hspace*{0pt}% Компенсируем правый отступ + } +} + +\pagestyle{mainstyle} + +\lefthyphenmin=2 +\righthyphenmin=3 + +\newcommand\printauthorsinfo{ + \@ifundefined{need@authors@info}{}{ + \par + \addvspace{0pt} % Добавляем отступ сверху + \widowpenalty=300 % Запрещаем висячие строки + \clubpenalty=300 + \noindent + \begin{minipage}[b]{\textwidth}% +% \bfseries + \sf@phv + + \def\authorlonginfo##1{ + \setstretch{0.9} + \noindent + \csname author##1@full\endcsname, + \ifcsname author##1@info\endcsname \csname author##1@info\endcsname\fi, + \ifcsname author##1@email\endcsname\ifcsname author##1@email@recepient\endcsname\@Letter~\fi\href{mailto:\csname author##1@email\endcsname}{\csname author##1@email\endcsname}\fi + } + + \def\allauthorslonginfo{% + \def\authorlonginfo####1{% + \setstretch{0.9}% + \noindent% + \if@englishversion% + \csname author####1@full@en\endcsname% + \ifcsname author####1@info@en\endcsname, \csname author####1@info@en\endcsname\fi% + \else% + \csname author####1@full\endcsname% + \ifcsname author####1@info\endcsname, \csname author####1@info\endcsname\fi% + \fi% + \ifcsname author####1@email\endcsname% + \ifcsname author####1@email@recepient\endcsname% + , \@Letter\ \href{mailto:\csname author####1@email\endcsname}{\csname author####1@email\endcsname}% + \else% + , \href{mailto:\csname author####1@email\endcsname}{\csname author####1@email\endcsname}% + \fi% + \fi% + }% + \let\@author@sep\@empty + \@authors@iter{@short}{% + \@author@sep + \authorlonginfo{\author@i}\par + \def\@author@sep{\vskip 2mm}% + }% + } + + \allauthorslonginfo + + \end{minipage} + } +} + +% Старая команда +\let\print@authors@info\printauthorsinfo + +\AtEndDocument{% + \lastpage% +} +\ifpdftex + \RequirePackage[T2A]{fontenc} % package 'fourier' sets T1 encoding +\fi + +\ifpdftex + \makeatletter + \AtBeginDocument{% + \gdef\f@encoding{T2A}% + } + \makeatother +\fi +\ifxetex + \usepackage{fontspec} +\fi + +\newcites{eng}{References} + + +\AtBeginDocument{% + \DeclareRobustCommand{\mylinkurl}{% + \begingroup + \catcode`\_=12\relax \catcode`\~=12\relax \catcode`\#=12\relax + \catcode`\%=12\relax \catcode`\&=12\relax \catcode`\$=12\relax + \catcode`\^=12\relax + \mylinkurl@scan}% + \def\mylinkurl@scan#1{\href{https://doi.org/#1}{#1}\endgroup}% +} + +\usepackage{letltxmacro} + +\LetLtxMacro{\originalcite}{\cite} + +%\let\originalcite\cite + +\makeatletter +\renewcommand{\cite}[2][]{% + \begingroup + \def\@cite@post{#1}% + \ifx\@cite@post\@empty + \originalcite{#2}% + \else + \originalcite[\@cite@post]{#2}% + \fi + \if@englishversion + \else + \@for\@tmp:=#2\do{% + \edef\@tmp@en{EN-\@tmp}% + \expandafter\nociteeng\expandafter{\@tmp@en}% + }% + \fi + \endgroup +} +\makeatother + +\makeatletter +\renewcommand\@biblabel[1]{#1.} +\makeatother + + +%\pagestyle{mainstyle} +\endinput diff --git a/InProgress/StackGraphs_to_CFL_Reachability/main.pdf b/InProgress/StackGraphs_to_CFL_Reachability/main.pdf new file mode 100644 index 00000000..8be3ac4c Binary files /dev/null and b/InProgress/StackGraphs_to_CFL_Reachability/main.pdf differ diff --git a/InProgress/StackGraphs_to_CFL_Reachability/main.tex b/InProgress/StackGraphs_to_CFL_Reachability/main.tex new file mode 100644 index 00000000..94a83cce --- /dev/null +++ b/InProgress/StackGraphs_to_CFL_Reachability/main.tex @@ -0,0 +1,88 @@ +% Статья для журнала «Компьютерные инструменты в образовании». +% Основа: официальный русский шаблон с классом kioj6 от 07.04.2026. +% Сведения, отсутствующие в исходном DOCX, перечислены в README.md. + +\documentclass[eqsecnum,authorsinfo]{kioj6} + +\usepackage{enumitem} +\usepackage{tabularray} +\usepackage{fancyvrb} + +% В актуальном классе блок издательских реквизитов на 0,02 см шире внешнего +% контейнера английской части; небольшое уменьшение устраняет выход за поле. +\makeatletter +\def\title@full@article@info@width{5.48cm} +\makeatother + +\raggedbottom +\widowpenalty=10000 +\clubpenalty=10000 + +% Редакционные поля. Год и номер выпуска уточняются редакцией; внутренняя +% нумерация проверочного макета начинается с первой страницы. +\setcounter{page}{1} +\journalsectionnoimage{empty} +\issue{--}{--}{edu} +\articletr{}{} + +% УДК и DOI в исходном файле отсутствуют, поэтому не подставляются. + +\title[Разрешение имён на основе сведения стековых графов]{Разрешение имён в языках программирования на основе сведения стековых графов к контекстно-свободной достижимости} +\titleen[Name Resolution Based on Stack Graphs Conversion]{Name Resolution Based on Stack Graphs Conversion to Context-Free Reachability for Programming Languages} + +\author{1}[Ильин Е.~С.\affil{1}]{Ильин Егор Сергеевич} +\authorinfo{1}{выпускник кафедры математического обеспечения и применения ЭВМ, СПбГЭТУ «ЛЭТИ»} +\authoremailEnvelope{1}{egor2105094ilin@gmail.com} +\affiliation{1}{Санкт-Петербургский государственный электротехнический университет «ЛЭТИ» им. В.~И. Ульянова (Ленина), Российская Федерация, 197022, Санкт-Петербург, ул. Профессора Попова, 5} + +\author{2}[Григорьев С.~В.\affil{2}]{Григорьев Семён Вячеславович} +\authorinfo{2}{канд. физ.-мат. наук, доцент кафедры системного программирования СПбГУ} +\authoremail{2}{s.v.grigoriev@spbu.ru} +\authororcid{2}{orcid.org/0000-0002-7966-0698} +\affiliation{2}{Санкт-Петербургский государственный университет, Российская Федерация, 199034, Санкт-Петербург, Университетская наб., 7–9} + +\authoren{1}[Ilin E.~S.\affil{1}]{Ilin Egor} +\authorinfoen{1}{graduate of ETU ``LETI''} +\affiliationen{1}{Saint Petersburg State Electrotechnical University “LETI”, Professora Popova ul. 5, St. Petersburg, 197022, Russian Federation} + +\authoren{2}[Grigorev S.~V.\affil{2}]{Semyon Grigorev} +\authorinfoen{2}{Associate Professor at St. Petersburg State University} +\affiliationen{2}{Saint Petersburg State University, Universitetskaya nab. 7–9, St. Petersburg, 199034, Russian Federation} + +\begin{document} + +\russianversion +\maketitle +\pagestyle{mainstyle} + +\begin{abstract} +Работа посвящена абстрактному разрешению имён, то есть связыванию ссылок на символы с их определениями, с использованием графовых моделей. Рассматривается способ сведения модели стековых графов к задаче достижимости с контекстно-свободными ограничениями (КС-достижимости). Областями применения являются инструменты анализа кода и навигации по кодовым базам, интегрированные среды разработки, компиляторы. В статье представлено теоретическое сведение модели стековых графов к КС-достижимости, рассмотрены его ограничения. Произведена проверка предложенного решения на практике, выполнено экспериментальное сравнение со стековыми графами. Также освещены направления дальнейших исследований и доработки сведения и разработанного программного средства. + +\keywordsru{стековые графы, контекстно-свободная достижимость, абстрактное разрешение имён, алгоритмы на графах} +\end{abstract} + +\input{article_body} + +% Номера источников определяются порядком первого упоминания в статье. +% База references-clones.bib создаётся официальным сценарием из references.bib. +\bibliographystyle{ugost2008} +\bibliography{references-clones} + +\printauthorsinfo + +\begin{translatedpart} +\maketranslatedtitle + +\begin{abstract} +The problem of abstract name resolution (binding symbol references to corresponding symbol definitions) in graph models is covered in the article. The method for stack graphs model conversion to the problem of context-free reachability (CFL-reachability) is considered. The areas of applicability encompass code analysis and navigation tools, integrated development environments, compilers. The article presents conversion of stack graphs model to CFL-reachability and considers conversion's limitations. A practical check of the proposed solution and an experimental comparison with stack graphs are conducted. Additionally, further areas of research and improvement of the presented method and the designed program are highlighted. + +\keywordsen{stack graphs, context-free reachability, abstract name resolution, graph algorithms} +\end{abstract} + +\begin{otherlanguage*}{english} +\bibliographystyleeng{IEEE} +\bibliographyeng{references-en-prefixed,references-clones} +\end{otherlanguage*} +\end{translatedpart} + +\end{document} diff --git a/InProgress/StackGraphs_to_CFL_Reachability/references-clones.bib b/InProgress/StackGraphs_to_CFL_Reachability/references-clones.bib new file mode 100644 index 00000000..ecf27afe --- /dev/null +++ b/InProgress/StackGraphs_to_CFL_Reachability/references-clones.bib @@ -0,0 +1,296 @@ +@INPROCEEDINGS{EN-Zwaan2023, + AUTHOR = {Zwaan, Aron and van Antwerpen, Hendrik}, + PUBLISHER = {Schloss Dagstuhl -- Leibniz-Zentrum für Informatik}, + ADDRESS = {Dagstuhl, Germany}, + BOOKTITLE = {Eelco Visser Commemorative Symposium ({EVCS} 2023)}, + DOI = {10.4230/OASIcs.EVCS.2023.32}, + PAGES = {32:1--32:13}, + SERIES = {Open Access Series in Informatics (OASIcs)}, + TITLE = {Scope Graphs: The Story so Far}, + VOLUME = {109}, + YEAR = {2023}, +} + +@ARTICLE{EN-vanAntwerpen2018, + AUTHOR = {van Antwerpen, Hendrik and Bach Poulsen, Casper and Rouvoet, Arjen and Visser, Eelco}, + PUBLISHER = {Association for Computing Machinery}, + ADDRESS = {New York, NY, USA}, + ARTICLENO = {114}, + DOI = {10.1145/3276484}, + JOURNAL = {Proceedings of the ACM on Programming Languages}, + MONTH = nov, + NUMBER = {OOPSLA}, + PAGES = {1--30}, + TITLE = {Scopes as Types}, + VOLUME = {2}, + YEAR = {2018}, +} + +@INPROCEEDINGS{EN-Neron2015, + AUTHOR = {Néron, Pierre and Tolmach, Andrew P. and Visser, Eelco and Wachsmuth, Guido}, + EDITOR = {Vitek, Jan}, + PUBLISHER = {Springer}, + ADDRESS = {Berlin, Heidelberg}, + BOOKTITLE = {Programming Languages and Systems: 24th European Symposium on Programming, {ESOP} 2015, Held as Part of {ETAPS} 2015, London, UK, April 11--18, 2015, Proceedings}, + DOI = {10.1007/978-3-662-46669-8_9}, + PAGES = {205--231}, + SERIES = {Lecture Notes in Computer Science}, + TITLE = {A Theory of Name Resolution}, + VOLUME = {9032}, + YEAR = {2015}, +} + +@INPROCEEDINGS{EN-MuravevGrigorev2025, + AUTHOR = {Muravev, Ilia and Grigorev, Semyon}, + PUBLISHER = {Association for Computing Machinery}, + ADDRESS = {New York, NY, USA}, + BOOKTITLE = {Proceedings of the 14th ACM SIGPLAN International Workshop on the State Of the Art in Program Analysis ({SOAP} '25)}, + DOI = {10.1145/3735544.3735585}, + ISBN = {979-8-4007-1922-6}, + PAGES = {28--35}, + TITLE = {Universal High-Performance {CFL}-Reachability via Matrix Multiplication}, + YEAR = {2025}, +} + +@ONLINE{EN-Hellings2015, + AUTHOR = {Hellings, Jelle}, + DOI = {10.48550/arXiv.1502.02242}, + EPRINT = {1502.02242}, + EPRINTTYPE = {arXiv}, + NOTE = {Version 2, revised 31 January 2016}, + TITLE = {Querying for Paths in Graphs using Context-Free Path Queries}, + URL = {https://arxiv.org/abs/1502.02242}, + URLDATE = {29.08.2026}, + YEAR = {2015}, +} + +@INPROCEEDINGS{EN-RepsHorwitzSagiv1995, + AUTHOR = {Reps, Thomas and Horwitz, Susan and Sagiv, Mooly}, + PUBLISHER = {ACM Press}, + ADDRESS = {New York, NY, USA}, + BOOKTITLE = {Proceedings of the 22nd ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages ({POPL} '95)}, + DOI = {10.1145/199448.199462}, + ISBN = {0-89791-692-1}, + PAGES = {49--61}, + TITLE = {Precise Interprocedural Dataflow Analysis via Graph Reachability}, + YEAR = {1995}, +} + +@SOFTWARE{EN-ShatteredPixelDungeon, + AUTHOR = {Debenham, Evan}, + HOWPUBLISHED = {GitHub repository}, + TITLE = {Shattered Pixel Dungeon}, + URL = {https://github.com/00-Evan/shattered-pixel-dungeon}, + URLDATE = {29.08.2026}, +} + +@SOFTWARE{EN-JaywayJsonPath, + AUTHOR = {{json-path}}, + HOWPUBLISHED = {GitHub repository}, + TITLE = {Jayway {JsonPath}}, + URL = {https://github.com/json-path/JsonPath}, + URLDATE = {29.08.2026}, +} + +@SOFTWARE{EN-CoreJustStackGraphExporter, + AUTHOR = {{CoreJust}}, + HOWPUBLISHED = {GitHub repository}, + TITLE = {Stack Graph Exporter}, + URL = {https://github.com/CoreJust/StackGraphExporter}, + URLDATE = {29.08.2026}, +} + +@INPROCEEDINGS{EN-Creager2023, + AUTHOR = {Creager, Douglas A. and van Antwerpen, Hendrik}, + PUBLISHER = {Schloss Dagstuhl -- Leibniz-Zentrum für Informatik}, + ADDRESS = {Dagstuhl, Germany}, + BOOKTITLE = {Eelco Visser Commemorative Symposium ({EVCS} 2023)}, + DOI = {10.4230/OASIcs.EVCS.2023.8}, + PAGES = {8:1--8:12}, + SERIES = {Open Access Series in Informatics (OASIcs)}, + TITLE = {Stack Graphs: Name Resolution at Scale}, + VOLUME = {109}, + YEAR = {2023}, +} + +@SOFTWARE{EN-JiaoZiVideoPlayer, + AUTHOR = {{lipangit}}, + HOWPUBLISHED = {Archived GitHub repository}, + NOTE = {The repository was archived by its owner; the project moved to JZVideo}, + TITLE = {JiaoZiVideoPlayer}, + URL = {https://github.com/lipangit/JiaoZiVideoPlayer}, + URLDATE = {29.08.2026}, +} + +@SOFTWARE{EN-LibGDX, + AUTHOR = {{libGDX}}, + HOWPUBLISHED = {GitHub repository}, + TITLE = {{libGDX}}, + URL = {https://github.com/libgdx/libgdx}, + URLDATE = {29.08.2026}, +} + +@INPROCEEDINGS{EN-HeLuXue2024, + AUTHOR = {He, Dongjie and Lu, Jingbo and Xue, Jingling}, + EDITOR = {Aldrich, Jonathan and Salvaneschi, Guido}, + PUBLISHER = {Schloss Dagstuhl -- Leibniz-Zentrum für Informatik}, + ADDRESS = {Dagstuhl, Germany}, + BOOKTITLE = {38th European Conference on Object-Oriented Programming ({ECOOP} 2024)}, + DOI = {10.4230/LIPIcs.ECOOP.2024.18}, + ISBN = {978-3-95977-341-6}, + ISSN = {1868-8969}, + PAGES = {18:1--18:29}, + SERIES = {Leibniz International Proceedings in Informatics (LIPIcs)}, + TITLE = {A {CFL}-Reachability Formulation of Callsite-Sensitive Pointer Analysis with Built-In On-The-Fly Call Graph Construction}, + VOLUME = {313}, + YEAR = {2024}, +} + +@INPROCEEDINGS{Neron2015, + AUTHOR = {Néron, Pierre and Tolmach, Andrew P. and Visser, Eelco and Wachsmuth, Guido}, + EDITOR = {Vitek, Jan}, + PUBLISHER = {Springer}, + ADDRESS = {Berlin, Heidelberg}, + BOOKTITLE = {Programming Languages and Systems: 24th European Symposium on Programming, {ESOP} 2015, Held as Part of {ETAPS} 2015, London, UK, April 11--18, 2015, Proceedings}, + DOI = {10.1007/978-3-662-46669-8_9}, + PAGES = {205--231}, + SERIES = {Lecture Notes in Computer Science}, + TITLE = {A Theory of Name Resolution}, + VOLUME = {9032}, + YEAR = {2015}, +} + +@ARTICLE{vanAntwerpen2018, + AUTHOR = {van Antwerpen, Hendrik and Bach Poulsen, Casper and Rouvoet, Arjen and Visser, Eelco}, + PUBLISHER = {Association for Computing Machinery}, + ADDRESS = {New York, NY, USA}, + ARTICLENO = {114}, + DOI = {10.1145/3276484}, + JOURNAL = {Proceedings of the ACM on Programming Languages}, + MONTH = nov, + NUMBER = {OOPSLA}, + PAGES = {1--30}, + TITLE = {Scopes as Types}, + VOLUME = {2}, + YEAR = {2018}, +} + +@INPROCEEDINGS{Zwaan2023, + AUTHOR = {Zwaan, Aron and van Antwerpen, Hendrik}, + PUBLISHER = {Schloss Dagstuhl -- Leibniz-Zentrum für Informatik}, + ADDRESS = {Dagstuhl, Germany}, + BOOKTITLE = {Eelco Visser Commemorative Symposium ({EVCS} 2023)}, + DOI = {10.4230/OASIcs.EVCS.2023.32}, + PAGES = {32:1--32:13}, + SERIES = {Open Access Series in Informatics (OASIcs)}, + TITLE = {Scope Graphs: The Story so Far}, + VOLUME = {109}, + YEAR = {2023}, +} + +@INPROCEEDINGS{Creager2023, + AUTHOR = {Creager, Douglas A. and van Antwerpen, Hendrik}, + PUBLISHER = {Schloss Dagstuhl -- Leibniz-Zentrum für Informatik}, + ADDRESS = {Dagstuhl, Germany}, + BOOKTITLE = {Eelco Visser Commemorative Symposium ({EVCS} 2023)}, + DOI = {10.4230/OASIcs.EVCS.2023.8}, + PAGES = {8:1--8:12}, + SERIES = {Open Access Series in Informatics (OASIcs)}, + TITLE = {Stack Graphs: Name Resolution at Scale}, + VOLUME = {109}, + YEAR = {2023}, +} + +@INPROCEEDINGS{RepsHorwitzSagiv1995, + AUTHOR = {Reps, Thomas and Horwitz, Susan and Sagiv, Mooly}, + PUBLISHER = {ACM Press}, + ADDRESS = {New York, NY, USA}, + BOOKTITLE = {Proceedings of the 22nd ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages ({POPL} '95)}, + DOI = {10.1145/199448.199462}, + ISBN = {0-89791-692-1}, + PAGES = {49--61}, + TITLE = {Precise Interprocedural Dataflow Analysis via Graph Reachability}, + YEAR = {1995}, +} + +@ONLINE{Hellings2015, + AUTHOR = {Hellings, Jelle}, + DOI = {10.48550/arXiv.1502.02242}, + EPRINT = {1502.02242}, + EPRINTTYPE = {arXiv}, + NOTE = {Version 2, revised 31 January 2016}, + TITLE = {Querying for Paths in Graphs using Context-Free Path Queries}, + URL = {https://arxiv.org/abs/1502.02242}, + URLDATE = {29.08.2026}, + YEAR = {2015}, +} + +@INPROCEEDINGS{HeLuXue2024, + AUTHOR = {He, Dongjie and Lu, Jingbo and Xue, Jingling}, + EDITOR = {Aldrich, Jonathan and Salvaneschi, Guido}, + PUBLISHER = {Schloss Dagstuhl -- Leibniz-Zentrum für Informatik}, + ADDRESS = {Dagstuhl, Germany}, + BOOKTITLE = {38th European Conference on Object-Oriented Programming ({ECOOP} 2024)}, + DOI = {10.4230/LIPIcs.ECOOP.2024.18}, + ISBN = {978-3-95977-341-6}, + ISSN = {1868-8969}, + PAGES = {18:1--18:29}, + SERIES = {Leibniz International Proceedings in Informatics (LIPIcs)}, + TITLE = {A {CFL}-Reachability Formulation of Callsite-Sensitive Pointer Analysis with Built-In On-The-Fly Call Graph Construction}, + VOLUME = {313}, + YEAR = {2024}, +} + +@INPROCEEDINGS{MuravevGrigorev2025, + AUTHOR = {Muravev, Ilia and Grigorev, Semyon}, + PUBLISHER = {Association for Computing Machinery}, + ADDRESS = {New York, NY, USA}, + BOOKTITLE = {Proceedings of the 14th ACM SIGPLAN International Workshop on the State Of the Art in Program Analysis ({SOAP} '25)}, + DOI = {10.1145/3735544.3735585}, + ISBN = {979-8-4007-1922-6}, + PAGES = {28--35}, + TITLE = {Universal High-Performance {CFL}-Reachability via Matrix Multiplication}, + YEAR = {2025}, +} + +@SOFTWARE{CoreJustStackGraphExporter, + AUTHOR = {{CoreJust}}, + HOWPUBLISHED = {GitHub repository}, + TITLE = {Stack Graph Exporter}, + URL = {https://github.com/CoreJust/StackGraphExporter}, + URLDATE = {29.08.2026}, +} + +@SOFTWARE{LibGDX, + AUTHOR = {{libGDX}}, + HOWPUBLISHED = {GitHub repository}, + TITLE = {{libGDX}}, + URL = {https://github.com/libgdx/libgdx}, + URLDATE = {29.08.2026}, +} + +@SOFTWARE{ShatteredPixelDungeon, + AUTHOR = {Debenham, Evan}, + HOWPUBLISHED = {GitHub repository}, + TITLE = {Shattered Pixel Dungeon}, + URL = {https://github.com/00-Evan/shattered-pixel-dungeon}, + URLDATE = {29.08.2026}, +} + +@SOFTWARE{JaywayJsonPath, + AUTHOR = {{json-path}}, + HOWPUBLISHED = {GitHub repository}, + TITLE = {Jayway {JsonPath}}, + URL = {https://github.com/json-path/JsonPath}, + URLDATE = {29.08.2026}, +} + +@SOFTWARE{JiaoZiVideoPlayer, + AUTHOR = {{lipangit}}, + HOWPUBLISHED = {Archived GitHub repository}, + NOTE = {The repository was archived by its owner; the project moved to JZVideo}, + TITLE = {JiaoZiVideoPlayer}, + URL = {https://github.com/lipangit/JiaoZiVideoPlayer}, + URLDATE = {29.08.2026}, +} + diff --git a/InProgress/StackGraphs_to_CFL_Reachability/references-en-prefixed.bib b/InProgress/StackGraphs_to_CFL_Reachability/references-en-prefixed.bib new file mode 100644 index 00000000..e69de29b diff --git a/InProgress/StackGraphs_to_CFL_Reachability/references.bib b/InProgress/StackGraphs_to_CFL_Reachability/references.bib new file mode 100644 index 00000000..9f18b83e --- /dev/null +++ b/InProgress/StackGraphs_to_CFL_Reachability/references.bib @@ -0,0 +1,153 @@ +% Sources cited in the article, in order of first citation. +% Metadata was checked against the publisher record or the official repository +% on 2026-08-29. Originally English-language sources are not duplicated in +% references-en.bib; the KIO preprocessing step creates EN-* clones. + +@inproceedings{Neron2015, + author = {N{\'e}ron, Pierre and Tolmach, Andrew P. and Visser, Eelco and Wachsmuth, Guido}, + title = {A Theory of Name Resolution}, + editor = {Vitek, Jan}, + booktitle = {Programming Languages and Systems: 24th European Symposium on Programming, {ESOP} 2015, Held as Part of {ETAPS} 2015, London, UK, April 11--18, 2015, Proceedings}, + series = {Lecture Notes in Computer Science}, + volume = {9032}, + pages = {205--231}, + year = {2015}, + publisher = {Springer}, + address = {Berlin, Heidelberg}, + doi = {10.1007/978-3-662-46669-8_9} +} + +@article{vanAntwerpen2018, + author = {van Antwerpen, Hendrik and Bach Poulsen, Casper and Rouvoet, Arjen and Visser, Eelco}, + title = {Scopes as Types}, + journal = {Proceedings of the ACM on Programming Languages}, + volume = {2}, + number = {OOPSLA}, + articleno = {114}, + pages = {1--30}, + numpages = {30}, + month = nov, + year = {2018}, + publisher = {Association for Computing Machinery}, + address = {New York, NY, USA}, + doi = {10.1145/3276484} +} + +@inproceedings{Zwaan2023, + author = {Zwaan, Aron and van Antwerpen, Hendrik}, + title = {Scope Graphs: The Story so Far}, + booktitle = {Eelco Visser Commemorative Symposium ({EVCS} 2023)}, + series = {Open Access Series in Informatics (OASIcs)}, + volume = {109}, + pages = {32:1--32:13}, + year = {2023}, + publisher = {Schloss Dagstuhl -- Leibniz-Zentrum f{\"u}r Informatik}, + address = {Dagstuhl, Germany}, + doi = {10.4230/OASIcs.EVCS.2023.32} +} + +@inproceedings{Creager2023, + author = {Creager, Douglas A. and van Antwerpen, Hendrik}, + title = {Stack Graphs: Name Resolution at Scale}, + booktitle = {Eelco Visser Commemorative Symposium ({EVCS} 2023)}, + series = {Open Access Series in Informatics (OASIcs)}, + volume = {109}, + pages = {8:1--8:12}, + year = {2023}, + publisher = {Schloss Dagstuhl -- Leibniz-Zentrum f{\"u}r Informatik}, + address = {Dagstuhl, Germany}, + doi = {10.4230/OASIcs.EVCS.2023.8} +} + +@inproceedings{RepsHorwitzSagiv1995, + author = {Reps, Thomas and Horwitz, Susan and Sagiv, Mooly}, + title = {Precise Interprocedural Dataflow Analysis via Graph Reachability}, + booktitle = {Proceedings of the 22nd ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages ({POPL} '95)}, + pages = {49--61}, + year = {1995}, + publisher = {ACM Press}, + address = {New York, NY, USA}, + isbn = {0-89791-692-1}, + doi = {10.1145/199448.199462} +} + +@online{Hellings2015, + author = {Hellings, Jelle}, + title = {Querying for Paths in Graphs using Context-Free Path Queries}, + year = {2015}, + eprint = {1502.02242}, + eprinttype = {arXiv}, + doi = {10.48550/arXiv.1502.02242}, + url = {https://arxiv.org/abs/1502.02242}, + urldate = {29.08.2026}, + note = {Version 2, revised 31 January 2016} +} + +@inproceedings{HeLuXue2024, + author = {He, Dongjie and Lu, Jingbo and Xue, Jingling}, + title = {A {CFL}-Reachability Formulation of Callsite-Sensitive Pointer Analysis with Built-In On-The-Fly Call Graph Construction}, + booktitle = {38th European Conference on Object-Oriented Programming ({ECOOP} 2024)}, + series = {Leibniz International Proceedings in Informatics (LIPIcs)}, + volume = {313}, + pages = {18:1--18:29}, + year = {2024}, + editor = {Aldrich, Jonathan and Salvaneschi, Guido}, + publisher = {Schloss Dagstuhl -- Leibniz-Zentrum f{\"u}r Informatik}, + address = {Dagstuhl, Germany}, + isbn = {978-3-95977-341-6}, + issn = {1868-8969}, + doi = {10.4230/LIPIcs.ECOOP.2024.18} +} + +@inproceedings{MuravevGrigorev2025, + author = {Muravev, Ilia and Grigorev, Semyon}, + title = {Universal High-Performance {CFL}-Reachability via Matrix Multiplication}, + booktitle = {Proceedings of the 14th ACM SIGPLAN International Workshop on the State Of the Art in Program Analysis ({SOAP} '25)}, + pages = {28--35}, + year = {2025}, + publisher = {Association for Computing Machinery}, + address = {New York, NY, USA}, + isbn = {979-8-4007-1922-6}, + doi = {10.1145/3735544.3735585} +} + +@software{CoreJustStackGraphExporter, + author = {{CoreJust}}, + title = {Stack Graph Exporter}, + howpublished = {GitHub repository}, + url = {https://github.com/CoreJust/StackGraphExporter}, + urldate = {29.08.2026} +} + +@software{LibGDX, + author = {{libGDX}}, + title = {{libGDX}}, + howpublished = {GitHub repository}, + url = {https://github.com/libgdx/libgdx}, + urldate = {29.08.2026} +} + +@software{ShatteredPixelDungeon, + author = {Debenham, Evan}, + title = {Shattered Pixel Dungeon}, + howpublished = {GitHub repository}, + url = {https://github.com/00-Evan/shattered-pixel-dungeon}, + urldate = {29.08.2026} +} + +@software{JaywayJsonPath, + author = {{json-path}}, + title = {Jayway {JsonPath}}, + howpublished = {GitHub repository}, + url = {https://github.com/json-path/JsonPath}, + urldate = {29.08.2026} +} + +@software{JiaoZiVideoPlayer, + author = {{lipangit}}, + title = {JiaoZiVideoPlayer}, + howpublished = {Archived GitHub repository}, + url = {https://github.com/lipangit/JiaoZiVideoPlayer}, + urldate = {29.08.2026}, + note = {The repository was archived by its owner; the project moved to JZVideo} +} diff --git a/InProgress/StackGraphs_to_CFL_Reachability/ugost2008.bst b/InProgress/StackGraphs_to_CFL_Reachability/ugost2008.bst new file mode 100644 index 00000000..cb205a19 --- /dev/null +++ b/InProgress/StackGraphs_to_CFL_Reachability/ugost2008.bst @@ -0,0 +1,3131 @@ +%% +%% This is file `ugost2008.bst', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% gost.dtx (with options: `bst,utf8,eprint') +%% +%% IMPORTANT NOTICE: +%% +%% For the copyright see the source file. +%% +%% Any modified versions of this file must be renamed +%% with new filenames distinct from ugost2008.bst. +%% +%% For distribution of the original source see the terms +%% for copying and modification in the file gost.dtx. +%% +%% This generated file may be distributed as long as the +%% original source files, as listed above, are part of the +%% same distribution. (The sources need not necessarily be +%% in the same archive or directory.) +%% This bibstyle attempts to format bibliography according to +%% GOST 7.0.5-2008 for bibliographic reference. + +ENTRY + { address + annote + author + booktitle + bookauthor + chapter + edition + editor + compiler + howpublished + institution + journal + key + %major % new in v.1.2i, alias for speciality, not implemented + majorcode % new in v.1.2i, alias for specialitycode + month + note + number + organization + pages + eid % new in v1.2c + publisher + school % alias for institution + series + %speciality % new in v.1.2i, eqv. to major in biblatex-gost, not implemented yet... + specialitycode % new in v.1.2i, alias of number, eqv. to majorcode in biblatex-gost + title + %medium % new in v1.2; renamed to media. + media % new in v1.2f + type + volume + year + language + langid % new in v1.2c + booklanguage + date % new in v1.2i + pagetotal + url + urldate + isbn + doi + eprint + eprinttype % = archivePrefix + eprintclass % = primaryClass + % new in v1.2f: + % appear in biblatex: + %addendum % not implemented yet... + holder % see patent + location % new in v.1.2i, alias of address + %subtitle % not implemented yet... + titleaddon % new in v.1.2i, see @thesis + %version % not implemented yet... + % Appear in biblatex-gost for @patent entry: + authorcountry % country of the patent authors + nationality % patent-issuing country (used by IEEE.bst's @patent) + credits % statement of responsibility, other than provided in Biblatex + ipc % Code of the International Patent Classification + %media % General material designation NOTE: medium in the above + requestnumber % Registration number of the application to the patent document + publicationdate % Date of publication + publication % and information on the official gazette, which published patent + prioritydate % Information about the convention priority: the date of filing of the application, + prioritynumber % number and + prioritycountry % country name of convention priority. + requestdate % ?? + } + {} + { label } + +INTEGERS { + output.state + before.all + mid.sentence + after.sentence + after.block + after.dblslash + after.slash + after.colon + after.semicolon +} + +STRINGS { curlanguage } + +STRINGS { s t } + +STRINGS { y m d } % new in v.1.2j +STRINGS { ud.y ud.m ud.d ud.tmp ud.parsed } +INTEGERS { ud.idx ud.len ud.space.pos } + +FUNCTION {init.state.consts} +{ #0 'before.all := + #1 'mid.sentence := + #2 'after.sentence := + #3 'after.block := + #4 'after.dblslash := + #5 'after.slash := + #6 'after.colon := + #7 'after.semicolon := +} + +FUNCTION {set.language} +{ langid empty$ + { language empty$ + { "english" 'curlanguage := } + { language 'curlanguage := } + if$ + } + { langid 'curlanguage := } + if$ +} + +FUNCTION {reset.language} +{ booklanguage empty$ + { "" } + { booklanguage 'curlanguage := + "\selectlanguageifdefined{" + curlanguage * + "}" * + } + if$ +} + +FUNCTION {output.nonnull} +{ + swap$ + output.state mid.sentence = + { ", " * write$ } + { output.state after.block = + { add.period$ write$ + " " write$ + newline$ + "\newblock " write$ + } + { output.state before.all = + 'write$ + { output.state after.dblslash = + { "~//" * reset.language * " " * write$ } + { output.state after.slash = + { "~/ " * write$ } + { output.state after.colon = + { ": " * write$ } + { output.state after.semicolon = + { "; " * write$ } + { add.period$ " " * write$ } + if$ + } + if$ + } + if$ + } + if$ + } + if$ + } + if$ + mid.sentence 'output.state := + } + if$ +} + +FUNCTION {output} +{ duplicate$ empty$ + 'pop$ + 'output.nonnull + if$ +} + +FUNCTION {output.check} +{ 't := + duplicate$ empty$ + { pop$ + "empty " t * " in " * cite$ * warning$ + } + 'output.nonnull + if$ +} + +FUNCTION {fin.entry} +{ add.period$ + write$ + newline$ +} + +FUNCTION {new.block} +{ output.state before.all = + 'skip$ + { after.block 'output.state := } + if$ +} + +FUNCTION {new.dblslash} +{ output.state before.all = + 'skip$ + { after.dblslash 'output.state := } + if$ +} + +FUNCTION {new.slash} +{ output.state before.all = + 'skip$ + { after.slash 'output.state := } + if$ +} + +FUNCTION {new.colon} +{ output.state before.all = + 'skip$ + { after.colon 'output.state := } + if$ +} + +FUNCTION {new.semicolon} +{ output.state before.all = + 'skip$ + { after.semicolon 'output.state := } + if$ +} + +FUNCTION {new.sentence} +{ output.state after.block = + 'skip$ + { output.state before.all = + 'skip$ + { after.sentence 'output.state := } + if$ + } + if$ +} + +FUNCTION {add.blank} +{ " " * before.all 'output.state := +} + +FUNCTION {not} +{ { #0 } + { #1 } + if$ +} + +FUNCTION {and} +{ 'skip$ + { pop$ #0 } + if$ +} + +FUNCTION {or} +{ { pop$ #1 } + 'skip$ + if$ +} + +FUNCTION {new.block.checka} +{ empty$ + 'skip$ + 'new.block + if$ +} + +FUNCTION {new.block.checkb} +{ empty$ + swap$ empty$ + and + 'skip$ + 'new.block + if$ +} + +FUNCTION {new.sentence.checka} +{ empty$ + 'skip$ + 'new.sentence + if$ +} + +FUNCTION {new.sentence.checkb} +{ empty$ + swap$ empty$ + and + 'skip$ + 'new.sentence + if$ +} + +FUNCTION {new.dblslash.checka} +{ empty$ + 'skip$ + 'new.dblslash + if$ +} + +FUNCTION {field.or.null} +{ duplicate$ empty$ + { pop$ "" } + 'skip$ + if$ +} + +%% +FUNCTION {either.or.check} +{ empty$ + 'pop$ + { "can't use both " swap$ * " fields in " * cite$ * warning$ } + if$ +} + +FUNCTION {spaces.around} +{ " " swap$ * " " * } + +FUNCTION {emphasize} +{ duplicate$ empty$ + %{ pop$ "" } + 'skip$ % v.1.2k + { "\BibEmph{" swap$ * "}" * } + if$ +} + +FUNCTION {bracify} +{ duplicate$ empty$ + { pop$ "{}" } + { "{" swap$ * "}" * } + if$ +} + +FUNCTION {bracketise} +{ + duplicate$ empty$ + { pop$ "" } + { "[" swap$ * "]" * } + if$ +} + +FUNCTION {paranthesify} +{ + duplicate$ empty$ + { pop$ "" } + { "(" swap$ * ")" * } + if$ +} + + +FUNCTION {tie.connect} + {"~" swap$ * * + } + +FUNCTION {tie.or.space.connect} +{ duplicate$ text.length$ #3 < + { "~" } + { " " } + if$ + swap$ * * +} + +FUNCTION {n.dashify} +{ 't := + "" + { t empty$ not } + { t #1 #1 substring$ "-" = + { t #1 #2 substring$ "--" = not + { "--" * + t #2 global.max$ substring$ 't := + } + { { t #1 #1 substring$ "-" = } + { "-" * + t #2 global.max$ substring$ 't := + } + while$ + } + if$ + } + { t #1 #1 substring$ * + t #2 global.max$ substring$ 't := + } + if$ + } + while$ +} + +INTEGERS { multiresult } + +FUNCTION {multi.page.check} +{ 't := + #0 'multiresult := + { multiresult not + t empty$ not + and + } + { t #1 #1 substring$ + duplicate$ "-" = + swap$ duplicate$ "," = + swap$ "+" = + or or + { #1 'multiresult := } + { t #2 global.max$ substring$ 't := } + if$ + } + while$ + multiresult +} + +FUNCTION {bbl.edby} +{ curlanguage "english" = + {"ed.\ by"} + { curlanguage "russian" = + {"под ред."} + { curlanguage "german" = + { "ed." } + {"language is not defined: " curlanguage " in bbl.edby" * * warning$ "Ed.\ by"} + if$} + if$} +if$} + +FUNCTION {bbl.compiler} +{ curlanguage "english" = + { "Compiler"} + { curlanguage "german" = + { "Hrsg." } + { curlanguage "russian" = + {"{Сост.}"} + {"language is not defined: " curlanguage " in bbl.compiler" * * warning$ "Compiler"} + if$} + if$} +if$} + +FUNCTION {bbl.edition} +{ curlanguage "english" = + {"ed."} + { curlanguage "russian" = + {"{изд.}"} + { curlanguage "german" = + {" {aus.}" } %%%% { "Aufl." } ?? + { curlanguage "italian" = + {"edizione"} + { curlanguage "french" = + {"\'{e}dition"} + {"language is not defined: " curlanguage " in bbl.edition" * * warning$ "ed."} + if$} + if$} + if$} + if$} +if$} + +FUNCTION {bbl.vvolume} +{ curlanguage "english" = curlanguage "french" = or curlanguage "italian" = or + {"Volume"} + { curlanguage "russian" = + { "Том" } + { curlanguage "german" = + {"{Band}"} %%%% { "Volumen" } + {"language is not defined: " curlanguage " in bbl.vvolume" * * warning$ "Volume"} + if$} + if$} +if$} + +FUNCTION {bbl.vvol} +{ curlanguage "english" = curlanguage "french" = or curlanguage "italian" = or + {"Vol."} + { curlanguage "russian" = + {"Т."} + { curlanguage "german" = + {"{Bd.}"} %%%% { "Vol." } + {"language is not defined: " curlanguage " in bbl.vvol" * * warning$ "Vol."} + if$} + if$} +if$} + +FUNCTION {bbl.iissue} +{ curlanguage "english" = + {"Issue"} + { curlanguage "russian" = + {"Выпуск"} + { curlanguage "german" = + {"{Heft}"} %%%% { "Ausgabe" } + {"language is not defined: " curlanguage " in bbl.iissue" * * warning$ "Issue"} + if$} + if$} +if$} + +FUNCTION {bbl.iiss} +{ curlanguage "english" = + {"Iss."} + { curlanguage "russian" = + {"Вып."} + { curlanguage "german" = + {"{H.}"} + {"language is not defined: " curlanguage " in bbl.iiss" * * warning$ "Iss."} + if$} + if$} +if$} + +FUNCTION {bbl.of} +{ curlanguage "english" = + {"of"} + { curlanguage "german" = + { "von" } + { curlanguage "russian" = + { "из" } + {"language is not defined: " curlanguage " in bbl.of" * * warning$ "of"} + if$} + if$} +if$} + +FUNCTION {bbl.etal} +{ curlanguage "english" = + {"et~al."} + { curlanguage "german" = + { "u.~a." } + { curlanguage "russian" = + {"и~др."} + {"language is not defined: " curlanguage " in bbl.etal" * * warning$ "et~al."} + if$} + if$} +if$} + +FUNCTION {bbl.and} +{ curlanguage "english" = + {"and"} + { curlanguage "german" = + { "und" } + { curlanguage "russian" = + {"и"} + { curlanguage "french" = + {"et"} + {"language is not defined: " curlanguage " in bbl.and" * * warning$ "and"} + if$} + if$} + if$} +if$} + +FUNCTION {bbl.nnumber} +{ curlanguage "english" = + {"Number"} + { curlanguage "russian" = + { "Номер" } + { curlanguage "german" = + {"{Heft}"} %%% { "Anzahl" } + {"language is not defined: " curlanguage " in bbl.nnumber" * * warning$ "Number"} + if$} + if$} +if$} + +FUNCTION {bbl.number} +{ curlanguage "english" = + {"number"} + { curlanguage "russian" = + {"номер"} + { curlanguage "german" = + {"{Heft}"} %%% { "anzahl" }??? + {"language is not defined: " curlanguage " in bbl.number" * * warning$ "number"} + if$} + if$} +if$} + +FUNCTION {bbl.nr} +{ curlanguage "english" = + {"no."} + { curlanguage "italian" = + { "no." } + { curlanguage "russian" = + { "№" } + { curlanguage "german" = + {"{nu.}"} %%% { "an." } + { curlanguage "french" = + { "no." } + {"language is not defined: " curlanguage " in bbl.nr" * * warning$ "no."} + if$} + if$} + if$} + if$} +if$} + +FUNCTION {bbl.nnr} +{ curlanguage "english" = + {"No."} + { curlanguage "russian" = + { "№" } + { curlanguage "german" = + {"{H.}"} %%% { "an." } + {"language is not defined: " curlanguage " in bbl.nnr" * * warning$ "No."} + if$} + if$} +if$} + +FUNCTION {bbl.in} +{ curlanguage "english" = curlanguage "german" = or + {"in"} + { curlanguage "russian" = + { "в" } + {"language is not defined: " curlanguage " in bbl.in" * * warning$ "in"} + if$} +if$} + +FUNCTION {bbl.iin} +{ curlanguage "english" = curlanguage "german" = or + {"In"} + { curlanguage "russian" = + { "В" } + {"language is not defined: " curlanguage " in bbl.iin" * * warning$ "In"} + if$} +if$} + +FUNCTION {bbl.pages} +{ curlanguage "english" = curlanguage "french" = or curlanguage "italian" = or + {"p."} %%% {"pp."} + { curlanguage "russian" = + {"с."} + { curlanguage "german" = + {"S."} %%%% { "s." } + {"language is not defined: " curlanguage " in bbl.pages" * * warning$ "p."} + if$} + if$} +if$} + +FUNCTION {bbl.page} +{ curlanguage "english" = curlanguage "french" = or curlanguage "italian" = or + {"p."} + { curlanguage "russian" = + {"c."} + { curlanguage "german" = + {"S."} %%%% { "s." } + {"language is not defined: " curlanguage " in bbl.page" * * warning$ "p."} + if$} + if$} +if$} + +FUNCTION {bbl.ppages} +{ curlanguage "english" = curlanguage "french" = or curlanguage "italian" = or + {"P."} %%%% { "Pp." } + { curlanguage "russian" = + {"C."} + { curlanguage "german" = + {"S."} + {"language is not defined: " curlanguage " in bbl.ppages" * * warning$ "P."} + if$} + if$} +if$} + +FUNCTION {bbl.ppage} +{ curlanguage "english" = curlanguage "french" = or curlanguage "italian" = or + {"P."} + { curlanguage "russian" = + {"C."} + { curlanguage "german" = + {"S."} + {"language is not defined: " curlanguage " in bbl.ppage" * * warning$ "P."} + if$} + if$} +if$} + +FUNCTION {bbl.url} +{ curlanguage "english" = + {"URL"} + { curlanguage "russian" = + { "URL" } + { curlanguage "german" = + { "URL" } + { curlanguage "french" = + { "URL" } + { "language is not defined: " curlanguage " in bbl.url" * * warning$ "online; accessed" } + if$} + if$} + if$} +if$} +FUNCTION {bbl.urldate} +{ curlanguage "english" = + {"online; accessed"} + { curlanguage "russian" = + { "{дата~обращения}" } + { curlanguage "german" = + { "{online; abgerufen}" } + { curlanguage "french" = + { "{en ligne; acc\'{e}d\'{e}}" } + { "language is not defined: " curlanguage " in bbl.urldate" * * warning$ "online; accessed" } + if$} + if$} + if$} +if$} + +% Localised default word for the "Patent" label used by @patent. +FUNCTION {bbl.patent} +{ curlanguage "english" = + { "Patent" } + { curlanguage "russian" = + { "{Патент}" } + { curlanguage "german" = + { "Patent" } + { curlanguage "french" = + { "Brevet" } + { "language is not defined: " curlanguage " in bbl.patent" * * warning$ "Patent" } + if$ + } + if$ + } + if$ + } +if$} + + +FUNCTION {bbl.techreport} +{ curlanguage "english" = + { "Rep." } + { curlanguage "german" = + { "Bericht" } + { curlanguage "russian" = + { "{Отчет}" } + { "language is not defined: " curlanguage " in bbl.techrep" * * warning$ "Rep." } + if$} + if$} +if$} + +FUNCTION {bbl.mathesis} +{ curlanguage "english" = + { "Master's thesis" } + { curlanguage "german" = + { "diss.~mag." } + { curlanguage "russian" = + { "{квалификационная~работа~магистра}" } + { "language is not defined: " curlanguage " in bbl.mthesis" * * warning$ "Master's thesis" } + if$} + if$} +if$} + +FUNCTION {bbl.phdthesis} +{ curlanguage "english" = + { "Ph.\,D. thesis" } + { curlanguage "german" = + { "diss.~Ph.\,D." } + { curlanguage "russian" = + { "{дис.\ \ldots\ канд.\ наук}" } + { curlanguage "french" = + { "th\`{e}se de doctorat" } + { "language is not defined: " curlanguage " in bbl.phdthesis" * * warning$ "Ph.\,D. thesis" } + if$} + if$} + if$} +if$} + +FUNCTION {bbl.docthesis} +{ curlanguage "english" = + { "dr.\,sci. dissertation" } + { curlanguage "german" = + { "diss.~dr." } + { curlanguage "russian" = + { "{дис.\ \ldots\ д-ра наук}" } + { "language is not defined: " curlanguage " in bbl.docthesis" * * warning$ "Dr.\,Sci. dissertation" } + if$} + if$} +if$} + +FUNCTION {bbl.nnoaddress} +{ curlanguage "english" = + { "S.\ l." } + { curlanguage "russian" = + { "{Б.\ м.}" } + { "language is not defined: " curlanguage " in bbl.nnoaddress" * * warning$ "S.\ l." } + if$} +if$} + +FUNCTION {bbl.nopublisher} +{ curlanguage "english" = + { "s.\ n." } + { curlanguage "russian" = + { "{б.\ и.}" } + { "language is not defined: " curlanguage " in bbl.nnopublisher" * * warning$ "s.\ n." } + if$} +if$} + +FUNCTION {bbl.nnopublisher} +{ curlanguage "english" = + { "S.\ n." } + { curlanguage "russian" = + { "{Б.\ и.}" } + { "language is not defined: " curlanguage " in bbl.nnopublisher" * * warning$ "S.\ n." } + if$} +if$} + +FUNCTION {bbl.media.text} +{ curlanguage "english" = + { "Text" } + { curlanguage "russian" = + { "{Текст}" } + { "language is not defined: " curlanguage " in bbl.media" * * warning$ "Text" } + if$} +if$} + +FUNCTION {bbl.media.eresource} +{ curlanguage "english" = + { "Electronic resource" } + { curlanguage "russian" = + { "Электронный ресурс" } + { "language is not defined: " curlanguage " in bbl.media" * * warning$ "Electronic resource" } + if$} +if$} + +FUNCTION {bbl.media.online} +{ curlanguage "english" = + { "Electronic resource online" } + { curlanguage "russian" = + { "Электронный ресурс онлайн" } + { "language is not defined: " curlanguage " in bbl.media" * * warning$ "Electronic resource" } + if$} +if$} + +FUNCTION {bbl.chief} +{ curlanguage "english" = + { "chief" } + { curlanguage "russian" = + { "рук." } + { "language is not defined: " curlanguage " in bbl.chief" * * warning$ "chief" } + if$} +if$} + +FUNCTION {bbl.executor} +{ curlanguage "english" = + { "authors" } + { curlanguage "russian" = + { "авторы" } + { "language is not defined: " curlanguage " in bbl.executor" * * warning$ "executor" } + if$} +if$} + +FUNCTION {bbl.media} +{ media "online" = + { bbl.media.online } + { media "eresource" = + { bbl.media.eresource } + { bbl.media.text } + if$} +if$} + +FUNCTION {bbl.video.bracket} +{ curlanguage "russian" = + { "[видео]" } + { "[video]" } + if$ + } + + +FUNCTION {bbl.software.developer} +{ curlanguage "russian" = + { "разработчик" } + { "developer" } + if$ + } + + +FUNCTION {bbl.software.kind} +{ curlanguage "russian" = + { "Электронная программа" } + { "Electronic program" } + if$ + } + +FUNCTION {bbl.software.subkind} +{ curlanguage "russian" = + { "электронная" } + { "electronic" } + if$ + } + +FUNCTION {bbl.dataset.kind} +{ curlanguage "russian" = + { "база данных" } + { "database" } + if$ + } + + +FUNCTION {bbl.standard.developed} +{ curlanguage "russian" = + { "разработан" } + { "developed by" } + if$ + } + +FUNCTION {bbl.standard.material} +{ curlanguage "russian" = + { "Текст : непосредственный" } + { "Text : direct" } + if$ + } + +FUNCTION {bbl.req} +{ + curlanguage "english" = + { "req." } + { curlanguage "german" = + { "ang." } + { curlanguage "russian" = + { "заявл." } + { "language is not defined: " curlanguage " in bbl.req" * * warning$ "req" } + if$ + } + if$ + } + if$ +} + +FUNCTION {bbl.publ} +{ + curlanguage "english" = + { "publ." } + { curlanguage "german" = + { "ausg." } + { curlanguage "russian" = + { "опубл." } + { "language is not defined: " curlanguage " in bbl.publication" * * warning$ "publication" } + if$ + } + if$ + } + if$ +} + +FUNCTION {bbl.priority} +{ + curlanguage "english" = + { "priority" } + { curlanguage "german" = + { "Prioritat" } + { curlanguage "russian" = + { "приоритет" } + { "language is not defined: " curlanguage " in bbl.priority" * * warning$ "priority" } + if$ + } + if$ + } + if$ +} + +FUNCTION {bbl.jan} +{ curlanguage "english" = + {"Jan."} + { curlanguage "russian" = + { "Янв." } + { curlanguage "german" = + { "Jan." } % Januar + { "language is not defined: bbl.jan for " curlanguage * warning$ "Jan." } + if$} + if$} +if$} + +FUNCTION {bbl.feb} +{ curlanguage "english" = + {"Feb."} + { curlanguage "russian" = + { "Фев." } + { curlanguage "german" = + {"Feb."} % Februar + {"language is not defined: bbl.feb for " curlanguage * warning$ "Feb."} + if$} + if$} +if$} + +FUNCTION {bbl.mar} +{ curlanguage "english" = + {"Mar."} + { curlanguage "russian" = + { "Март" } + { curlanguage "german" = + {"M^^c3^^a4rz"} % M^^c3^^a4rz + {"language is not defined: bbl.mar for " curlanguage * warning$ "Mar."} + if$} + if$} +if$} + +FUNCTION {bbl.apr} +{ curlanguage "english" = + {"Apr."} + { curlanguage "russian" = + { "Апр." } + { curlanguage "german" = + {"Apr."} % April + { "language is not defined: bbl.apr for " curlanguage * warning$ "Apr." } + if$} + if$} +if$} + +FUNCTION {bbl.may} +{ curlanguage "english" = + {"May"} + { curlanguage "russian" = + { "Май" } + { curlanguage "german" = + {"Mai"} + { "language is not defined: bbl.may for " curlanguage * warning$ "May" } + if$} + if$} +if$} + +FUNCTION {bbl.jun} +{ curlanguage "english" = + {"June"} + { curlanguage "russian" = + { "Июнь" } + { curlanguage "german" = + {"Juni"} + { "language is not defined: bbl.jun for " curlanguage * warning$ "June" } + if$} + if$} +if$} + +FUNCTION {bbl.jul} +{ curlanguage "english" = + {"July"} + { curlanguage "russian" = + { "Июль" } + { curlanguage "german" = + {"Juli"} + { "language is not defined: bbl.jul for " curlanguage * warning$ "July" } + if$} + if$} +if$} + +FUNCTION {bbl.aug} +{ curlanguage "english" = + {"Aug."} + { curlanguage "russian" = + { "Авг." } + { curlanguage "german" = + {"Aug."} % August + { "language is not defined: bbl.aug for " curlanguage * warning$ "Aug." } + if$} + if$} +if$} + +FUNCTION {bbl.sep} +{ curlanguage "english" = + {"Sep."} + { curlanguage "russian" = + { "Сен." } + { curlanguage "german" = + {"Sep."} % September + { "language is not defined: bbl.sep for " curlanguage * warning$ "Sep." } + if$} + if$} +if$} + +FUNCTION {bbl.oct} +{ curlanguage "english" = + {"Oct."} + { curlanguage "russian" = + { "Окт." } + { curlanguage "german" = + {"Okt."} % Oktober + { "language is not defined: bbl.oct for " curlanguage * warning$ "Oct." } + if$} + if$} +if$} + +FUNCTION {bbl.nov} +{ curlanguage "english" = + {"Nov."} + { curlanguage "russian" = + { "Ноя." } + { curlanguage "german" = + {"Nov."} % November + { "language is not defined: bbl.nov for " curlanguage * warning$ "Nov." } + if$} + if$} +if$} + +FUNCTION {bbl.dec} +{ curlanguage "english" = + {"Dec."} + { curlanguage "russian" = + { "Дек." } + { curlanguage "german" = + {"Dez."} % Dezember + { "language is not defined: bbl.dec for " curlanguage * warning$ "Dec." } + if$} + if$} +if$} +FUNCTION {bbl.arxiv} +{ curlanguage "english" = + { "ArXiv" } + { curlanguage "russian" = + { "ArXiv" } + { curlanguage "german" = + { "ArXiv" } + { "language is not defined: bbl.arxiv for " curlanguage * warning$ "ArXiv" } + if$} + if$} +if$} + +FUNCTION {bbl.jstor} +{ curlanguage "english" = + { "JSTOR" } + { curlanguage "russian" = + { "JSTOR" } + { curlanguage "german" = + { "JSTOR" } + { "language is not defined: bbl.jstor for " curlanguage * warning$ "JSTOR" } + if$} + if$} +if$} + +FUNCTION {bbl.pubmed} +{ curlanguage "english" = + { "PubMed" } + { curlanguage "russian" = + { "PubMed" } + { curlanguage "german" = + { "PubMed" } + { "language is not defined: bbl.pubmed for " curlanguage * warning$ "PubMed" } + if$} + if$} +if$} + +FUNCTION {bbl.googlebooks} +{ curlanguage "english" = + { "Google Books" } + { curlanguage "russian" = + { "Google Книги" } + { curlanguage "german" = + { "Google Books" } + { "language is not defined: bbl.googlebooks for " curlanguage * warning$ "Google Books" } + if$} + if$} +if$} + +FUNCTION {bbl.hdl} +{ curlanguage "english" = + { "Handle.Net" } + { curlanguage "russian" = + { "Handle.Net" } + { curlanguage "german" = + { "Handle.Net" } + { "language is not defined: bbl.hdl for " curlanguage * warning$ "Handle.Net" } + if$} + if$} +if$} +FUNCTION {address.or.location} +{ + address empty$ + { location } + { address } + if$ +} + +FUNCTION {specialitycode.or.number} +{ + specialitycode empty$ + { number } + { specialitycode } + if$ +} + +FUNCTION {institution.or.school} +{ + institution empty$ + { school} + { institution } + if$ +} +FUNCTION {date.to.year} +{ + date empty$ + { date } + { + date text.length$ #3 > + { + date #1 #4 substring$ 'y := + y + } + { + "wrong format of date in " cite$ * ": date=" * date * warning$ + date + } + if$ + } + if$ +} + +FUNCTION {date.to.month} +{ + date empty$ + { date } + { + date text.length$ #6 > + { + date #6 #2 substring$ 'm := + m + } + { + "wrong format of date in " cite$ * ": date=" * date * warning$ + date + } + if$ + } + if$ +} + +FUNCTION {date.to.day} +{ + date empty$ + { date } + { + date text.length$ #10 = + { + date #9 #2 substring$ 'd := + d + } + { + "wrong format of date in " cite$ * ": date=" * date * warning$ + date + } + if$ + } + if$ +} + +FUNCTION {year.or.date.to.year} +{ + year empty$ + { + date.to.year + } + { year } + if$ +} + +FUNCTION {format.month} +{ month empty$ + { "" } + { month "Jan." = + { bbl.jan } + { month "Feb." = + { bbl.feb } + { month "Mar." = + { bbl.mar } + { month "Apr." = + { bbl.apr } + { month "May" = + { bbl.may } + { month "Jun." = + { bbl.jun } + { month "Jul." = + { bbl.jul } + { month "Aug." = + { bbl.aug } + { month "Sep." = + { bbl.sep } + { month "Oct." = + { "^^d0^^9e^^d0^^ba^^d1^^82." } + { month "Nov." = + { bbl.nov } + { month "Dec." = + { bbl.dec } + { + "unknown month in " cite$ * warning$ + month + } + if$}if$}if$}if$}if$}if$}if$}if$}if$}if$}if$}if$} + if$ +} +FUNCTION {format.date} +{ year.or.date.to.year empty$ + { month empty$ + { "" } + { "there's a month but no year in " cite$ * warning$ + format.month + } + if$ + } + { month empty$ + 'year.or.date.to.year + { year.or.date.to.year ". " format.month * * } + if$ + } + if$ +} + +INTEGERS { nameptr namesleft numnames } + +FUNCTION {fmt.names.three} +{ + 's := + #1 'nameptr := + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { s nameptr + "{vv~}{ll}{~jj}{~f.}" + format.name$ 't := + nameptr #1 > + { nameptr #4 = numnames #4 > and + { "others" 't := + #1 'namesleft := + } + 'skip$ + if$ + namesleft #1 > + { ", " * t * } + { t "others" = t "~others" = or + { " " * bbl.etal * } + { ", " * t * } + if$ + } + if$ + } + 't + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ +} + +FUNCTION {fmt.names.all} +{ 's := + #1 'nameptr := + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { s nameptr + %"{vv~}{ll}" format.name$ 't := + "{vv~}{ll}{~jj}{~f.}" + format.name$ 't := + nameptr #1 > + { namesleft #1 > + { ", " * t * } + { numnames #2 > curlanguage "english" = and + { "," * } + 'skip$ + if$ + t "others" = t "~others" = or + { " " * bbl.etal * } + { " " bbl.and " " * * * t * } + if$ + } + if$ + } + 't + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ +} + +%% { author fmt.names.all emphasize} +%% { author fmt.names.three emphasize} +FUNCTION {format.author} +{ + author empty$ + { author } %%%'skip$ + { author num.names$ #400 < + { + author fmt.names.all + } + { "" } %%%'skip$ + if$} + if$ +} + + +FUNCTION {format.editors.rest} +{ editor empty$ + { "" } + { bbl.edby "\ " * editor fmt.names.all * } + if$ +} + +FUNCTION {format.chief.rest} +{ editor empty$ + { "" } + { bbl.chief "\ " * editor fmt.names.all * } + if$ +} + +FUNCTION {format.executor.rest} +{ author empty$ + { "" } + { author fmt.names.all } + if$ +} + +FUNCTION {format.compiler.rest} +{ compiler empty$ + { "" } + { bbl.compiler "\ " * compiler fmt.names.all * } + if$ +} + +FUNCTION {output.address.publisher} +{ + address empty$ location empty$ and + 'skip$ + { address.or.location output + publisher empty$ + 'skip$ + { new.colon } + if$ + } + if$ + publisher output +} +FUNCTION {output.bibitem} +{ + set.language + newline$ + "\bibitem" write$ + cite$ bracify write$ + newline$ + "\selectlanguageifdefined" curlanguage bracify * write$ + newline$ + "" + before.all 'output.state := +} + +FUNCTION {format.bvolume} +{ volume empty$ + { "" } + { bbl.vvol volume tie.connect + series empty$ + 'skip$ + { bbl.of spaces.around * series emphasize * } + if$ + "volume and number" number either.or.check + } + if$ +} + +FUNCTION {format.number.series} +{ volume empty$ + { number empty$ + { series field.or.null } + { series empty$ + { "there's a number but no series in " cite$ * warning$ + bbl.nnr } + { + %new.dblslash + new.sentence + series + bbl.nr + tie.or.space.connect} + if$ + number tie.or.space.connect + } + if$ + } + { "" } + if$ +} + + +FUNCTION {convert.edition} +{ edition +} + +FUNCTION {format.edition} +{ edition empty$ + { "" } + { output.state mid.sentence = + { convert.edition " " * bbl.edition * } + { convert.edition " " * bbl.edition * } + if$ + } + if$ +} + +FUNCTION {format.pages} +{ eid empty$ + { + pages empty$ + { "" } + { pages multi.page.check + { bbl.ppages pages n.dashify tie.connect } + { bbl.ppage pages tie.connect } + if$ + } + if$ + } + { eid multi.page.check + { bbl.ppages eid n.dashify tie.connect } + { bbl.ppage eid tie.connect } + if$ + } + if$ +} + +FUNCTION {format.pages.page} +{ eid empty$ + { pages empty$ + { pagetotal empty$ + { "" } + { pagetotal bbl.pages tie.connect } + if$ + } + { format.pages} + if$ + } + { format.pages } + if$ +} + +FUNCTION {format.vol.num.pages} +{ volume field.or.null + number empty$ + 'skip$ + { + ", no." number tie.or.space.connect * + volume empty$ + { "there's a number but no volume in " cite$ * warning$ } + 'skip$ + if$ + } + if$ + pages empty$ + 'skip$ + { duplicate$ empty$ + { pop$ format.pages } + { ": " * pages n.dashify * } + if$ + } + if$ +} + +FUNCTION {format.volume} +{ volume empty$ + { "" } + { bbl.vvol volume tie.or.space.connect } + if$ +} + +FUNCTION {format.number} +{ number empty$ + { "" } + { bbl.nr number tie.or.space.connect } + if$ +} + + +FUNCTION {empty.misc.check} +{ author empty$ title empty$ howpublished empty$ + month empty$ year empty$ note empty$ + and and and and and + key empty$ not and + { "all relevant fields are empty in " cite$ * warning$ } + 'skip$ + if$ +} + +FUNCTION {bbl.thesis.type} +{ type "mathesis" = + { bbl.mathesis } + { type "phdthesis" = + { bbl.phdthesis } + { type "docthesis" = + { bbl.docthesis } + %%{ "!!!" type * "t" change.case$ } + { type } + if$} + if$} +if$} + +%% bbl.thesis.type "t" change.case$ +%% bbl.thesis.type +FUNCTION {format.thesis.type} +{ type empty$ + 'skip$ + { pop$ + bbl.thesis.type + } + if$ +} +%% { "t" change.case$ } +%% { "" } + +FUNCTION {format.techreport.type} +{ type empty$ + { bbl.techreport } + 'type + if$ +} + +FUNCTION {output.author.head} +{ + author empty$ + 'skip$ + {author num.names$ #400 < + { + author fmt.names.all output + new.sentence + } + 'skip$ + if$} + if$ +} + +FUNCTION {output.author.rest} +{ +%'skip$ +% author empty$ +% 'skip$ +% {author num.names$ #3 > +% { author fmt.names.all output +% new.semicolon +% } +% 'skip$ +% if$} +% if$ +} + +FUNCTION {bookauthor.rest} +{ + bookauthor empty$ + 'skip$ + { + bookauthor fmt.names.three output + new.semicolon + } + if$ +} + +FUNCTION {editor.organization.rest} +{ + compiler empty$ + {} + { format.compiler.rest output + new.semicolon + } + if$ + editor empty$ + {} + { format.editors.rest output.nonnull + new.semicolon + } + if$ + organization empty$ + {} + {organization output.nonnull + new.semicolon + } + if$ +} + +%% ----- urldate normalisation ----------------------------------------- +%% The `urldate` field in the .bib may be written in any of three +%% popular formats; we parse it and re-emit as GOST "DD.MM.YYYY". +%% Inputs supported: +%% * ISO "YYYY-MM-DD" e.g. 2026-04-06 +%% * GOST "DD.MM.YYYY" e.g. 06.04.2026 +%% * IEEE "Mon. DD, YYYY" / "Month DD, YYYY" e.g. Apr. 6, 2026 +%% Anything else passes through unchanged. + +% Zero-pad a 1-digit number string to 2 digits ("6" -> "06"). +FUNCTION {ud.pad2} +{ duplicate$ text.length$ #1 = + { "0" swap$ * } + { skip$ } + if$ +} + +FUNCTION {ud.month.name.to.num} +{ duplicate$ #1 #3 substring$ "l" change.case$ 'ud.tmp := + ud.tmp "jan" = + { pop$ "01" } + { ud.tmp "feb" = + { pop$ "02" } + { ud.tmp "mar" = + { pop$ "03" } + { ud.tmp "apr" = + { pop$ "04" } + { ud.tmp "may" = + { pop$ "05" } + { ud.tmp "jun" = + { pop$ "06" } + { ud.tmp "jul" = + { pop$ "07" } + { ud.tmp "aug" = + { pop$ "08" } + { ud.tmp "sep" = + { pop$ "09" } + { ud.tmp "oct" = + { pop$ "10" } + { ud.tmp "nov" = + { pop$ "11" } + { ud.tmp "dec" = + { pop$ "12" } + { skip$ } + if$ + } + if$ + } + if$ + } + if$ + } + if$ + } + if$ + } + if$ + } + if$ + } + if$ + } + if$ + } + if$ + } + if$ +} + +FUNCTION {parse.urldate} +{ "no" 'ud.parsed := + "" 'ud.y := "" 'ud.m := "" 'ud.d := + urldate empty$ 'skip$ + { urldate text.length$ 'ud.len := + ud.len #10 = + { % ISO YYYY-MM-DD? + urldate #5 #1 substring$ "-" = + urldate #8 #1 substring$ "-" = and + { urldate #1 #4 substring$ 'ud.y := + urldate #6 #2 substring$ 'ud.m := + urldate #9 #2 substring$ 'ud.d := + "yes" 'ud.parsed := + } + { % GOST DD.MM.YYYY? + urldate #3 #1 substring$ "." = + urldate #6 #1 substring$ "." = and + { urldate #1 #2 substring$ 'ud.d := + urldate #4 #2 substring$ 'ud.m := + urldate #7 #4 substring$ 'ud.y := + "yes" 'ud.parsed := + } + { skip$ } + if$ + } + if$ + } + { skip$ } + if$ + ud.parsed "no" = + { ud.len #7 > + { urldate ud.len #3 - #4 substring$ 'ud.y := + urldate ud.len #4 - #1 substring$ " " = + urldate ud.len #5 - #1 substring$ "," = and + { #1 'ud.idx := + #0 'ud.space.pos := + { ud.idx ud.len #5 - < + ud.space.pos #0 = and + } + { urldate ud.idx #1 substring$ " " = + { ud.idx 'ud.space.pos := } + { skip$ } + if$ + ud.idx #1 + 'ud.idx := + } + while$ + ud.space.pos #0 > + { urldate #1 ud.space.pos #1 - substring$ + ud.month.name.to.num 'ud.m := + urldate ud.space.pos #1 + + ud.len #6 - ud.space.pos - + substring$ 'ud.d := + "yes" 'ud.parsed := + } + { skip$ } + if$ + } + { skip$ } + if$ + } + { skip$ } + if$ + } + { skip$ } + if$ + } + if$ +} + +FUNCTION {urldate.in.gost.style} +{ parse.urldate + ud.parsed "yes" = + { ud.d ud.pad2 "." * ud.m ud.pad2 * "." * ud.y * } + { urldate } + if$ +} + + +FUNCTION {format.url} +{ url empty$ + { "" } + { + bbl.url ": \url{" * url * "}" * + urldate empty$ + { "" } + { " (" bbl.urldate * ": " * urldate.in.gost.style * ")" * } + if$ * + } + if$ +} + +FUNCTION {output.url} +{ doi empty$ + { url empty$ + 'skip$ + { format.url output } + if$ + } + 'skip$ + if$ +} + +FUNCTION {format.annote} +{ annote empty$ + { "" } +{ after.sentence 'output.state := + "\BibAnnote{" annote add.period$ * "}" * +} + if$ +} + +FUNCTION {format.isbn} +{ + isbn empty$ + { "" } + { "ISBN:~\href{http://isbndb.com/search-all.html?kw=" isbn * + "}{" * isbn * "}" * + } + if$ +} + +FUNCTION {format.doi} +{ doi empty$ + { "" } + { "doi:\mylinkurl{" doi * "}" * } + if$ +} + +FUNCTION {add.media} +{ duplicate$ empty$ + 'skip$ + { media empty$ + 'skip$ + { " " * bbl.media bracketise * } + if$ + } + if$ +} + + + +FUNCTION {format.eprint} +{ eprint empty$ + { "" } + { eprinttype empty$ + { "" } + { eprinttype "~: " *} + if$ + eprintclass empty$ + { } + { eprintclass * "/" *} + if$ + url empty$ + { eprint * } + { "\href{" * url * "}{" * eprint * "}}" *} + if$ + } + if$ +} + +FUNCTION {output.eprint.url} +{ doi empty$ + {eprint empty$ + { format.url output } + { format.eprint output } + if$ + } + 'skip$ + if$ +} + + + +FUNCTION {add.number} +{ duplicate$ empty$ + { "" } + { bbl.nr swap$ tie.or.space.connect } + if$ +} + +FUNCTION {format.type.number} +{ + type empty$ + { "" } + { + number empty$ + { "" } + { type number tie.or.space.connect } + if$ + } + if$ +} +FUNCTION {format.patent.id} +{ number empty$ + { "" } + { type empty$ + { bbl.patent } + { type } + if$ + nationality empty$ + { skip$ } + { " " * nationality * } + if$ + " " * number * + } + if$ +} + +FUNCTION {format.requestdate} +{ requestdate empty$ + { "" } + { bbl.req requestdate tie.or.space.connect } + if$ +} + +FUNCTION {format.publicationdate} +{ publicationdate empty$ + { "" } + { bbl.publ publicationdate tie.or.space.connect } + if$ +} + +FUNCTION {format.prioritydate} +{ prioritydate empty$ + { "" } + { bbl.priority prioritydate tie.or.space.connect } + if$ +} + +FUNCTION {article} +{ + output.bibitem + output.author.head + new.sentence + title add.media "title" output.check + new.slash +% output.author.rest + new.dblslash + journal emphasize "journal" output.check % new in v1.2 + new.block + format.date "year/date" output.check + new.block + format.volume output + format.number output + new.block + format.pages.page output + new.block + note output + new.sentence + format.doi output + new.sentence + output.eprint.url + format.annote output + fin.entry +} + +FUNCTION {book} +{ + output.bibitem + output.author.head + new.sentence + title add.media "title" output.check + new.colon % added in v.1.2k + titleaddon output % added in v.1.2k + new.slash +% output.author.rest + editor.organization.rest + new.sentence + format.number.series output + new.block + format.edition output + new.block + output.address.publisher + format.date "year/date" output.check + new.block + format.bvolume output + new.block + format.pages.page output + new.block + format.isbn output + new.block + note output + new.sentence + format.doi output + new.sentence + output.eprint.url + format.annote output + fin.entry +} + +FUNCTION {booklet} +{ + output.bibitem + output.author.head + new.sentence + title add.media "title" output.check + new.colon % added in v.1.2k + titleaddon output % added in v.1.2k + new.slash +% output.author.rest + editor.organization.rest + new.block + howpublished output + address.or.location output + format.date "year/date" output.check + new.block + note output + new.sentence + format.doi output + new.sentence + output.eprint.url + format.annote output + fin.entry +} + +FUNCTION {inbook} +{ + output.bibitem + output.author.head + new.sentence + title add.media "title" output.check + new.colon % added in v.1.2k + titleaddon output % added in v.1.2k + new.slash +% output.author.rest + new.dblslash + booktitle "booktitle" output.check + new.slash + bookauthor.rest + editor.organization.rest + new.block + format.edition output + new.block + format.number.series output + new.sentence + output.address.publisher + format.date "year/date" output.check + new.block + format.bvolume output + new.block + format.pages.page output + new.block + format.isbn output + new.block + note output + new.sentence + format.doi output + new.sentence + output.eprint.url + format.annote output + fin.entry +} + +FUNCTION {incollection} +{ + output.bibitem + output.author.head + new.sentence + new.sentence + title add.media "title" output.check + new.colon % added in v.1.2k + titleaddon output % added in v.1.2k + new.slash +% output.author.rest + new.dblslash + booktitle "booktitle" output.check + new.slash + editor.organization.rest + new.block + output.address.publisher + format.date "year/date" output.check + new.block + format.bvolume output + format.number.series output + new.block + format.pages.page output + new.block + note output + new.sentence + format.doi output + new.sentence + output.eprint.url + format.annote output + fin.entry +} + +FUNCTION {proceedings} +{ + output.bibitem + title add.media "title" output.check + new.colon % added in v.1.2k + titleaddon output % added in v.1.2k + new.slash + editor.organization.rest + new.block + output.address.publisher % 1.2k moved from below + new.block % added in v.1.2k + format.date "year/date" output.check + new.block + format.bvolume output + format.number.series output + new.block + format.pages.page output + %%%output.address.publisher % 1.2k moved upper + new.block + note output + new.sentence + format.doi output + new.sentence + output.eprint.url + format.annote output + fin.entry +} + +FUNCTION {inproceedings} +{ output.bibitem + output.author.head + new.sentence + new.sentence + title add.media "title" output.check + new.colon % added in v.1.2k + titleaddon output % added in v.1.2k + new.slash +% output.author.rest + new.dblslash + booktitle "booktitle" output.check + new.slash + editor.organization.rest + new.block + output.address.publisher % 1.2k moved from below + new.block % added in v.1.2k + format.date "year/date" output.check + new.block + format.bvolume output + format.number.series output + new.block + format.pages.page output + new.block + note output + new.sentence + format.doi output + new.sentence + output.eprint.url + format.annote output + fin.entry +} + +FUNCTION {manual} +{ output.bibitem + author empty$ + { organization empty$ + 'skip$ + { organization output.nonnull + address output + } + if$ + } + { format.author output.nonnull } + if$ + new.block + title add.media "title" output.check + new.colon % added in v.1.2k + titleaddon output % added in v.1.2k + author empty$ + { organization empty$ + { + address new.block.checka + address output + } + 'skip$ + if$ + } + { + organization address new.block.checkb + organization output + address output + } + if$ + format.edition output + format.date "year/date" output.check + new.block + note output + new.sentence + format.doi output + new.sentence + output.eprint.url + format.annote output + fin.entry +} + +FUNCTION {patent} +{ + output.bibitem + title add.media "title" output.check + new.colon % added in v.1.2k + titleaddon output % added in v.1.2k + format.patent.id + duplicate$ empty$ + { pop$ add.period$ new.colon format.type.number output } + { output.nonnull } + if$ + add.blank + address.or.location output + new.colon + ipc output + new.slash + format.author "author" output.check + %add.blank + authorcountry missing$ + 'skip$ + { authorcountry paranthesify output } + if$ + new.semicolon + holder output + new.semicolon + credits output + new.block + requestnumber missing$ + 'skip$ + { requestnumber add.number output } + if$ + new.semicolon + format.requestdate output + new.semicolon + format.publicationdate output + publication missing$ + 'skip$ + { publication output } + if$ + new.semicolon + format.prioritydate output + prioritynumber missing$ + 'skip$ + { prioritynumber output } + if$ + prioritycountry missing$ + 'skip$ + { prioritycountry paranthesify output } + if$ + new.block + format.date output + new.block + note output + new.sentence + output.url + format.annote output + new.block + pagetotal output + fin.entry +} + +FUNCTION {misc} +{ output.bibitem + %format.author output % < v.1.2k + output.author.head % v.1.2k + new.sentence % v.1.2k + title howpublished new.sentence.checkb + title add.media output + howpublished new.block.checka + howpublished output + new.block + format.date "year/date" output.check + new.block + note output + new.sentence + output.eprint.url + format.annote output + fin.entry +} + +FUNCTION {unpublished} +{ output.bibitem + output.author.head + new.sentence + title "title" output.check + new.colon % added in v.1.2k + titleaddon output % added in v.1.2k + new.slash +% output.author.rest + editor.organization.rest + new.block + format.date "year/date" output.check + new.block + note "note" output.check + new.sentence + output.eprint.url + format.annote output + fin.entry +} + +FUNCTION {online} +{ output.bibitem + format.author output + title howpublished new.sentence.checkb + title add.media "title" output.check + new.colon % added in v.1.2k + titleaddon output % added in v.1.2k + howpublished new.dblslash.checka + howpublished output + editor.organization.rest + new.sentence + new.block + output.address.publisher + format.date output + new.sentence + format.doi output + new.block + output.eprint.url + new.sentence + note output + format.annote output + fin.entry +} + +FUNCTION {internet} {online} +FUNCTION {www} {online} +FUNCTION {webpage} {online} +FUNCTION {electronic} {online} +FUNCTION {thesis} +{ output.bibitem + format.author "author" output.check + new.sentence + title add.media "title" output.check + new.colon + bbl.phdthesis format.thesis.type output.nonnull + new.colon + specialitycode.or.number output % code of the speciality, new in v.1.2i + new.colon + titleaddon output % date of defence and approvement; new in v.1.2i + new.slash + %%%format.author.rest output %% dupplicates athours from the head zone +% output.author.rest %% prints if num.names$ > 3 or > 1 + new.semicolon + %institution "institution" output.check + institution.or.school "institution/school" output.check + new.block + output.address.publisher + format.date "year/date" output.check + new.block + format.pages.page output + new.block + note output + new.sentence + format.doi output + new.sentence + output.eprint.url + format.annote output + fin.entry +} +%% format.techrep.type.number output.nonnull +%% format.url output +FUNCTION {report} +{ + output.bibitem + title add.media "title" output.check + new.colon % added in v.1.2k + titleaddon output % added in v.1.2k + new.colon + type "type" output.check + new.colon + number output + new.slash + %institution "institution" output.check + institution.or.school "institution/school" output.check + new.semicolon + format.chief.rest output % from editor field + new.semicolon + format.executor.rest output % from author field + new.block + address.or.location output + new.colon + organization output + format.date "year/date" output.check + new.block % v.2 + format.pages.page output % v.2 + new.sentence + format.doi output + new.sentence % ^^d0^^b8^^d0^^bb^^d0^^b8 new.block ? + output.eprint.url + new.block + note output + format.annote output + fin.entry +} + +FUNCTION {phdthesis} +{ output.bibitem + format.author "author" output.check + new.sentence + title add.media "title" output.check + new.colon + bbl.phdthesis format.thesis.type output.nonnull + new.colon + %%number output % code of the speciality + specialitycode.or.number output % code of the speciality, new in v.1.2i + new.colon + titleaddon output % date of defence and approvement; new in v.1.2i + new.slash + %%%format.author.rest output %% dupplicates athours +% output.author.rest %% prints if num.names$ > 3 or > 1 + new.semicolon + %institution "institution" output.check + institution.or.school "institution/school" output.check + new.block + output.address.publisher + format.date "year/date" output.check + new.block + format.pages.page output + new.block + note output + new.sentence + format.doi output + new.sentence + output.eprint.url + format.annote output + fin.entry +} +FUNCTION {mastersthesis} +{ output.bibitem + format.author "author" output.check + new.sentence + title add.media "title" output.check + new.colon + bbl.mathesis format.thesis.type output.nonnull + new.colon + %%number output % code of the speciality + specialitycode.or.number output % code of the speciality, new in v.1.2i + new.colon + titleaddon output % date of defence and approvement; new in v.1.2i + new.slash + %%%format.author.rest output %% dupplicates athours +% output.author.rest %% prints if num.names$ > 3 or > 1 + new.semicolon + %institution "institution" output.check + institution.or.school "institution/school" output.check + new.block + output.address.publisher + format.date "year/date" output.check + new.block + format.pages.page output + new.block + note output + new.sentence + format.doi output + new.sentence + output.eprint.url + format.annote output + fin.entry +} +FUNCTION {docthesis} +{ output.bibitem + format.author "author" output.check + new.sentence + title add.media "title" output.check + new.colon + bbl.docthesis format.thesis.type output.nonnull + new.colon + %%number output % code of the speciality + specialitycode.or.number output % code of the speciality, new in v.1.2i + new.colon + titleaddon output % date of defence and approvement; new in v.1.2i + new.slash + %%%format.author.rest output %% dupplicate athours +% output.author.rest %% prints if num.names$ > 3 or > 1 + new.semicolon + %institution "institution" output.check + institution.or.school "institution/school" output.check + new.block + output.address.publisher + format.date "year/date" output.check + new.block + format.pages.page output + new.block + note output + new.sentence + format.doi output + new.sentence + output.eprint.url + format.annote output + fin.entry +} +FUNCTION {conference} { inproceedings } + +%% format.url output + +% FUNCTION {article} +% { +% output.bibitem +% output.author.head +% new.sentence +% title add.media "title" output.check +% new.slash +% output.author.rest +% new.dblslash +% journal emphasize "journal" output.check % new in v1.2 +% new.block +% format.date "year/date" output.check +% new.block +% format.volume output +% format.number output +% new.block +% format.pages.page output +% new.block +% note output +% new.sentence +% format.doi output +% new.sentence +% output.eprint.url +% format.annote output +% fin.entry +% } + + +FUNCTION {techreport} +{ + output.bibitem + format.executor.rest output % from author field + new.sentence + title add.media "title" output.check + new.slash + format.techreport.type output + number output + new.slash + %institution "institution" output.check + institution.or.school "institution/school" output.check + new.semicolon + format.chief.rest output % from editor field + new.block + address.or.location output + new.colon + organization output + format.date "year/date" output.check + new.block % v.2 + format.pages.page output % v.2 + new.sentence + format.doi output + new.sentence % ^^d0^^b8^^d0^^bb^^d0^^b8 new.block ? + output.eprint.url + new.block + note output + format.annote output + fin.entry +} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% New IEEE type aliases — best-fit mappings to GOST 7.0.5 handlers. %% +%% These let the same BibTeX file feed both the IEEE.bst (English) %% +%% and ugost2008.bst (Russian) bibliographies. GOST has no separate %% +%% layouts for blogs, datasets, software, lectures, social-media etc, %% +%% so each new IEEE entry type is routed to the closest existing %% +%% GOST handler: %% +%% * any online/electronic resource → @online (URL-based, with %% +%% \BIBforeignlanguage / [Электронный ресурс] handling), %% +%% * news article in a periodical → @article, %% +%% * presentation / conf. paper → @inproceedings, %% +%% * preprint → @misc, %% +%% * standard / handbook → @manual, %% +%% * government document → @misc, %% +%% * patent (any form) → @patent, %% +%% * dissertation → @phdthesis. %% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% @video — dedicated GOST 7.0.5 handler. +%% Layout (Russian): +%% Title : [видео] / Author -- URL: (дата обращения: ) +%% Layout (English): +%% Title : [video] / Author -- URL: (online; accessed: ) +%% The entry is built as a single string for full control over the +%% segment separators (which mix " : ", " / ", and "\BibDash{}" — a +%% combination the standard state machine doesn't model). +FUNCTION {video} +{ output.bibitem + % output.bibitem leaves an empty buffer on the stack; discard it so we + % can build the entry as a single string from scratch. + pop$ + title duplicate$ empty$ + { pop$ "empty title in " cite$ * warning$ "" } + 'skip$ + if$ + "~: " * + bbl.video.bracket * + author empty$ + 'skip$ + { "~/ " * + format.author * + } + if$ + url empty$ + 'skip$ + { " \BibDash{} " * + bbl.url * + ": \url{" * + url * + "}" * + urldate empty$ + 'skip$ + { " (" * + bbl.urldate * + ": " * + urldate.in.gost.style * + ")" * + } + if$ + } + if$ + add.period$ + write$ + newline$ +} + +FUNCTION {software} +{ output.bibitem + pop$ + title duplicate$ empty$ + { pop$ "empty title in " cite$ * warning$ "" } + 'skip$ + if$ + author empty$ organization empty$ and howpublished empty$ and + 'skip$ + { "~/ " * + bbl.software.developer * + ": " * + author empty$ + { organization empty$ + { howpublished * } + { organization * } + if$ + } + { format.author * } + if$ + } + if$ + address empty$ year empty$ and + 'skip$ + { add.period$ + " \BibDash{} " * + address empty$ + { year * } + { address * + year empty$ + 'skip$ + { " : " * year * } + if$ + } + if$ + } + if$ + add.period$ + " \BibDash{} " * + bbl.software.kind * + " : " * + bbl.software.subkind * + url empty$ + 'skip$ + { add.period$ + " \BibDash{} " * + bbl.url * + ": \url{" * + url * + "}" * + urldate empty$ + 'skip$ + { " (" * + bbl.urldate * + ": " * + urldate.in.gost.style * + ")" * + } + if$ + } + if$ + add.period$ + write$ + newline$ +} + +FUNCTION {dataset} +{ output.bibitem + pop$ + title duplicate$ empty$ + { pop$ "empty title in " cite$ * warning$ "" } + 'skip$ + if$ + "~: " * + bbl.dataset.kind * + author empty$ organization empty$ and howpublished empty$ and + 'skip$ + { "~/ " * + author empty$ + { organization empty$ + { howpublished * } + { organization * } + if$ + } + { format.author * } + if$ + } + if$ + year empty$ + 'skip$ + { ", " * year * } + if$ + url empty$ + 'skip$ + { add.period$ + " " * + bbl.url * + ": \url{" * + url * + "}" * + urldate empty$ + 'skip$ + { " (" * + bbl.urldate * + ": " * + urldate.in.gost.style * + ")" * + } + if$ + } + if$ + add.period$ + write$ + newline$ +} + +FUNCTION {blog} {online} +FUNCTION {news} {article} +FUNCTION {newsarticle} {article} +FUNCTION {lecture} {online} +FUNCTION {website} {online} +FUNCTION {socialmedia} {online} +FUNCTION {government} {misc} +FUNCTION {presentation} {inproceedings} +FUNCTION {confonline} {online} +FUNCTION {conferenceonline} {online} +FUNCTION {confpaperonline} {online} +FUNCTION {patentonline} {patent} +FUNCTION {preprint} {misc} +FUNCTION {arxiv} {misc} +FUNCTION {dissertation} {phdthesis} + +%% @standard — dedicated GOST handler. +%% Forms the leading identifier from the organization + number fields, +%% so the standard number is not lost. Layout: +%% [Organization Number]. Title. — Address. — Year. — Note. — doi. +FUNCTION {standard} +{ output.bibitem + pop$ + organization empty$ number empty$ and + { "" } + { organization empty$ + { number } + { number empty$ + { organization } + { organization " " * number * } + if$ + } + if$ + } + if$ + title empty$ + 'skip$ + { duplicate$ empty$ + { pop$ title } + { add.period$ " " * title * } + if$ + } + if$ + % " : " + type empty$ + 'skip$ + { " : " * type * } + if$ + % " / разработан " + author empty$ + 'skip$ + { "~/ " * + bbl.standard.developed * + " " * + format.author * + } + if$ + % ". --
: , " + address empty$ publisher empty$ and year empty$ and + 'skip$ + { add.period$ + " \BibDash{} " * + address empty$ + 'skip$ + { address * } + if$ + publisher empty$ + 'skip$ + { address empty$ + 'skip$ + { " : " * } + if$ + publisher * + } + if$ + year empty$ + 'skip$ + { address empty$ publisher empty$ and + 'skip$ + { ", " * } + if$ + year * + } + if$ + } + if$ + % ". -- " + pages empty$ + 'skip$ + { add.period$ + " \BibDash{} " * + pages * + } + if$ + % ". -- Note" if provided. + note empty$ + 'skip$ + { add.period$ + " \BibDash{} " * + note * + } + if$ + % ". -- Текст : непосредственный" + add.period$ + " \BibDash{} " * + bbl.standard.material * + add.period$ + write$ + newline$ +} + +FUNCTION {default.type} { misc } + +MACRO {jan} {"Jan."} +MACRO {feb} {"Feb."} +MACRO {mar} {"Mar."} +MACRO {apr} {"Apr."} +MACRO {may} {"May"} +MACRO {jun} {"Jun."} +MACRO {jul} {"Jul."} +MACRO {aug} {"Aug."} +MACRO {sep} {"Sep."} +MACRO {oct} {"Oct."} +MACRO {nov} {"Nov."} +MACRO {dec} {"Dec."} +MACRO {aa}{"Astron.\ \& Astrophys."} +MACRO {aasup}{"Astron.\ \& Astrophys.\ Suppl.\ Ser."} +MACRO {aj} {"Astron.\ J."} +MACRO {aph} {"Acta Phys."} +MACRO {advp} {"Adv.\ Phys."} +MACRO {ajp} {"Amer.\ J.\ Phys."} +MACRO {ajm} {"Amer.\ J.\ Math."} +MACRO {amsci} {"Amer.\ Sci."} +MACRO {anofd} {"Ann.\ Fluid Dyn."} +MACRO {am} {"Ann.\ Math."} +MACRO {ap} {"Ann.\ Phys.\ (NY)"} +MACRO {adp} {"Ann.\ Phys.\ (Leipzig)"} +MACRO {ao} {"Appl.\ Opt."} +MACRO {apl} {"Appl.\ Phys.\ Lett."} +MACRO {app} {"Astroparticle Phys."} +MACRO {apj} {"Astrophys.\ J."} +MACRO {apjsup} {"Astrophys.\ J.\ Suppl."} +MACRO {apss} {"Astrophys.\ Space Sci."} +MACRO {araa} {"Ann.\ Rev.\ Astron.\ Astrophys."} +MACRO {baas} {"Bull.\ Amer.\ Astron.\ Soc."} +MACRO {baps} {"Bull.\ Amer.\ Phys.\ Soc."} +MACRO {cmp} {"Comm.\ Math.\ Phys."} +MACRO {cpam} {"Commun.\ Pure Appl.\ Math."} +MACRO {cppcf} {"Comm.\ Plasma Phys.\ \& Controlled Fusion"} +MACRO {cpc} {"Comp.\ Phys.\ Comm."} +MACRO {cqg} {"Class.\ Quant.\ Grav."} +MACRO {cra} {"C.\ R.\ Acad.\ Sci.\ A"} +MACRO {fed} {"Fusion Eng.\ \& Design"} +MACRO {ft} {"Fusion Tech."} +MACRO {grg} {"Gen.\ Relativ.\ Gravit."} +MACRO {ieeens} {"IEEE Trans.\ Nucl.\ Sci."} +MACRO {ieeeps} {"IEEE Trans.\ Plasma Sci."} +MACRO {ijimw} {"Interntl.\ J.\ Infrared \& Millimeter Waves"} +MACRO {ip} {"Infrared Phys."} +MACRO {irp} {"Infrared Phys."} +MACRO {jap} {"J.\ Appl.\ Phys."} +MACRO {jasa} {"J.\ Acoust.\ Soc.\ America"} +MACRO {jcp} {"J.\ Comp.\ Phys."} +MACRO {jchp} {"J.\ Chem.\ Phys."} +MACRO {jetp} {"Sov.\ Phys.--JETP"} +MACRO {jfe} {"J.\ Fusion Energy"} +MACRO {jfm} {"J.\ Fluid Mech."} +MACRO {jmp} {"J.\ Math.\ Phys."} +MACRO {jne} {"J.\ Nucl.\ Energy"} +MACRO {jnec} {"J.\ Nucl.\ Energy, C: Plasma Phys., Accelerators, Thermonucl.\ Res."} +MACRO {jnm} {"J.\ Nucl.\ Mat."} +MACRO {jpc} {"J.\ Phys.\ Chem."} +MACRO {jpp} {"J.\ Plasma Phys."} +MACRO {jpsj} {"J.\ Phys.\ Soc.\ Japan"} +MACRO {jsi} {"J.\ Sci.\ Instrum."} +MACRO {jvst} {"J.\ Vac.\ Sci.\ \& Tech."} +MACRO {nat} {"Nature"} +MACRO {nature} {"Nature"} +MACRO {nedf} {"Nucl.\ Eng.\ \& Design/Fusion"} +MACRO {nf} {"Nucl.\ Fusion"} +MACRO {nim} {"Nucl.\ Inst.\ \& Meth."} +MACRO {nimpr} {"Nucl.\ Inst.\ \& Meth.\ in Phys.\ Res."} +MACRO {np} {"Nucl.\ Phys."} +MACRO {npb} {"Nucl.\ Phys.\ B"} +MACRO {nt/f} {"Nucl.\ Tech./Fusion"} +MACRO {npbpc} {"Nucl.\ Phys.\ B (Proc.\ Suppl.)"} +MACRO {inc} {"Nuovo Cimento"} +MACRO {nc} {"Nuovo Cimento"} +MACRO {pf} {"Phys.\ Fluids"} +MACRO {pfa} {"Phys.\ Fluids A: Fluid Dyn."} +MACRO {pfb} {"Phys.\ Fluids B: Plasma Phys."} +MACRO {pl} {"Phys.\ Lett."} +MACRO {pla} {"Phys.\ Lett.\ A"} +MACRO {plb} {"Phys.\ Lett.\ B"} +MACRO {prep} {"Phys.\ Rep."} +MACRO {pnas} {"Proc.\ Nat.\ Acad.\ Sci.\ USA"} +MACRO {pp} {"Phys.\ Plasmas"} +MACRO {pop} {"Phys.\ Plasmas"} +MACRO {ppcf} {"Plasma Phys.\ \& Controlled Fusion"} +MACRO {phitrsl} {"Philos.\ Trans.\ Roy.\ Soc.\ London"} +MACRO {prl} {"Phys.\ Rev.\ Lett."} +MACRO {pr} {"Phys.\ Rev."} +MACRO {physrev} {"Phys.\ Rev."} +MACRO {pra} {"Phys.\ Rev.\ A"} +MACRO {prb} {"Phys.\ Rev.\ B"} +MACRO {prc} {"Phys.\ Rev.\ C"} +MACRO {prd} {"Phys.\ Rev.\ D"} +MACRO {pre} {"Phys.\ Rev.\ E"} +MACRO {ps} {"Phys.\ Scripta"} +MACRO {procrsl} {"Proc.\ Roy.\ Soc.\ London"} +MACRO {rmp} {"Rev.\ Mod.\ Phys."} +MACRO {rsi} {"Rev.\ Sci.\ Inst."} +MACRO {science} {"Science"} +MACRO {sciam} {"Sci.\ Am."} +MACRO {sam} {"Stud.\ Appl.\ Math."} +MACRO {st} {"Sky and Telesc."} +MACRO {cjp} {"Czech. J. Phys."} +MACRO {el} {"Europhys. Lett."} +MACRO {en} {"Europhys. News"} +MACRO {fujitsustj} {"FUJITSU Sci. Tech. J."} +MACRO {ieeeed} {"IEEE Trans. Electron Devices"} +MACRO {ieeeim} {"IEEE Trans. Instrum. Meas."} +MACRO {ieeejqe} {"IEEE J. Quantum Electron."} +MACRO {ieeem} {"IEEE Trans. Magn."} +MACRO {ieeeptl} {"IEEE Photonic Technol. Lett."} +MACRO {ieeeuffc} {"IEEE Trans. Ultrason., Ferroelect., Freq. Cont."} +MACRO {jem} {"J. Electron. Mater."} +MACRO {jes} {"J. Electrochem. Soc."} +MACRO {jetplett} {"JETP Lett."} +MACRO {jjap} {"Japan. J. Appl. Phys."} +MACRO {jpha} {"J. Phys. A: Math. Gen."} +MACRO {jphb} {"J. Phys. B: At. Mol. Opt. Phys."} +MACRO {jphbold} {"J. Phys. B: At. Mol. Phys."} +MACRO {jphc} {"J. Phys.: Condens. Matter"} +MACRO {jphcold} {"J. Phys. C: Solid State Phys."} +MACRO {jphd} {"J. Phys. D: Appl. Phys."} +MACRO {jvsta} {"J. Vac. Sci. Technol. A"} +MACRO {jvstb} {"J. Vac. Sci. Technol. B"} +MACRO {me} {"Microelectron. Eng."} +MACRO {necrd} {"NEC Res.{\&} Develop."} +MACRO {pa} {"Physica A"} +MACRO {pb} {"Physica B"} +MACRO {pc} {"Physica C"} +MACRO {pd} {"Physica D"} +MACRO {procieee} {"Proc. IEEE"} +MACRO {procspie} {"Proc. SPIE"} +MACRO {pssa} {"Phys. Stat. Sol. A"} +MACRO {pssb} {"Phys. Stat. Sol. B"} +MACRO {rpp} {"Rep. Progr. Phys."} +MACRO {sm} {"Synthet. Metal"} +MACRO {sost} {"Solid State Technol."} +MACRO {ss} {"Surf. Sci."} +MACRO {ssc} {"Solid State Commun."} +MACRO {sst} {"Semicond. Sci. Technol."} +MACRO {suplatt} {"Superlatt. Microstr."} +MACRO {sust} {"Supercond. Sci. Technol."} +MACRO {znat} {"Z. Naturforsch."} +MACRO {appopt} {"Appl.\ Opt."} +MACRO {bell} {"Bell Syst.\ Tech.\ J."} +MACRO {ell} {"Electron.\ Lett."} +MACRO {jasp} {"J.\ Appl.\ Spectr."} +MACRO {jqe} {"IEEE J.\ Quantum Electron."} +MACRO {jlwt} {"J.\ Lightwave Technol."} +MACRO {jmo} {"J.\ Mod.\ Opt."} +MACRO {josa} {"J.\ Opt.\ Soc.\ America"} +MACRO {josaa} {"J.\ Opt.\ Soc.\ Amer.~A"} +MACRO {josab} {"J.\ Opt.\ Soc.\ Amer.~B"} +MACRO {jdp} {"J.\ Phys.\ (Paris)"} +MACRO {oc} {"Opt.\ Commun."} +MACRO {ol} {"Opt.\ Lett."} +MACRO {os} {"Opt.\ Spectrosc."} +MACRO {phtl} {"IEEE Photon. Technol. Lett."} +MACRO {pspie} {"Proc.\ Soc.\ Photo-Opt.\ Instrum. Eng."} +MACRO {vr} {"Vision Res."} +MACRO {zph} {"Z.\ f.\ Physik"} +MACRO {zphb} {"Z.\ f.\ Physik~B"} +MACRO {zphd} {"Z.\ f.\ Physik~D"} +MACRO {sse} {"Solid-State Electron."} +MACRO {pss} {"Phys. Sol. State"} +MACRO {nl} {"Nano Lett."} +MACRO {sjpp} {"Sov.\ J.\ Plasma Phys."} +MACRO {spd} {"Sov.\ Phys.--Doklady"} +MACRO {sptp} {"Sov.\ Phys.--Tech. Phys."} +MACRO {spu} {"Sov.\ Phys.--Uspekhi"} +MACRO {ufn} {"^^d0^^a3^^d0^^a4^^d0^^9d"} +MACRO {pu} {"Phys.--Uspekhi"} +MACRO {sjot} {"Sov.\ J.\ Opt.\ Technol."} +MACRO {sjqe} {"Sov.\ J.\ Quantum Electron."} +MACRO {sleb} {"Sov.\ Phys.--Leb.\ Inst.\ Rep."} +MACRO {stph} {"Sov.\ Phys.--Techn.\ Phys."} +MACRO {stphl}{"Sov.\ Techn.\ Phys.\ Lett."} + +READ + + + + +STRINGS { longest.label } + +INTEGERS { number.label longest.label.width } + +FUNCTION {initialize.longest.label} +{ "" 'longest.label := + #1 'number.label := + #0 'longest.label.width := +} + +EXECUTE {initialize.longest.label} + +FUNCTION {forward.pass} +{ number.label int.to.str$ 'label := + number.label #1 + 'number.label := + label width$ longest.label.width > + { label 'longest.label := + label width$ 'longest.label.width := + } + 'skip$ + if$ +} + +ITERATE {forward.pass} + + +FUNCTION {begin.bib} +{ "\begin{thebibliography}{" longest.label * "}" * write$ newline$ + "\def\selectlanguageifdefined#1{" write$ newline$ + "\expandafter\ifx\csname date#1\endcsname\relax" write$ newline$ + "\else\selectlanguage{#1}\fi}" write$ newline$ +% "\providecommand*{\href}[2]{{\small #2}}" write$ newline$ +% "\providecommand*{\url}[1]{{\small #1}}" write$ newline$ + "\providecommand*{\BibUrl}[1]{\url{#1}}" write$ newline$ + "\providecommand{\BibAnnote}[1]{}" write$ newline$ + "\providecommand*{\BibEmph}[1]{#1}" write$ newline$ + % User-configurable appearance hooks. Defaults match the historic + % ugost2008.bst look (\small font, single line spacing, -5pt itemsep). + % Override from the document preamble with \renewcommand, e.g.: + % \renewcommand{\bibfontsize}{\footnotesize} + % \renewcommand{\biblinespread}{1.1} + % \renewcommand{\bibitemsep}{0pt} + "\providecommand{\bibfontsize}{\small}" write$ newline$ + "\providecommand{\biblinespread}{1.0}" write$ newline$ + "\providecommand{\bibitemsep}{-5pt}" write$ newline$ + "\bibfontsize\linespread{\biblinespread}\selectfont" write$ newline$ + "\setlength{\itemsep}{\bibitemsep}" write$ newline$ + "\setlength{\labelwidth}{20pt}" write$ newline$ + + + "\ProvideTextCommandDefault{\cyrdash}{\iflanguage{russian}{\hbox to.8em{--\hss--}}{\textemdash}}" write$ newline$ + "\providecommand*{\BibDash}{\ifdim\lastskip>0pt\unskip\nobreak\hskip.2em plus 0.1em\fi" write$ newline$ + "\cyrdash\hskip.2em plus 0.1em\ignorespaces}" write$ newline$ + "\renewcommand{\newblock}{\ignorespaces}" write$ newline$ + preamble$ empty$ + 'skip$ + { preamble$ write$ newline$ } + if$ +} + +EXECUTE {begin.bib} + +EXECUTE {init.state.consts} + +ITERATE {call.type$} + +FUNCTION {end.bib} +{ newline$ + "\end{thebibliography}" write$ newline$ +} + +EXECUTE {end.bib} + +%%\endinput +%% +%% End of file `ugost2008.bst'.