Lua5.0 词法分析

语法分析器会调用词法分析器。

在语法分析之前,简单的看一下词法分析。

内存管理和 ZIO 输入在词法分析中会用到,因为它们相对比较孤立,不影响主流程的阅读。

上一个版本也看过它们了,这里就不再重复了。


词法分析最重要的函数就是

int luaX_lex (LexState *LS, SemInfo *seminfo);


如果你用其它的词法分析工具生成器,生成的词法分析器也会有个类似的函数。

这个函数主要就是从源代码中读出一个 token 返回给语法分析器。


在语法分析的 next 和 lookhead 中会调用到它:

static void next (LexState *ls) { 
  ls->lastline = ls->linenumber;
  if (ls->lookahead.token != TK_EOS) {  /* is there a look-ahead token? */
    ls->t = ls->lookahead;  /* use this one */
    ls->lookahead.token = TK_EOS;  /* and discharge it */
  }
  else
    ls->t.token = luaX_lex(ls, &ls->t.seminfo);  /* read next token */
}
static void lookahead (LexState *ls) {
  lua_assert(ls->lookahead.token == TK_EOS);
  ls->lookahead.token = luaX_lex(ls, &ls->lookahead.seminfo);
}


可以看到,返回一个 token 类型和一个表示表示 token 信息的结构体。

typedef union {
  lua_Number r;
  TString *ts;
} SemInfo;  /* semantics information */
typedef struct Token {
  int token;
  SemInfo seminfo;
} Token;


luaX_lex 返回的就是 Token 结构体中的 token 类型字段。

如果类型字段不足以描述它自己的话,Token 中的 seminfo 字段就派上用场了。

比如:

对于大于小于这种比较运算,直接返回 token 就完事儿了。

case '<': {
  next(LS);
  if (LS->current != '=') return '<';
  else { next(LS); return TK_LE; }
}
case '>': {
  next(LS);
  if (LS->current != '=') return '>';
  else { next(LS); return TK_GE; }
}

而对于像是数值 TK_NUMBER,字符串型 TK_STRING 则需要将具体的 value 设置给 seminfo。 

可以认为 Token 结构体表示的为 type-value 或者 key-value 对。


你可能感兴趣的:(lua,Lua5.0)