%{
/* flex -o m.cpp m.f && gcc -o m m.cpp -lstdc++ -lfl */

#include <map>
#include <string>
#include <vector>

using namespace std;

map<int, int> footnote_ids;     /* old id -> new id */
vector<string> footnotes;       /* number -> footnote text */

int translate_fn_id(int old_id) {
       map<int, int>::const_iterator it = footnote_ids.find(old_id);
       if(it != footnote_ids.end()) return it->second;

       footnote_ids.insert(make_pair(old_id, footnote_ids.size()+1));
       return footnote_ids.size();
}

int current_fn=0;

void define_footnote(const char* txt) {
       int id = translate_fn_id(current_fn);
       if(footnotes.size() <= id) footnotes.resize(id+1);
       footnotes[id] = txt;
}

%}

%x FN FN2

%%

\[[0-9]+\]                printf("[%d]", translate_fn_id(atoi(yytext+1)));
@footnote[^\n]*\n         ECHO; BEGIN FN;

<FN>\[[[:digit:]]+\]      current_fn = atoi(yytext+1); BEGIN FN2;
<FN2>[^\n]*               define_footnote(yytext);
<FN2,FN>\n                BEGIN FN;

%%

int main(char argc, char** argv)
{
       yyin =  argc > 0 ? fopen(argv[1], "r") : stdin;
       yylex();

       for(int i=1; i<footnotes.size(); ++i)
               printf("[%d]%s\n", i, footnotes[i].c_str());

       return 0;
}