UVA12421 (Jiandan) Mua (I) - Lexical Analyzer

题目描述

在这个系列的题目中,你需要实现 Lua 语言($5.1$ 版本)的一个子集,叫做 mini-Lua(mua)。这是刘汝佳的实验性语言之一,主要用于实现算法,而非真实世界的程序。 这是该系列的第一个问题,你需要编写一个词法分析器(lexer),也就是将输入的程序拆分为一系列 **词法单元**(定义如下)。 在 mini-lua 中,共有六种词法单元: **保留字(RESERVED)**:以下是保留字列表。请注意,mini-lua 是区分大小写的,因此 $\text{AND}$ 不是一个保留字。另外,虽然这些保留字并不都在 mini-lua 中被使用,但我们想要所有在 mini-lua 合法的程序在 Lua 中也是合法的。 $$ \begin{array}{l l l l l l} \texttt{and}\quad&\texttt{break}\quad&\texttt{do}\quad&\texttt{else}\quad&\texttt{elseif}\\ \texttt{end}\quad&\texttt{false}\quad&\texttt{for}\quad&\texttt{function}\quad&\texttt{if}\\ \texttt{in}\quad&\texttt{local}\quad&\texttt{nil}\quad&\texttt{not}\quad&\texttt{or}\\ \texttt{repeat}\quad&\texttt{return}\quad&\texttt{then}\quad&\texttt{true}\quad&\texttt{until}\quad&\texttt{while} \end{array} $$ **数字(NUMBER)**:数字分为两种: + 整数:十进制整数由一位或多位数字($0\sim 9$)组成;十六进制整数以 $\texttt{0x}$ 或 $\texttt{0X}$ 开头,后面跟着一位或多位十六进制数字($0\sim 9$、$\texttt{a}\sim\texttt{f}$,不区分大小写)。注意,前导零会被忽略(例如,$0123$ 相当于 $123$)。 + 浮点数:始终使用十进制,例如 $1.23$。可以使用科学记数法,即在数字后添加 $\texttt{e}$ 或 $\texttt{E}$,再跟着一个十进制指数(例如 $\text{1.23e2}$,其值为 $123.0$)。小数点或指数部分至少需要出现一个,但整数部分可以省略(例如 $\text{.2e3}$)。若省略整数部分,则必须保留小数点和小数点后的至少一位数字(因此,$\text{.e2}$ 是非法的)。不支持十六进制的浮点数。注意,指数前可以有“+”或“-”,例如 $\text{1e+10}$ 和 $\text{4e-3}$。 需要注意的是,负数实际上由两个词法单元组成:一元“负号”运算符和绝对值数字。例如,$\text{-34}$ 包含两个词法单元。同理,$\text{+7e8}$ 也包含两个词法单元。 **字符串(STRING)**:由 $\texttt{""}$ 或 $\texttt{''}$ 包围的字符串。仅支持四种转义字符:$\texttt{\textbackslash"\space\textbackslash'\space\textbackslash\textbackslash\space\textbackslash n}$。字符串中不能包含真正的换行符。 **符号(SYMBOL)**:具有特殊含义的符号。以下是符号列表: $$ \begin{array}{l l l l l l l} \texttt{+}\quad&\texttt{-}\quad&\texttt{*}\quad&\texttt{/}\quad&\texttt{\%}\quad&\texttt{\verb|^|}\quad&\texttt{\#}\\ \texttt{==}\quad&\texttt{\verb|~|=}\quad&\texttt{=}\quad&\texttt{}\quad&\texttt{=}\\ \texttt{(}\quad&\texttt{)}\quad&\texttt{\{}\quad&\texttt{\}}\quad&\texttt{[}\quad&\texttt{]}\\ \texttt{;}\quad&\texttt{:}\quad&\texttt{,}\quad&\texttt{.}\quad&\texttt{..}\quad&\texttt{...}\\ \end{array} $$ **名称(NAME)**:以字母开头,后面可以跟着字母、数字或下划线的标识符。注意,保留字不能用作名称。 **行尾(EOL)**:表示一行的结尾。 **注释(COMMENT)**:以 $‘\texttt{--}’$ 开头,不能跨行(注释后的换行符依然存在,它需要作为一个单独的 $\text{EOL}$ 词法单元)。 字符串常量外的空白字符会被忽略,因此 $‘\texttt{1+1}’$ 和 $‘\texttt{1+\space 1}’$ 对词法分析器来说没有区别。 词法分析器应当采用贪心策略,即若存在多种拆分词法单元的方式,先让第一个词法单元尽量长,然后让第二个词法单元尽量长,以此类推。例如,$‘\texttt{abc123

输入格式

一个合法的 mini-lua 程序。

输出格式

对于所有非注释类型的词法单元,每行一个,格式为 $\texttt{[TYPE] token}$,其中 $\texttt{TYPE}$ 表示词法单元类型,$\texttt{token}$ 表示词法单元内容(你需要按照输入原样去输出词法单元中的内容)。若类型为 $\text{EOL}$,则 $\texttt{token}$ 为空。