当前位置: 首页 > news >正文

大连城市建设集团网站网页美工怎么做

大连城市建设集团网站,网页美工怎么做,济南网站建设有限公司,资讯是做网站还是公众号LuaJIT源码分析#xff08;五#xff09;词法分析 lua虽然是脚本语言#xff0c;但在执行时#xff0c;还是先将脚本编译成字节码#xff0c;然后再由虚拟机解释执行。在编译脚本时#xff0c;首先需要对源代码进行词法分析#xff0c;把源代码分解为token流。lua的toke… LuaJIT源码分析五词法分析 lua虽然是脚本语言但在执行时还是先将脚本编译成字节码然后再由虚拟机解释执行。在编译脚本时首先需要对源代码进行词法分析把源代码分解为token流。lua的token可以分为若干不同的类型比如关键字标识符字面量运算符分隔符等等。 标识符 可以是由字母、数字和下划线组成的任意字符串但不能以数字开头。 关键字 具有特殊含义的保留字不可以用作标识符共有22个。 and break do else elseifend false for function ifin local nil not orrepeat return then true until while字符串字面常量 lua的字面字符串定义相当灵活以下几种写法都是合法的而且表示同一个字符串 a alo\n123a alo\n123\a \97lo\10\04923a [[alo123]]a [[alo123]]数字字面常量 一个数值常量可以用可选的小数部分和可选的小数指数来表示。lua还接受十六进制整数常量通过在前面加上0x来表示。以下几种表示形式都是合法的 3 3.0 3.1416 314.16e-2 0.31416E1 0xff 0x56运算符和分隔符 主要有以下若干种。 - * / % ^ # ~ ( ) { } [ ]; : , . .. ...LuaJIT的词法分析代码集中在lex_scan这个函数上。在深入之前我们先了解一下LuaJIT用于词法分析的数据结构。 // lj_lex.h /* Lua lexer state. */ typedef struct LexState {struct FuncState *fs; /* Current FuncState. Defined in lj_parse.c. */struct lua_State *L; /* Lua state. */TValue tokval; /* Current token value. */TValue lookaheadval; /* Lookahead token value. */const char *p; /* Current position in input buffer. */const char *pe; /* End of input buffer. */LexChar c; /* Current character. */LexToken tok; /* Current token. */LexToken lookahead; /* Lookahead token. */SBuf sb; /* String buffer for tokens. */lua_Reader rfunc; /* Reader callback. */void *rdata; /* Reader callback data. */BCLine linenumber; /* Input line counter. */BCLine lastline; /* Line of last token. */GCstr *chunkname; /* Current chunk name (interned string). */const char *chunkarg; /* Chunk name argument. */const char *mode; /* Allow loading bytecode (b) and/or source text (t). */VarInfo *vstack; /* Stack for names and extents of local variables. */MSize sizevstack; /* Size of variable stack. */MSize vtop; /* Top of variable stack. */BCInsLine *bcstack; /* Stack for bytecode instructions/line numbers. */MSize sizebcstack; /* Size of bytecode stack. */uint32_t level; /* Syntactical nesting level. */int endmark; /* Trust bytecode end marker, even if not at EOF. */int fr2; /* Generate bytecode for LJ_FR2 mode. */ } LexState;数据结构看上去很复杂不过好在每个成员变量都有相应的注释而且在目前讨论的词法分析阶段中只有少数几个成员变量需要考虑 // lj_lex.h /* Lua lexer state. */ typedef struct LexState {TValue tokval; /* Current token value. */TValue lookaheadval; /* Lookahead token value. */const char *p; /* Current position in input buffer. */const char *pe; /* End of input buffer. */LexChar c; /* Current character. */LexToken tok; /* Current token. */LexToken lookahead; /* Lookahead token. */SBuf sb; /* String buffer for tokens. */ } LexState;tokval和lookaheadval分别表示当前扫描到的token和下一个即将被扫描的tokenp和pe表示扫描的源代码buffer当前位置和重点位置c表示当前扫描到的字符tok和lookahead分别表示当前和下一个扫描的token类型最后sb表示处理当前token所缓存的buffer。 LuaJIT的词法分析实现基本上也是个有限状态机根据当前读到的字符切换到不同的读取状态 /* Get next lexical token. */ static LexToken lex_scan(LexState *ls, TValue *tv) {lj_buf_reset(ls-sb);for (;;) {if (lj_char_isident(ls-c)) {GCstr *s;if (lj_char_isdigit(ls-c)) { /* Numeric literal. */lex_number(ls, tv);return TK_number;}/* Identifier or reserved word. */do {lex_savenext(ls);} while (lj_char_isident(ls-c));s lj_parse_keepstr(ls, ls-sb.b, sbuflen(ls-sb));setstrV(ls-L, tv, s);if (s-reserved 0) /* Reserved word? */return TK_OFS s-reserved;return TK_name;}switch (ls-c) {case \n:case \r:lex_newline(ls);continue;case :case \t:case \v:case \f:lex_next(ls);continue;case -:lex_next(ls);if (ls-c ! -) return -;lex_next(ls);if (ls-c [) { /* Long comment --[*[...]*]. */int sep lex_skipeq(ls);lj_buf_reset(ls-sb); /* lex_skipeq may dirty the buffer */if (sep 0) {lex_longstring(ls, NULL, sep);lj_buf_reset(ls-sb);continue;}}/* Short comment --.*\n. */while (!lex_iseol(ls) ls-c ! LEX_EOF)lex_next(ls);continue;case [: {int sep lex_skipeq(ls);if (sep 0) {lex_longstring(ls, tv, sep);return TK_string;} else if (sep -1) {return [;} else {lj_lex_error(ls, TK_string, LJ_ERR_XLDELIM);continue;}}case :lex_next(ls);if (ls-c ! ) return ; else { lex_next(ls); return TK_eq; }case :lex_next(ls);if (ls-c ! ) return ; else { lex_next(ls); return TK_le; }case :lex_next(ls);if (ls-c ! ) return ; else { lex_next(ls); return TK_ge; }case ~:lex_next(ls);if (ls-c ! ) return ~; else { lex_next(ls); return TK_ne; }case ::lex_next(ls);if (ls-c ! :) return :; else { lex_next(ls); return TK_label; }case :case \:lex_string(ls, tv);return TK_string;case .:if (lex_savenext(ls) .) {lex_next(ls);if (ls-c .) {lex_next(ls);return TK_dots; /* ... */}return TK_concat; /* .. */} else if (!lj_char_isdigit(ls-c)) {return .;} else {lex_number(ls, tv);return TK_number;}case LEX_EOF:return TK_eof;default: {LexChar c ls-c;lex_next(ls);return c; /* Single-char tokens ( - / ...). */}}} }lex_scan会返回当前扫描的token类型LuaJIT只对那些不能用单字符表示的token进行了定义如果token本身就是单字符的比如( - / )之类就直接用该字符作为它的token类型。由于char的取值范围为0-255那么特殊定义的token类型需要从256开始了。 // lj_lex.h /* Lua lexer tokens. */ #define TKDEF(_, __) \_(and) _(break) _(do) _(else) _(elseif) _(end) _(false) \_(for) _(function) _(goto) _(if) _(in) _(local) _(nil) _(not) _(or) \_(repeat) _(return) _(then) _(true) _(until) _(while) \__(concat, ..) __(dots, ...) __(eq, ) __(ge, ) __(le, ) __(ne, ~) \__(label, ::) __(number, number) __(name, name) __(string, string) \__(eof, eof)enum {TK_OFS 256, #define TKENUM1(name) TK_##name, #define TKENUM2(name, sym) TK_##name, TKDEF(TKENUM1, TKENUM2) #undef TKENUM1 #undef TKENUM2TK_RESERVED TK_while - TK_OFS };可能会有疑问的一点是为什么这里要引入TKENUM1和TKENUM2两种不同的宏明明作用完全相同。答案是作者为了简洁少写一些代码把LuaJIT的关键字定义也套用到了TKDEF这个宏上 // lj_lex.c /* Lua lexer token names. */ static const char *const tokennames[] { #define TKSTR1(name) #name, #define TKSTR2(name, sym) #sym, TKDEF(TKSTR1, TKSTR2) #undef TKSTR1 #undef TKSTR2NULL };接下来我们回到lex_scan函数上首先函数会调用lj_buf_reset清理缓存的token buffer这个buffer只在单次scan中有效。然后LuaJIT开始判断当前字符是一个什么样的字符。这里LuaJIT使用了查表的方式预先将ASCII表中的所有字符进行属性标记。 // lj_char.h #define LJ_CHAR_CNTRL 0x01 #define LJ_CHAR_SPACE 0x02 #define LJ_CHAR_PUNCT 0x04 #define LJ_CHAR_DIGIT 0x08 #define LJ_CHAR_XDIGIT 0x10 #define LJ_CHAR_UPPER 0x20 #define LJ_CHAR_LOWER 0x40 #define LJ_CHAR_IDENT 0x80 #define LJ_CHAR_ALPHA (LJ_CHAR_LOWER|LJ_CHAR_UPPER) #define LJ_CHAR_ALNUM (LJ_CHAR_ALPHA|LJ_CHAR_DIGIT) #define LJ_CHAR_GRAPH (LJ_CHAR_ALNUM|LJ_CHAR_PUNCT)LJ_DATA const uint8_t lj_char_bits[257];剩下的逻辑其实就比较简单了如果当前字符是数字那么就走假设token是数字字面常量的逻辑如果是字母下划线那就走关键字或是标识符的逻辑否则就走其他处理逻辑。这些处理逻辑都比较简单如果只通过当前字符无法判断token类型就会去读取下一个字符甚至更多字符来进行判断。例如遇到字符.时会尝试再读取一个字符如果依旧是.那么还需要再读一个字符来确定当前token是TK_dots ...还是TK_concat ..如果不是那么根据字符是否为数字就能得出token是TK_number还是.类型了。
http://www.w-s-a.com/news/711248/

