MRTZFMj;+P?9pd
zM}z-AU6G)r&0uL^g0)`Fe()HXs01rDR3cr5GUH_Ja1wCqW;sz2nCvZTyJM
zHK!S2F&uNHQ2caahAW~@03GUy#oucSYX1}{chTCZw?Sp&5Ti+IrSnmdTvnboYF4Sw
z!D=dzS+8Fug7o#{nD4#mGJ8+%Zj#w-sdWKBr{__TDrn}WC>2fNmSxCztG~Onv7SFX
zsvFEtf07o7N2d-Jn#5iFtDO5y_(gD!Furl6iR83xL`S)PfoerXp)a`3LU8l+gvpQ9
zBcUz%W(G@#=H9IMHH_JcVXa>q-JfkvlxJ*?6~)a}l$`>p?jdlZFK89;Es)lf+;6%Z562E>`)Kb;r@$FDh?2n0yzR}&@Yd0bxyFy7a$EX-<`Z}_$nD~S?HFeECSAt
z%&Dt#5{{c4DxjssjE}r{-Eov9>$@JmIbNFPI##IuX{!(3o4Oou+=KmJ
zQD@Z!>{$Hz*|wVn;6>0Qn)=jGheQfk-MgO=jfyyPI5hAkz^{213~1R9VA|Tvo(tN5
zA1~+&O{xINmk!w56G*P-Au-t2Fl!Ghwfq&QmwTY75EN(l-x5?-w3;
z?kN*A3-~K>>zVcV$=7;kR-{F>MWYyKuL{uVFoFXM`T{Q5I5_sxyCR&C6(PPCx%nkN
zf-ky)o+D}C-iHR;6LkL(e+fyfNOZ>Ujx)q6pW96YDoQE&u4}4?QKQn@UZ-c**))6R
zxX!#Ourc}B`O_c;#pwwa8>2rAqNq`gm3hyR&zZ|xX&&{kK(8fefm0kcht&8h9dU}K
z(XNOH!A~Ku*=ngoWqneC14M8xk9jl^rC2gar^CSG{BQ=ym?v%`>9(eHL6a&G(9@XR
zxO@R}_s1CQRanyTqOQD(k&B6o3vy$n@W?0P%SlpE73N=!L1t})wW%W`h2wn#8jE<(B05_{`j4cGO5#Vs{j%oJ&
z=b#jat1+6?Sh<3(m@4IHXPc5tBe1YzqjYNBx97?GeIvlqg!a7qKEDtj!m&G0_wWLS
zN6*ITRt|~{t^ne7i%!DhBCf|#Fxx8x=r{|`@=PbMw%_R?+Kzb*3W1`yOvf4YupBeH
zj?m*Sl73-%TPyTrCC&+)F>s$j3U>J!Ac~Lg;lFHXknr0qd6osB?X>m6EgOI(=6}S<
zq;U1fk-fBymtIT0KRWR6m|1Xt3!u|A#e1K+>>lWilXjn~5(P}Ww%qh}F3zjVfg%}Z
zVaW(z=J}mHT(VZRhq$rD#9_Pvgl9=i16F_Nxo8i|dr6db3SH9m_B3V~I)Hy#d
zF(QqkghkQ8fzrjbEc@919UBXQPAYi`-FU);n=~&H50(zc#gxO(MvMS!Ilgz@-
z(iVb3x)I@PZ2>!V?^*ZoW3--JGp_(_bA_btS#p8uV#uz7-vHk;rl#$W={!?(tC9Ew
zzflFxkhlHmqo6c6Rn41u=5diJ8+^qg3FIXAe{!f&4E>(u0~xZ%S203f|C_IU5umui
zTD?>RYA+cn1~iJHsv8>{=Cg6>{;6!u_vWS=T*lsK1^C@O2{-iPgN~0
zDNj1pLmDWg7WD(d&e_P{t*)rSZH2Pa(kvh@l5OI5hIjz(GSzH!!}q(U3E&nR4)pIo
zQJy-I~ovBnczn671hDb|V_~xA9jg^dV`7ia9;TC@KD0GCdG8P_u`FOxrQsaY6_+gA
z$0*b`)DrLubfZoc1}e(;fH!?ltX`}0C)<8J@lMugn4j{iNF(9R1Go$GLz1D2@1u2tOZw(wM_VIN
zWeZbFcoM$i+x&JAHv2jh?o3Dg9z#ztiYoel7QPclg{bTGe~Ec>eq@*Yii-Bg;PwZ6
z&^sqMF=iFr=sdzc_^tv(;ev$`r7FMg!;%!6-J6s(;^`$%@h-3Wb!dave5xV>%Bxef
zzGJvbr%qyGk``{c{V>%f@axE6eFbO!_wvgnipw|}o
zKc{VXJpa!tC+#R@{99}DmMN^#M+<8UJ{m?_KU#?53kWn)*~)RkML;_I+H||65Y27+peQ-{c`ivt(G!x2PlkZ~je#@c%X)JlEQwz;_(In2
z)nR^=O|_w0HtA60*c`K6=Kj#X6K>@~hRV;CfTcsv0oizZc{VdHv@S6L7(T_4;K1?6
zfq9*L5HzL?N#`*&Ir18
zS%96{Y}ZCknBpp2W3H~QK+sflI^3EpNe$^cyr2AXsx5FgvrB)rO`$LgbnX;C25xQi
z#q=v2m!P4p=W4AN9)e2C3u?ua{N7=Poa>7t(l=b-?WL`@Pw2sWd$=qhvS49?b{X3T
z+=!Ckv6ynn=Qilc`$Jrvs>v=PTR+Z9;V$Lw}R8
zoBE^Q2;N19aVUni6n37i7b){62tTxWV;A+cGpuc3V4yaYr-MA5T4`@nHJqwtgt5_`
zcaWb03f^3RXmbk52?|DdWiwP0Juk|#(E{4%Fh2zdpP>;;{K)?(Oq1fbZWx?M4dZ
z#8c#jgHHsVJ8I&%Oh!IniEk>w^+{uz@7<)wx$##={DO5sA_Nbq5DTXujlpho9}!-+d1d+KJW8B-wn-;Kr25=#HqRFr5$pK
zH!ZQZ9S7&O29h{XI%T9{=Tf)Osi@Jh=%GtWDYiziHa@VKrPRHZJ)DO+f
z52izf%h1pLCr__EsF-D0kArk2p-A8g_kZlI3_rei}>^)5}5I{#PU|P-+
z8f#SN!dpFyM^(-_0W9>`oU@FK2X!ogPjZV}@SK6ih0esI#ul`}t?+nRnY)j%B0O%H
znS*o&@J9r68xnE~JEZGJq$}EY0YN{zDR&k9M4iK28!XqZqV7EJv$U%D4&~6e11!G>
z3@MDD|E+U+SNHB_Bt5;bTg9UQgakTQ9SmNurVUb)FfgDmg}+}SxV1B@d{-nVyoJ>^
zTq#2T=14$Toq6M=*-Yqie}U!eTQTV^$PUm<@1dC%8u{pBVWuarIa}6dnvMwBcFyP%
z#{dWafla-L?0N@uFv3LIlh0hJfE?KWujt~n;WJ^^<_z4+UeXZFj>>t1L+)$32N*sH
zhEKV{KGgLCAl$8-}V6N#L6)(3!G`hjaG-b6ni0n`U7apoV`alV41i}>-_n-?3CL0tE!}6aP
zr^$j#t;Fd>iLeF|X4iwq6XlBb$wHL^_|Wq4j@(#cJM&>7B;Tw>`k_ND_&rSP8cb!R
zB@VHj8J_bavkhlGk&&Q3X*kI_%5!llF?3lK>fof8*L^<#Ay>ouB=OhQZieYDrEo`n
z;yC5|)F3-Tp7OB8*>KI!{5U{lrmlM15e@t9@qb994bky3s5?RtG2no#0w-rK
zyJSfjQSE6onhwaMFyxY>tktQZ#=p`2dl!2E)POHo1LF(^s71|g3DN5S)olx~z1trN
z=aci}8ygyq3I3%ZE&cYdrz1vKwoOO%I3JneX?^r`)V9_696|(7~`ot@`|PEg*Ywv)Dp{y
z2e9whrz}M#dwF@Kh7hX=;st-42--bf3F!nuDsKNiz(5y`OIWBwV*n3s$-YXsaLY+G
zUd_Hsh6J=eTjaO%AC}^iAk4*6X!dInr5Z_mHZDX$g@kJtPA2iN0py^*oMTfmA>Oom
zl%}@R3a+UC3+kKBMZLZFEjbB*lDOzgZ}4$H(d5oQ%F%?F(+|hdoba7IWGXe`9o*(Q
zaf%u{#FY~1fRhz^x=3)VG)zXmejo%kR3qHgvI@A^S9%2fXuu?#c{I3%clcXjB#c@n
zUCXo}##CtGskb^Z(p;h69Mf+x*JGT~qg7O@8cxauN=sH?Fdt$7LxyuQKYJm9Svd`Q
zydWLGLYEF#X+uDxyV^e9-t^{;!qU>x2vlVVT(i|QWASFU1c$!z4*Tw+MtgcypL5Ql
z%YoN%`jDC(75JJS`RC|e;&cKqy?YcLr%J4|RAFI4Xkj;#$i0$1Af@0`LkFqKRelE8{)Wh^k#QYt;KW2PW+QnL;xv~xjDinc3
zz0Vk$e3gj%m@v8&V1MrIiig^~lIPr$z47VFu(KXus)zn?GtDz3w=<0iOY_QA*YCVx
z&uqpx;BHdH=A+fxx@)leusRPfl;{A+npmeOR8oD38RoIM>3D-AFM
z%4t&6(pRSSH9Ljt;+CQHIbS`kZK78A$&0|wIU%aQl~7Cbp}KN0DSgRiOHUS929XDQ
zOx?-G;ZAU&W_$ys<8zkI({q(N;54mplWj}OxOOW8is0g)Cl85vBY7<>6!V}V{Kaq{qS
zC&1SV_Fd!ILa}7S4vhaT%mDX;#5tXeLX{Y#0^Q-C3L!}{*i^W`5Bdg6cOCPZb3Ms2L
z$|<|Kd}Cc5`aCdo&7IC|o?tdan=DD{{%Y*ch~xL_=N4)n+o`hW1aX$eg9jS9zhy>)
zs$|CG@)?dq4*r+`(pV@XdfP=MT-Y${0)Vb?=b{jiF9GwRHZ`%IK*7f%XEw^8<<+RR
z;NX9JonGZj$mVIjs;#m5M9%m&ICm5Zn`Z~LS6d-}RP}nAH4{9Vk9k2z0WgKo`<6#1
zzeEjA_f>3fj$~~a4z26t!P}kSbU;7$@_an0dDpLEiwxC}Io-$o<4Pj%&nCkM@Q$$+
zegF
ziWD{Jf_7TIHvF4mXKb`w?5m-(cs}*Rvvp??NKu=p;T|L{8z?3#CY4Mu?0W5Z&1d<57iS
zJl?)I6^^5*UioCv2==cjeDTe
zz>JltX*|FW?ScO&wX;3*Ei1FtEd1yRuWf*x)*OjgFaZ3k?3y$9iV1EeUg^Ut!G2x5
z`t}qAFNWDRg{I6+O05mGUqeatMvLznmEEQuGFCvVAp4>8>P0ot;4%m2BCAvBT$;in
z{?0o|(GLwE2TC^RmBjgRjLChvjfah_}f-n|}JEoapmJaioY3QddDK5VjTbB|U3K
z%rC=?MY-!B${j9L2?eBARG=;Pq0H!FcH%nnXJskr1xBETw9z$z40$X51Q-VkimS83
z8&3=OzM@&TGe6gdncbyxRp^bb{}RF{pf>W>Wr)5cHVaKw?=(zfD|p@MqYJ={#G?`$
zbOxD(#bC=kcmX)DQZ_I7n?e*1Y$
zQe0fzle31QtQnzYN}>nYePM^??PA6ug=H5J_kSLO@(c9$9KvYyKr)cj9KVrSz1JuQ
zvVsvYT}rTv>ZMJlto%%!Lj{HH0A&J^&dovov_5~oJ81s;HjwcIR7=8lrdaOVG0ODnl1`4DuZlq!ZzF$xH^Po%-
zyNC+NB)z78KjK;~jlSC$n{0sp_khf`z_ljJHFzQ3uCId&)^UBDP|WJ?M-NuJ!gR~1
z+6Mc74FH-lNP+(UqW^(CN)fO#5XJYn@{(@+Pj`=#zVZEY4;q%FC1Wi2+
J>d6ZM{{{9fiP!)D
literal 0
HcmV?d00001
diff --git a/easyPR-doc/test/main.md b/easyPR-doc/test/main.md
new file mode 100644
index 00000000..e69de29b
diff --git a/easyPR-doc/util/Kv.md b/easyPR-doc/util/Kv.md
new file mode 100644
index 00000000..fd01d8f6
--- /dev/null
+++ b/easyPR-doc/util/Kv.md
@@ -0,0 +1,53 @@
+### Class Kv
+
+#### Properties
+ - [`std::map data_`](#data)
+
+#### Functions
+ - [`Kv()`](#Kv)
+ - [`void load(const std::string &file)`](#load)
+ - [`std::string get(const std::string &key)`](#get)
+ - [`void add(const std::string &key,const std::string &value)`](#add)
+ - [`void remove(const std::string &key)`](#remove)
+ - [`void clear()`](#clear)
+
+***
+
+
+#### std::map< std::string,std::string > data_
+ - 存储了`map< string string >`类型的数据
+
+***
+
+
+#### Kv()
+ - 无
+
+
+#### void load(const std::string &file)
+ - 参数为`file`,即要读入的文件名
+ - 解析之前会先将`data_`清空,即调用`this.clear()`
+ - 内部解析文件,文件的存储格式都为`string(空格)string\n`
+ - 将`space`前的`string`存储在`data_`的第一个`string里`,将空格后的`string`存储在`data_`的第二个`string`里
+
+
+#### std::string get(const std::string &key)
+ - 参数为在`data_`中的`key`
+ - 返回值为`key`对应的`value`
+ - 当`value`不存在时,会打印`[Kv] cannot find ${key}`,并返回`""`
+
+
+#### void add(const std::string &key,const std::string &value)
+ - 参数为`string key`和`string value`
+ - 在`data_`中添加`key:value`
+ - 如果在`data_`中已经存在`key`时,打印`[Kv] find duplicate: %s = %s , ignore\n`
+
+
+#### void remove(const std::string &key)
+ - 参数为`string key`
+ - 删除`data_`中`key`为`string key`的值
+ - 如果没有这个`key`,打印`[Kv] cannot find ${key}`
+
+
+#### void clear()
+ - 执行`data_.clear()`,清空`data_`
diff --git a/easyPR-doc/util/Utils.md b/easyPR-doc/util/Utils.md
new file mode 100644
index 00000000..46975b28
--- /dev/null
+++ b/easyPR-doc/util/Utils.md
@@ -0,0 +1,84 @@
+### Class Utils
+
+#### Properties
+ -
+
+#### Functions
+ - [`static long getTimestamp()`](#getTimestamp)
+ - [`static std::string getFileName(const std::string &path,const bool postfix = false)`](#getFileName)
+ - [`static std::vector splitString(const std::string &str,const char delimiter)`](#splitString)
+ - [`static T min(const T &v1, const T &v2)`](#min)
+ - [`static std::vector getFiles(const std::string &folder,const bool all = true)`](#getFiles)
+ - [`static void print_str_lines(const char** lines)`](#print_str_lines1)
+ - [`static void print_str_lines(const std::initializer_list &lines)`](#print_str_lines2)
+ - [`static void print_file_lines(const std::string &file)`](#print_file_lines)
+ - [`static unsigned int levenshtein_distance(const T &s1, const T &s2)`](#levenshtein_distance)
+ - [`static bool mkdir(const std::string folder)`](#mkdir)
+ - [`static bool imwrite(const std::string &file, const cv::Mat &image)`](#imwrite)
+ - [`(private)static std::size_t get_last_slash(const std::string &path)`](#get_last_slash)
+
+***
+
+***
+
+
+#### long getTimestamp()
+ - windows:
+ - 返回`cv::getTickCount()`,即系统启动到当前的时间
+ - `cv::getTickCount()`经常用于`opencv`下计算代码运行时间
+ - linux:
+ - 使用linux时间结构体`timespes`,`CLOCK_MONOTONIC`为系统启动时间
+ - 以毫秒的形式返回系统启动到当前的时间
+ - macOS:
+ - 使用了1970/1/1来代替计算时间
+
+
+#### std::string getFileName(const std::string &path,const bool postfix = false)
+ - 输入`string &path`:文件名,`bool postfix`:是否需要后缀
+ - 返回文件名(是否有后缀取决于postfix的值)
+
+
+#### static std::vector< std::string > splitString(const std::string &str,const char delimiter)
+ - 输入`string &str`和`const char delimiter`分隔符
+ - 返回`vector`,存储了用分隔符分割的字符串
+
+
+#### static T min(const T &v1, const T &v2)
+ - 返回`(v1 < v2) ? v1 : v2`;
+
+
+#### static std::vector< std::string > getFiles(const std::string &folder,const bool all = true)
+ - 输入`string &folder`:目录,`bool all`:是否搜索子目录
+ - 返回`vector`:文件的集合
+
+
+#### static void print\_str\_lines(const char** lines)
+ - 打印行
+
+
+#### static void print\_str\_lines(const std::initializer_list &lines)
+ - 打印行
+
+
+#### static void print\_file\_lines(const std::string &file)
+ - 读取`file`中的内容,并打印
+
+
+#### static unsigned int levenshtein_distance(const T &s1, const T &s2)
+ - 输入两个`T`类型`&s1`和`&s2`
+ - 返回这两个数据的编辑距离(Levenshtein Distance),即从s1转化到s2需要的最小步数.
+
+
+#### static bool mkdir(const std::string folder)
+ - 输入`string folder`:需要创建的目录
+ - 返回:`bool`,表示创建成功或者失败
+
+
+#### static bool imwrite(const std::string &file, const cv::Mat &image)
+ - 输入`string &file`:路径,`Mat &image`:图片
+ - 输出:是否存储成功
+
+
+#### std::size\_t get\_last\_slash(const std::string &path)
+ - 输入一个`string &path`,代表了路径
+ - 返回路径`/`最后的文件名的位置
diff --git a/easyPR-doc/util/program_options.md b/easyPR-doc/util/program_options.md
new file mode 100644
index 00000000..57eabf53
--- /dev/null
+++ b/easyPR-doc/util/program_options.md
@@ -0,0 +1,157 @@
+### Class:
+ - [Class Row](#Row)
+ - [Class Subroutine](#Subroutine)
+ - [Class Generator](#Generator)
+
+
+### Class Row
+
+#### Properties
+ - `(private)`:
+ - [`bool require_value`](#require_value)
+ - [`std::string option_short`](#option_short)
+ - [`std::string option_long`](#option_long)
+ - [`std::string default_value`](#default_value)
+ - [`std::string description`](#description)
+ - `(public)`:
+ - [`enum Field { kShort, kLong, kDefault, kDescription }`](#Field)
+ - [`typedef std::initializer_list Order`](#Order)
+
+#### Functions
+ - `(public)`:
+ - [`Row()`](#Row)
+ - [`inline std::string oshort() const { return option_short; }`](#oshort_get)
+ - [`inline std::string olong() const { return option_long; }`](#olong_get)
+ - [`inline std::string value() const { return default_value; }`](#value_get)
+ - [`inline std::string desc() const { return description; }`](#desc_get)
+ - [`inline bool required() const { return require_value; }`](#required_get)
+ - [`inline void oshort(const std::string& oshort) { option_short = oshort; }`](#oshort_set)
+ - [`inline void olong(const std::string& olong) { option_long = olong; }`](#olong_set)
+ - [`inline void value(const std::string& value) { default_value = value; }`](#value_set)
+ - [`inline void desc(const std::string& desc) { description = desc; }`](#desc_set)
+ - [`inline void required(bool required) { require_value = required; }`](#required_set)
+***
+ -
+***
+
+
+### Class Subroutine
+
+#### Properties
+ - `(public)`:
+ - [`typedef std::vector Usages`](#Usages)
+ - [`typedef std::initializer_list TemplateValue`](#TemplateValue)
+ - [`typedef std::vector TemplateValues`](#TemplateValues)
+ - `(private)`:
+ - [`Usages usages_`](#usages_)
+ - [`TemplateValues templates_`](#templates_)
+ - [`const char* first_line_`](#first_line_)
+ - [`const char* description_`](#description_)
+ - [`std::string name_`](#name_)
+ - [`std::string template_str_`](#template_str_)
+ - [`Row::Order order_`](#order_)
+
+#### Functions
+ - `(public)`:
+ - [`Subroutine()`](#Subroutine1)
+ - [`Subroutine(const char* name, const char* description)`](#Subroutine2)
+ - [`inline void add_usage_line(const Row& row) { usages_.push_back(row); }`](#add_usage_line1)
+ - [`inline void add_usage_line(const TemplateValue& row) {templates_.push_back(row);}`](#add_usage_line2)
+ - [`inline void set_first_line(const char* line) { first_line_ = line; }`](#set_first_line)
+ - [`inline void set_description(const char* desc) { description_ = desc; }`](#set_description)
+ - [`inline void set_template(const char* tstr, const Row::Order& order)`](#set_template)
+ - [`inline std::string to_string()`](#to_string)
+ - [`inline std::string get_name() const { return name_; }`](#get_name)
+ - [`inline const char* get_description() const { return description_; }`](#get_description)
+ - [`inline const char* get_first_line() const { return first_line_; }`](#get_first_line)
+ - [`inline Usages::iterator begin() { return usages_.begin(); }`](#begin)
+ - [`inline Usages::iterator end() { return usages_.end(); }`](#end)
+ - [`inline size_t size() { return usages_.size(); }`](#size)
+ - [`inline Row& at(size_t i) { return usages_.at(i); }`](#at)
+ - [`inline const Usages& get_usage() const { return usages_; }`](#get_usage)
+ - [`inline static const char* get_default_name() { return "EmptySubroutine"; }`](#get_default_name)
+ - `(private)`:
+ - [`friend std::ostream& operator<<(std::ostream& out, Subroutine& subroutine)`](#operator_subroutine)
+ - [`void print_with_row(std::ostream& out)`](#print_with_row)
+ - [`void print_with_template(std::ostream& out)`](#print_with_template)
+***
+
+***
+
+#### Subroutine()
+
+
+#### Subroutine(const char* name, const char* description)
+ - //need to confirm
+
+
+### Class Generator
+
+#### Properties
+ - [`typedef std::map SubroutineCollection`](#SubroutineCollection)
+ - [`(private)const char kDelimiter`](#kDelimiter)
+ - [`(private)SubroutineCollection subroutines_`](#subroutines)
+ - [`(private)std::string current_subroutine_`](#current_subroutine_)
+ - [`(private)Parser* parser_`](#parser_)
+
+#### Functions
+ - (`public:`)
+ - [`Generator()`](#Generator)
+ - [`~Generator()`](#~Generator)
+ - [`Generator& make_usage(const char* first_line)`](#make_usage)
+ - [`Parser* make_parser()`](#make_parser)
+ - [`Generator& add_subroutine(const char* name)`](#add_subroutine1`)
+ - [`Generator& add_subroutine(const char* name, const char* description)`](#add_subroutine2)
+ - [`std::map get_subroutine_list()`](#get_subroutine_list)
+ - [`inline std::string to_string()`](#to_string)
+ - [`inline Generator& operator()(const char* option, const char* description)`](#operator1)
+ - [`inline Generator& operator()(const char* option, const char* default_value,const char* description)`](#operator2)
+ - [`inline Subroutine& operator()(const char* name)`](#operator3)
+ - [`inline Generator& make_template(const char* template_str,const Row::Order& order)`](#operator4)
+ - (`private:`)
+ - [`(private)inline Subroutine* get_subroutine()`](#get_subroutine)
+ - [`(private)friend std::ostream& operator<<(std::ostream& out, Generator& generator)`](#operator5)
+ - [`(private)bool add_usage_line(const char* option,const char* default_value,const char* description)`](#add_usage_line)
+
+***
+
+#### typedef std::map SubroutineCollection
+ - 用于存储`[string:Subroutine]`的`map`:`SubroutineCollection`
+
+
+#### (private)SubroutineCollection subroutines_
+ - `SubroutineCollection`类型,用来存储`Subroutine`集合
+
+
+#### (private)std::string current_subroutine_
+ - 表示当前子程序
+
+
+#### (private)Parser* parser_
+ - 在构造方法中被初始化为`nullptr`
+
+***
+
+#### Generator()
+ - 向`subroutines_`添加一条["EmptySubroutine",new Subroutine("EmptySubroutine","")]
+
+
+#### Generator& make_usage(const char* first_line)
+ - 获取当前`current_subroutine_`在`subroutines_`中对应的`Subroutine`
+ - 将上述的`Subroutine`的属性`first_line`设置成输入的参数`first_line`
+ - 返回`*this`
+
+#### Generator& add_subroutine(const char* name)
+ - 执行`add_subroutine(name, "")`
+ - 执行`return *this`,返回当前`Generator`
+
+
+#### Generator& add_subroutine(const char* name, const char* description)
+ - 查找`subroutines_`中有没有子程序`name`
+ - 如果有,则`return *this`
+ - 如果没有,则将`[name:new Subroutine(name,description)]`添加到`subroutines_`中
+
+
+#### inline Subroutine* get_subroutine(){return subroutines_.at(current_subroutine_);}
+ - 输入`current_subroutine_`
+ - 返回`subroutines`中`current_subroutine_`对应的`Subroutine`,即当前指令