Skip to content

Latest commit

 

History

History
81 lines (41 loc) · 2.27 KB

ch04-Lua词法.md

File metadata and controls

81 lines (41 loc) · 2.27 KB

Lua词法

Lua使用的一遍扫描代码文件的同时生成opcode指令,这么做主要是为了解释执行的速度。但是速度快的背后,带来的却是这一部分代码比较难以理解。可以说,由于我编译部分基础知识的匮乏,这一部分是给我带来最大障碍的代码。

Lua的遍历使用的是递归下降分析,其EBNF词法如下,基本上是按照lparser.c中的函数对照来整理的,读者可以不必在前期完全理解这些内容,后面会按照不同的指令来进行分析,到时候需要对照着这部分EBNF进行理解:


chunk -> { stat [`;'] }

stat -> ifstat | whilestat | dostat | forstat | repeatstat | funcstat | localstat | retstat | breakstat | exprstat

ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END

whilestat -> WHILE cond DO block END

dostat -> DO block END

forstat -> FOR {fornum | forlist} END

repeatstat -> REPEAT block UNTIL cond

funcstat -> FUNCTION funcname body

localstat -> LOCAL function Name funcbody | LOCAL NAME {`,' NAME} [`=' explist1]

retstat -> RETURN [explist1]

breakstat -> BREAK

exprstat -> primaryexp

block ->

cond ->

fornum ->

forlist ->

funcname ->

body ->

primaryexp -> prefixexp {`.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs }

prefixexp -> NAME | `(' exp `)'

funcargs -> `(' explist1 `)' | constructor | STRING

exp -> subexpr

subexpr -> (simpleexp | unop subexpr) {binop subexpr}

simpleexp -> NUMBER | STRING | NIL | true | false | ... | constructor | FUNCTION body | primaryexp

explist1 -> expr {`,' expr}

constructor -> `{' [ fieldlist ]  `}'

fieldlist -> field { fieldsep field } [ fieldsep ]

field -> ‘[’ exp ‘]’ ‘=’ exp | name ‘=’ exp | exp

fieldsep -> ‘,’ | ‘;’

fieldlist ->

unop ->

binop ->

注意在上面的EBNF词法中:

  • "{}"尖括号包住的部分表示是可选的,比如一个if表达式ifstat中,else的部分不是必须存在的。
  • "[]"中括号包住的部分,表示会有0次或多次出现,比如一个返回表达式retstat中,return关键字后面的表达式列表就是这样的例子。
  • 大写字母表示一个终结符,所谓终结符就是不能在继续用子表达式表示它的符号,如上面的STRING表示字符串,NUMBER表示数字,等等。