相关文章:

  • 免费可商用素材网站山东威海网站开发
  • 建设网站什么语言比较合适柳州建设网经济适用房
  • 企业网站的主要功能板块平台推广是做什么的
  • 网页网站自做全搞定西安建设工程信息网诚信平台
  • 网站vip怎么做建网站外包公司
  • 胶州建网站域名不备案可以正常使用吗
  • 网站建设客户开发方案软件工程师行业分析
  • 沈阳网站建设黑酷科技微信小程序怎么一键删除
  • 做网站产品搜索展示实现西安百度推广服务公司
  • 建立网站接受投注是什么意思一般使用的分辨率的显示密度是多少
  • 怎么建立一个网站开展业务网站建设人员的工资分配
  • 求职网站建设方案企业网站开发需求分析
  • 西安企业网站开发可以做哪些有趣的网站
  • 房产类网站开发云南百度建站
  • 泰州网站建设电话彩票网站怎么做代理
  • 泉州网站制作推广山西网站开发建设
  • 百度商桥怎样绑定网站百度推广登陆
  • 重庆网站建设论坛株洲论坛
  • 网站怎么做切换中英文济南广运建设公司网站
  • 网页游戏网站搭建免费建网站哪个模板多
  • 公司起名打分最准的免费网站直播网站app开发
  • 医疗器械类网站前置审批网站临时域名
  • 金融网站策划方案网站开发表格整体页面居中
  • 句容本地网站黄石下陆区建设局网站
  • 免费网站服务陕西省咸阳市建设银行网站
  • 网站建设活动计划做网站意义
  • 莱芜新闻主持人名单seo sem 外贸建站 网站建设 文化墙设计
  • 易语言可以做网站嘛赣州网站建设开发
  • 网站建设规范布局网站建设费往什么科目
  • 乐清手机网站设计哪个汽车网站汽贸店免费做