Tokens
 

接口

词法分析器的基本公共界面来自lex.bas
    • lexGetToken():检索当前令牌的id,一个FB_TK_ *值。
    • lexGetLookAhead(N):向前看N个令牌
    • lexSkipToken():转到下一个标记
    • lexGetText():将zstring ptr返回到当前令牌的文本,例如字符串/数字字面值(它们的值如此检索)或其他标记的文本表示(例如,运算符 )。
    • 更多lexGet*()访问当前令牌的数据
    • lexPeekLine():由错误报告用于检索当前代码行。

当前令牌+向前看标记

令牌是一件很短暂的事情。当前的令牌只有一些令牌队列中的令牌,所有解析器需要解密FB代码。通常的模式是检查当前的标记,根据它是什么来决定下一步做什么,然后跳过它并继续。向后运动是不可能的。错误报告期间显示的文件名,行号和令牌位置也来自当前的词法分析器状态。

令牌队列是令牌的静态数组,其中包含当前令牌的空间以及几个向前的令牌。令牌结构包含用于令牌文本的相当大(静态)缓冲区。每个令牌都有一个指向下一个的指针,所以它们形成一个循环列表。这是一个便捷的方式向前移动并跳过令牌,而无需处理数组索引。因为巨大的文本缓冲区,复制令牌本身是没有问题的。“头”指向当前令牌;下一个“k”令牌是向前看的令牌;其余的未使用。当我们跳过时,我们只需要做“head = head- >next”。除非新的头已经包含一个令牌(从前面的一些前景),我们将新的令牌加载到新的当前标记结构体(通过lexNextToken())。通过在队列中加载以下令牌(但不跳过当前的令牌),向前看。

{断词}999796002
lex.bas:lexNextToken()

词法分析器将文件输入分解成令牌。标记在概念上是标识符,关键字,字符串文字,数字字面值,操作符,EOL或EOF,或其他字符,如括号和逗号。每个令牌作为赋值给它的唯一值,解析器将使用它来标识它,而不是进行字符串比较(这将太慢)。

lexNextToken()使用当前的char,并且如果需要还可以前瞻性的char来解析输入。数字和字符串文字也在这里处理。在symb哈希表中查找字母数字标识符,这将表明它是关键字,宏还是其他FB符号(类型,过程,变量,...)。

包含点(QB兼容性)和标识符类型后缀(如stringvar $)的标识符也在这里处理(但不是命名空间/结构成员访问)。令牌可以具有与它们相关联的数据类型。这也与数字文字一起使用,可以有类型后缀(如&hFFFFFFFFFFFFFFFFull)。

单行评论旁边的留言

非常不寻常的,单行注释由解析器处理,而不是在词法分析器中跳过。这样做就可以像QB那样容易地限制REM的使用,所以REM更像是一个声明而不是一个注释。此外,注释可以包含QB元语句,因此注释不能被忽略。请注意,如果找不到QB元语句,解析器仍然会跳过注释的其余部分(不带标记)。

(多行注释在标记化期间完全处理。)

文件输入
lex.bas:hReadChar()

输入文件在fb.bas:fbCompile()中打开;文件编号存储在全局env上下文中(#989796045}中的#includes类似)。词法分析器使用env上下文中的文件编号来读取输入。它有一个静态的zstring缓冲区,用于流式传输文件内容(而不是读取每个字符的字符),而对于Unicode输入,词法分析器使用wstring缓冲区,将UTF32或UTF8解码为UTF16。词法分析器通过缓冲区中的字符进行读取,然后从文件读入下一个块。返回NULL字符表示EOF。