Page 280 - 《软件学报》2021年第6期
P. 280

1854                                     Journal of Software  软件学报 Vol.32, No.6,  June 2021

         3.1   预处理模块
             在预处理模块中,需要处理版本标识语句和导入其他源文件语句.由于版本标识语句并不会影响 Solidity 源
         程序的正确性和逻辑性,因此只需要对其进行移除.导入其他源文件是使用保留字 import 进行声明,导入语句的
         作用是待导入文件的所有全局变量导入到当前文件中的全局作用域中,以便于模块化代码.因此,需要先将待导
         入文件的全局变量合并到当前文件中,之后再进行词法分析.若不存在导入语句,直接进行后续分析.

         3.2   词法分析模块
             词法分析模块顺序扫描 Solidity 源程序,根据构词规则将其识别为具有特定含义的单词,并按照属性对其进
         行分类和标识.本文使用 JavaCC 工具自动生成词法分析器.一般的词法分析器包含 SKIP 与 TOKEN 两部分:
         SIKP 定义了源程序中需要忽略的部分,如注释部分和空白部分等;TOKEN 中使用正则表达式定义了需要特定
         识别的单词,在扫描源程序的过程中对字符序列进行分割并识别为单词及其属性,最终将所得到的 TOKEN 序
         列交给语法分析器.
             SKIP 部分定义了需要自动跳过的部分,包括单行注释、多行注释、空格、缩进符、换行符以及回车符,使
         用正则表达式描述其构词规则如图 4 所示.
                                     1   SKIP
                                     2   {
                                     3
                                     4     “⋅”|“\t”|“\n”|“\r”
                                     5
                                     6  |〈“//”(~[“\r”,“\n”])*(“\n”|“\r”|“\r\n”)〉

                                     7

                                     8  |〈“/*”(~[“*”])*“*”(~[“/”](~[“*”])*“*”)*“/”〉
                                     9
                                     10 }
                                              Fig.4   SKIP part
                                              图 4   SKIP 部分
             TOKEN 部分定义了需要特定识别的内容,主要包括保留字、标识符、常量以及运算符等.
             (1)  保留字
             如表 1 所示:int 与 uint 均可表示整型类型,且可以限定整型变量的长度,如 int8 到 int256,当省略后面数字时,
         默认为 int256;保留字 public/private/internal 用于表明函数或者变量的可见性,但由于可见性并不影响程序的逻
         辑性和正确性,因此予以忽略;保留字 event 用于定义一个事件,用于调用以太坊虚拟机日志功能的接口,起到储
         存记录的作用,并不影响程序的逻辑性和正确性,因此忽略 event 保留字.

                                           Table 1   Reserved words
                                                表 1   保留字
                                  保留字         对应标记        保留字        对应标记
                                 “contract”  CONTRACT     “return”   RETURN
                                  “solidity”  SOLIDITY   “payable”  PAYABLE
                                “int”(〈ISIZE〉)?   INT      “if”        IF
                               “bytes”(〈BSIZE〉)?  BYTES   “while”    WHILE
                                   “bool”      BOOL       “throw”    THROW
                                 “function”  FUNCTION     “struct”   STRUCT
                                  “public”    PUBLIC   “uint”(〈ISIZE〉)?  UINT
                                  “address”  ADDRESS     “mapping”  MAPPING
                                  “private”   PRIVATE    “internal”  INTERNAL
                                  “returns”  RETURNS       “else”     ELSE
              (2)  标识符
             标识符包含用户自定义的合约名、函数名以及变量名等,其首字母为下划线或字母,其他部分为下划线、
         字母以及数字.当一个单词既能够被识别为保留字,又能够被识别为标识符时,将其首先识别为保留字.标识符
         的正则表达式如图 5 所示.
   275   276   277   278   279   280   281   282   283   284   285