1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
use v5.10;
use warnings;
my $parser = do{
use Regexp::Grammars;
qr{
<file>
<rule: file>
<[element]>*
<rule: element>
<special> | <command> | <literal>
<token: special>
<MATCH= mathematical>
| <MATCH= group>
| <MATCH= comment>
| <MATCH= vinculum>
| <MATCH= newline>
| <MATCH= super>
| <MATCH= sub>
| <MATCH= column_separator>
<rule: mathematical>
\$ <[element]>* \$
<rule: comment>
\# <MATCH= ( [^\n]* \n [^\S\n]* )>
<rule: vinculum>
\~
<rule: newline>
\\ \\
<rule: super>
\^
<rule: sub>
\_
<rule: column_separator>
\$
<rule: command>
\\ <name> <options>? <[arg=group]>*
<rule: options>
\[ <[option]>+ % <_Sep=(,)> \]
<rule: group>
\{ <[element]>* \}
<rule: option>
[^][\$&%#_{}~^\s,]++
<token: literal>
<MATCH=( [^][\\\$&%#_{}~^\s]*+ (?: \\[^\w\\] [^][\\\$&%#_{}~^\s]*+ )*+ )>
<require: (?{ length($CAPTURE) > 0 })>
<token: name>
<MATCH=alphas> | <MATCH=single_nonalpha>
<token: alphas>
<MATCH=([^\W\d_]++)>
<token: single_nonalpha>
<MATCH=([\W\d_])>
}xms
};
my $input = do{ local $/; <DATA>};
if ($input =~ $parser) {
use Data::Dumper 'Dumper';
warn Dumper [ \%/ ];
}
__DATA__
\documentclass[a4paper,11pt]{article}
\usepackage{latexsym}
\author{D.~Conway}
\title{Parsing \LaTeX{}}
\begin{document}
\maketitle
\tableofcontents
\section{Description}
...is easy \footnote{But not\\ \emph{necessarily} simple}.
In fact it's $easy_peasy^2$ to do.
\end{document}
|