- Automatically subscript part of the symbol after underscore
That could lead to problems, though; in particular, what if an identifier contains an underscore?
- Automatically replace
_1 with _xs and _2 with _ys
I think Horst is definitely on the right track. Even though I'm not a big fan of it, the literate key can be put to good use, here.
- Automatically markup matching strings, e.g. make labels init_1, guard_2 bold.
Do you mean "Goto labels"? Highlighting those automatically with listings is a tougher nut to crack. What follows is more of a glorified hack than a proper solution, but see if it works for you.

Breakdown of the solution
Package loading
Nothing very interesting here, aside from the fact that you need the fixltx2e package (because it defines the \textsubscript macro).
\usepackage{fixltx2e}
\usepackage{listings}
\usepackage{xcolor}
Style definitions
\colorlet{gotolabel}{red}
\newcommand\lstsubstyle{\itshape\rmfamily}
\newcommand\gotolabelstyle{\itshape\rmfamily\color{gotolabel}}
Listing settings
We use columns=flexible here instead of the default columns=fixed; otherwise, the output looks quite ugly. We define a one-line delimiter starting by goto␣. Finally, we define a number of literate replacements for subscripts, for two consecutive spaces, and for the colon character.
\lstset{
basicstyle=\ttfamily\upshape\color{black},
columns=fullflexible,
moredelim=**[il][\processgoto]{goto\ },
moredelim=**[il][\processpipe]{\ |\ },
literate={_1}{{\lstsub{xs}}}1
{_2}{{\lstsub{ys}}}1
{\ \ }{\processtwospaces}2
{:}{\processcolon}1,
}
Switch
The following switch will be used as state variable and will tell us when to activate/deactivate certain styles.
\newif\ifgotolabel
EveryPar hook
At the beginning of every "true" line, we apply the style of GoTo labels and we set the switch to true.
\makeatletter
\lst@AddToHook{EveryPar}{%
\let\lst@thestyle\gotolabelstyle%
\global\gotolabeltrue%
}
Helper macros
Here, we define the macros used in the values passed to the moredelim and literate keys.
Every time goto␣ is encountered, we print it normally, but we trigger the style associated to GoTo labels; no need to set the switch (it was already set at the beginning of the current line).
\newcommand\processgoto{%
\lst@CalcLostSpaceAndOutput%
{\lst@basicstyle goto\ }\gotolabelstyle%
}
Same idea for every occurence of ␣|␣:
\newcommand\processpipe{%
\lst@CalcLostSpaceAndOutput%
{\lst@basicstyle\ |\ }\gotolabelstyle%
}
The following macro typesets subscripts in the corresponding style and applies the color of GoTo labels only if the switch is set.
\newcommand\lstsub[1]{%
\textsubscript{%
\ifgotolabel%
\color{gotolabel}%
\fi
\lstsubstyle #1%
}%
}
The following macro leaves two consecutive spaces occuring in "processing mode" unchanged, but reactivates the basic style and unset the switch. In particular, it is invoked at the beginning of each line that is indented by two spaces.
\newcommand\processtwospaces{%
\ifnum\lst@mode=\lst@Pmode%
\lst@basicstyle%
\global\gotolabelfalse%
\fi
\ \ %
}
Same idea here, but for the colon character.
\newcommand\processcolon{%
\ifnum\lst@mode=\lst@Pmode%
\lst@basicstyle%
\global\gotolabelfalse%
\fi
:%
}
\makeatother
Complete code
\documentclass{article}
\usepackage{fixltx2e}
\usepackage{listings}
\usepackage{xcolor}
% Define styles for GoTo labels and subscripts
\colorlet{gotolabel}{red}
\newcommand\lstsubstyle{\itshape\rmfamily}
\newcommand\gotolabelstyle{\itshape\rmfamily\color{gotolabel}}
%
\lstset{
basicstyle=\ttfamily\upshape\color{black},
columns=fullflexible,
moredelim=**[il][\processgoto]{goto\ },
moredelim=**[il][\processpipe]{\ |\ },
literate={_1}{{\lstsub{xs}}}1
{_2}{{\lstsub{ys}}}1
{\ \ }{\processtwospaces}2
{:}{\processcolon}1,
}
\newif\ifgotolabel
\makeatletter
\lst@AddToHook{EveryPar}{%
\let\lst@thestyle\gotolabelstyle%
\global\gotolabeltrue%
}
\newcommand\processgoto{%
\lst@CalcLostSpaceAndOutput%
{\lst@basicstyle goto\ }\gotolabelstyle%
}
\newcommand\processpipe{%
\lst@CalcLostSpaceAndOutput%
{\lst@basicstyle\ |\ }\gotolabelstyle%
}
\newcommand\lstsub[1]{%
\textsubscript{%
\ifgotolabel%
\color{gotolabel}%
\fi
\lstsubstyle #1%
}%
}
\newcommand\processtwospaces{%
\ifnum\lst@mode=\lst@Pmode%
\lst@basicstyle%
\global\gotolabelfalse%
\fi
\ \ %
}
\newcommand\processcolon{%
\ifnum\lst@mode=\lst@Pmode%
\lst@basicstyle%
\global\gotolabelfalse%
\fi
:%
}
\makeatother
\begin{document}
\begin{lstlisting}
init_2:
i_1 = 0
arr_2 = newArray (length arr_1)
goto guard_2
guard_2:
guard i_1 < length arr_1 | done_2
goto body_2
body_2:
elt_1 = readArray arr_1 i_1
elt_2 = f_2 elt_1
writeArray arr_2 i_1
i_1 := i_1 + 1
goto guard_2
done_2:
return arr_2
\end{lstlisting}
\end{document}
\lstset{...}, setting all options to\begin{lstlisting}only once and they will apply as long you override them locally or use another\lstset– Sep 11 '14 at 06:46\lstsetwas this:\lstset{moredelim=[is][\textsubscript]{\_}{\ }}. It doesn't always work and is (unsurprisingly) very picky about trailing spaces. – roldugin Sep 11 '14 at 07:18listingshacks are just amazing :-) – Daniel Sep 18 '14 at 07:24listingsfor Lua-based lexers. – Daniel Sep 18 '14 at 10:06