LuaLua脚本语言开发

词法分析_2

2019-06-06  本文已影响7人  Moid莫
Lexer = {p=1,src="",line=0,code=true,list={},tmp="",err=false,errors="",keyword={i_null="null",i_true="true",i_false="false",i_s="s",i_ss="ss",i_sss="sss",i_f="f",i_else="else",i_w="w",i_t="t",i_for="for",i_fn="fn",i_end="end",i_goto="goto",i_endcode="endcode",i_return="return"}}

function Lexer:new(str)

  self.src = str
  return self

end

先创个lua文件,p是字符串指针、src是字符串、line表示当前行、list用来保存每行代码(出错时用来提示)、err是错误判断、errors用来保存错误信息、keyword是关键字列表。其它的信息暂时不讲。用处不大

然后function Lexer:new用来初始化。

再写个run方法函数用于开始词法解析

下面是具体代码,有一定lua基础的人应该能看懂

function Lexer:run()

  local result,code = {},true

  while code do
    
    local token = Lexer:next()
    
    if Lexer.errors ~= "" then return Lexer.errors,Lexer.list,true end
   
    if token == nil then return result,Lexer.list,false end
    
    result[#result+1] = token
    
    end
  
  return result,Lexer.list,false

end

上面代码具体意思是说,用while循环获取整个token(上偏文章说的{"KEYWORD","s",1}数据),而Lexer:next()用来获取下个token table(表)

现在看看Lexer:next()整个代码(由于是直接发全部代码,可能比较长。可以从后面向上看。)

function Lexer:next()

   local ch = string.char(string.byte(Lexer.src,Lexer.p))
   
   if ch == nil or ch == "" then return nil end
   
   local t,v,l,lines
   
   --换行解析
   if ch == "\x0a" then
     
     t = "LINE" v = ch l = Lexer.line
     
     Lexer.line = Lexer.line + 1
     
     --空格解析
     elseif ch == "\x20" then
       
     t = "SPACE" v = ch l = Lexer.line
     
     --标识符解析
     elseif "a" <= ch and ch <= "z" or "A" <= ch and ch <= "Z" then
     
     local str = Lexer:Identifier()
     
     t = "IDENTIFIER"
     
     --判断关键字
     local keyword = Lexer:Keyword(str)
     
     if keyword then t = keyword end
    
     v = str l = Lexer.line
     
     --解析数字
     elseif "0" <= ch and ch <= "9" then
     
     t = "NUMBER" v = Lexer:Number() l = Lexer.line
     
     --解析字符串
     elseif ch == "\"" or ch == "'" then
     
     local vv = Lexer.String()
     
     t = "STRING" v = vv l = Lexer.line
     
     lines = "\"" .. vv .. "\""
     
     elseif ch == '+' then
     
     Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析+=
     if chr == "=" then t = "ADD_ASSIGN" v = ch .. chr l = Lexer.line
       
       --解析++
       elseif chr == "+" then t = "INCREMENT" v = ch .. chr l = Lexer.line
       
       --解析+
       else Lexer.p = Lexer.p - 1 t = "PLUS" v = ch l = Lexer.line end
     
     elseif ch == "-" then
     
     Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析-=
     if chr == "=" then t = "SUBTRACT_ASSIGN" v = ch .. chr l = Lexer.line
       
       --解析--
       elseif chr == "-" then t = "DECREMENT" v = ch .. chr l = Lexer.line
       
       --解析-
       else Lexer.p = Lexer.p - 1 t = "MINUS" v = ch l = Lexer.line end
     
     elseif ch == "*" then
     
     Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析*指针
     if "a" <= chr and chr <= "z" or "A" <= chr and chr <= "Z" then t = "POINTER" v = Lexer:Identifier() l = Lexer.line
     
       --解析*=
       elseif chr == "=" then t = "MULTIPLY_ASSIGN" v = ch .. chr l = Lexer.line
       
       --解析*
       else Lexer.p = Lexer.p - 1 t = "MULTIPLY" v = ch l = Lexer.line end
     
     elseif ch == "/" then
     
     Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析/=
     if chr == "=" then t = "QUOTIENT_ASSIGN" v = ch .. chr l = Lexer.line
       
       --解析//
       elseif chr == "/" then
       
       
       
       local line,c_p,c_d,cc = Lexer.line,true,"",""

       while c_p do

       Lexer.p = Lexer.p + 1

       cc = string.char(string.byte(Lexer.src,Lexer.p))

       if cc == "\x0a" or cc == "" then Lexer.line = Lexer.line + 1 break end

       c_d = c_d .. cc

       end

       t = "COMMENT" v = c_d l = line
       
       
       
       --解析/* ... */
       elseif chr == "*" then
       
       
       
       local line,c_p,c_d,a,b = Lexer.line,true,"","",""

       while c_p do

       Lexer.p = Lexer.p + 1

       a = string.char(string.byte(Lexer.src,Lexer.p))

       b = string.char(string.byte(Lexer.src,Lexer.p+1))

       if a == "" then Lexer.p = Lexer.p + 1 break end

       if a == '*' and b == '/' then break end

       if a == "\x0a" then Lexer.line = Lexer.line + 1 end

       c_d = c_d .. a

       end

       Lexer.p = Lexer.p + 1
       
       t = "COMMENT" v = c_d l = line
       
       
       
       --解析/
       else Lexer.p = Lexer.p - 1 t = "SLASH" v = ch l = Lexer.line end
     
     elseif ch == "%" then
     
     Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析%=
     if chr == "=" then t = "REMAINDER_ASSIGN" v = ch .. chr l = Lexer.line
       
       --解析%
       else Lexer.p = Lexer.p - 1 t = "REMAINDER" v = ch l = Lexer.line end
     
     elseif ch == "&" then
     
      Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析&指针
     if "a" <= chr and chr <= "z" or "A" <= chr and chr <= "Z" then t = "QUOTE" v = Lexer:Identifier() l = Lexer.line
     
       --解析&^
       elseif chr == "^" then t = "AND_NOT" v = ch .. chr l = Lexer.line
       
       --解析&=
       elseif chr == "=" then t = "AND_ASSIGN" v = ch .. chr l = Lexer.line
       
       --解析&&
       elseif chr == "&" then t = "LOGICAL_AND" v = ch .. chr l = Lexer.line
       
       --解析&
       else Lexer.p = Lexer.p - 1 t = "AND" v = ch l = Lexer.line end
     
     elseif ch == "|" then
     
     Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析|=
     if chr == "=" then t = "OR_ASSIGN" v = ch .. chr l = Lexer.line
       
       --解析||
       elseif chr == "|" then t = "LOGICAL_OR" v = ch .. chr l = Lexer.line
       
       --解析|
       else Lexer.p = Lexer.p - 1 t = "OR" v = ch l = Lexer.line end
     
     elseif ch == "^" then t = "EXCLUSIVE_OR" v = ch l = Lexer.line
     
     elseif ch == "=" then
     
     Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析==
     if chr == "=" then
       
       Lexer.p = Lexer.p + 1
       
       local chrs = string.char(string.byte(Lexer.src,Lexer.p))
       
       --解析===
       if chrs == "=" then t = "STRICT_EQUAL" v = ch .. chr .. chrs l = Lexer.line
         
         --解析==
         else Lexer.p = Lexer.p - 1 t = "EQUAL" v = ch .. chr l = Lexer.line end
       
       --解析=
       else Lexer.p = Lexer.p - 1 t = "ASSIGN" v = ch l = Lexer.line end
     
     elseif ch == "<" then
       
       Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析<=
     if chr == "=" then t = "LESS_OR_EQUAL" v = ch .. chr l = Lexer.line
       
       --解析<<
       elseif chr == "<" then t = "SHIFT_LEFT" v = ch .. chr l = Lexer.line
       
       --解析<
       else Lexer.p = Lexer.p - 1 t = "LESS" v = ch l = Lexer.line end
     
     elseif ch == ">" then
     
     Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析>=
     if chr == "=" then t = "GREATER_OR_EQUAL" v = ch .. chr l = Lexer.line
       
       --解析>>
       elseif chr == ">" then t = "SHIFT_RIGHT" v = ch .. chr l = Lexer.line
       
       --解析>
       else Lexer.p = Lexer.p - 1 t = "GREATER" v = ch l = Lexer.line end
     
     elseif ch == "!" then
     
     Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析!=
     if chr == "=" then
       
       Lexer.p = Lexer.p + 1
       
       local chrs = string.char(string.byte(Lexer.src,Lexer.p))
       
       --解析!==
       if chrs == "=" then t = "STRICT_NOT_EQUAL" v = ch .. chr .. chrs l = Lexer.line
         
         --解析!=
         else Lexer.p = Lexer.p - 1 t = "NOT_EQUAL" v = ch .. chr l = Lexer.line end
       
       --解析!
       else Lexer.p = Lexer.p - 1 t = "NOT" v = ch l = Lexer.line end
     
     --解析~
     elseif ch == "~" then t = "BITWISE_NOT" v = ch l = Lexer.line
     
     --解析(
     elseif ch == "(" then t = "LEFT_PARENTHESIS" v = ch l = Lexer.line
     
     --解析[
     elseif ch == "[" then t = "LEFT_BRACKET" v = ch l = Lexer.line
     
     --解析{
     elseif ch == "{" then t = "LEFT_BRACE" v = ch l = Lexer.line
     
     --解析)
     elseif ch == ")" then t = "RIGHT_PARENTHESIS" v = ch l = Lexer.line
     
     --解析]
     elseif ch == "]" then t = "RIGHT_BRACKET" v = ch l = Lexer.line
     
     --解析}
     elseif ch == "}" then t = "RIGHT_BRACE" v = ch l = Lexer.line
     
     --解析,
     elseif ch == "," then t = "COMMA" v = ch l = Lexer.line
     
     elseif ch == "." then
     
     Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析..
     if chr == "." then t = "CONCAT" v = ch .. chr l = Lexer.line
       
       --解析.
       else Lexer.p = Lexer.p - 1 t = "PERIOD" v = ch l = Lexer.line end
     
     --解析;
     elseif ch == ";" then t = "SEMICOLON" v = ch l = Lexer.line
     
     --解析:
     elseif ch == ":" then t = "COLON" v = ch l = Lexer.line
     
     --解析?
     elseif ch == "?" then t = "QUESTION_MARK" v = ch l = Lexer.line
     
     else
     
     if Lexer.err == true and ch ~= "" then Lexer.errors = "词法分析错误:在第" .. Lexer.line .. "行,error数据[" .. ch .. "],具体代码--->" .. Lexer.list[Lexer.line] .. Lexer:Line() return nil end
     
     end
   
   Lexer.err = true
   
   Lexer.p = Lexer.p + 1
   
   --存储每行代码
     if lines then str = lines else str = v end
     
     if Lexer.list[l] == nil then Lexer.list[l] = "" end
     
     Lexer.list[l] = Lexer.list[l] .. str
   
   return {token=t,value=v,line=l}
   
end

附辅助函数:

--解析一行
function Lexer:Line()
  
  local result = ""
  
  while true do
    
    local chr = string.char(string.byte(Lexer.src,Lexer.p))
    
    if chr == "\x0a" or chr == "" then return result
      
      else result = result .. chr Lexer.p = Lexer.p + 1 end
    
    end
  
  end

--整体标识符解析
function Lexer:Identifier()

   local result = ""

   local code = true

   while code do

   local chr = string.char(string.byte(Lexer.src,Lexer.p))

   if chr == nil or chr == "" then code = false break end

   if ("a" <= chr and chr <= "z") or ("A" <= chr and chr <= "Z") or ("0" <= chr and chr <= "9") then

   result = result .. chr

   Lexer.p = Lexer.p + 1

   else

   code = false

   end

   end

   Lexer.p = Lexer.p - 1

   return result

end

--判断关键字
function Lexer:Keyword(str)
  
  local keyword = Lexer.keyword
  
  for key,value in pairs(keyword) do
    
    if value == str then
        
        return key
        
        end
  
  end

  return false
  
  end


--解析字符串
function Lexer.String()

  local p = string.char(string.byte(Lexer.src,Lexer.p))

  Lexer.p = Lexer.p + 1

  local result = ""

  local code = true

  while code do

  local chr = string.char(string.byte(Lexer.src,Lexer.p))

  if chr == "\x0a" then Lexer.line = Lexer.line + 1 end

  if chr == "" then break end

  if chr ~= p then

  result = result .. chr

  Lexer.p = Lexer.p + 1

  else

  code = false;

  end

end

return result

end

--整体数字解析
function Lexer:Number()

   local result = ""

   local code = true

   while code do

   local chr = string.char(string.byte(Lexer.src,Lexer.p))

   if chr == nil or chr == "" then code = false break end

   if "0" <= chr and chr <= "9" then

   result = result .. chr

   Lexer.p = Lexer.p + 1

   else

   code = false

   end

   end

   Lexer.p = Lexer.p - 1

   return result

end

lexer.lua文件全部代码:

Lexer = {p=1,src="",line=0,code=true,list={},tmp="",err=false,errors="",keyword={i_null="null",i_true="true",i_false="false",i_s="s",i_ss="ss",i_sss="sss",i_f="f",i_else="else",i_w="w",i_t="t",i_for="for",i_fn="fn",i_end="end",i_goto="goto",i_endcode="endcode",i_return="return"}}

function Lexer:new(str)

  self.src = str
  return self

end

function Lexer:run()

  local result,code = {},true

  while code do
    
    local token = Lexer:next()
    
    if Lexer.errors ~= "" then return Lexer.errors,Lexer.list,true end
   
    if token == nil then return result,Lexer.list,false end
    
    result[#result+1] = token
    
    end
  
  return result,Lexer.list,false

end

function Lexer:next()

   local ch = string.char(string.byte(Lexer.src,Lexer.p))
   
   if ch == nil or ch == "" then return nil end
   
   local t,v,l,lines
   
   --换行解析
   if ch == "\x0a" then
     
     t = "LINE" v = ch l = Lexer.line
     
     Lexer.line = Lexer.line + 1
     
     --空格解析
     elseif ch == "\x20" then
       
     t = "SPACE" v = ch l = Lexer.line
     
     --标识符解析
     elseif "a" <= ch and ch <= "z" or "A" <= ch and ch <= "Z" then
     
     local str = Lexer:Identifier()
     
     t = "IDENTIFIER"
     
     --判断关键字
     local keyword = Lexer:Keyword(str)
     
     if keyword then t = keyword end
    
     v = str l = Lexer.line
     
     --解析数字
     elseif "0" <= ch and ch <= "9" then
     
     t = "NUMBER" v = Lexer:Number() l = Lexer.line
     
     --解析字符串
     elseif ch == "\"" or ch == "'" then
     
     local vv = Lexer.String()
     
     t = "STRING" v = vv l = Lexer.line
     
     lines = "\"" .. vv .. "\""
     
     elseif ch == '+' then
     
     Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析+=
     if chr == "=" then t = "ADD_ASSIGN" v = ch .. chr l = Lexer.line
       
       --解析++
       elseif chr == "+" then t = "INCREMENT" v = ch .. chr l = Lexer.line
       
       --解析+
       else Lexer.p = Lexer.p - 1 t = "PLUS" v = ch l = Lexer.line end
     
     elseif ch == "-" then
     
     Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析-=
     if chr == "=" then t = "SUBTRACT_ASSIGN" v = ch .. chr l = Lexer.line
       
       --解析--
       elseif chr == "-" then t = "DECREMENT" v = ch .. chr l = Lexer.line
       
       --解析-
       else Lexer.p = Lexer.p - 1 t = "MINUS" v = ch l = Lexer.line end
     
     elseif ch == "*" then
     
     Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析*指针
     if "a" <= chr and chr <= "z" or "A" <= chr and chr <= "Z" then t = "POINTER" v = Lexer:Identifier() l = Lexer.line
     
       --解析*=
       elseif chr == "=" then t = "MULTIPLY_ASSIGN" v = ch .. chr l = Lexer.line
       
       --解析*
       else Lexer.p = Lexer.p - 1 t = "MULTIPLY" v = ch l = Lexer.line end
     
     elseif ch == "/" then
     
     Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析/=
     if chr == "=" then t = "QUOTIENT_ASSIGN" v = ch .. chr l = Lexer.line
       
       --解析//
       elseif chr == "/" then
       
       
       
       local line,c_p,c_d,cc = Lexer.line,true,"",""

       while c_p do

       Lexer.p = Lexer.p + 1

       cc = string.char(string.byte(Lexer.src,Lexer.p))

       if cc == "\x0a" or cc == "" then Lexer.line = Lexer.line + 1 break end

       c_d = c_d .. cc

       end

       t = "COMMENT" v = c_d l = line
       
       
       
       --解析/* ... */
       elseif chr == "*" then
       
       
       
       local line,c_p,c_d,a,b = Lexer.line,true,"","",""

       while c_p do

       Lexer.p = Lexer.p + 1

       a = string.char(string.byte(Lexer.src,Lexer.p))

       b = string.char(string.byte(Lexer.src,Lexer.p+1))

       if a == "" then Lexer.p = Lexer.p + 1 break end

       if a == '*' and b == '/' then break end

       if a == "\x0a" then Lexer.line = Lexer.line + 1 end

       c_d = c_d .. a

       end

       Lexer.p = Lexer.p + 1
       
       t = "COMMENT" v = c_d l = line
       
       
       
       --解析/
       else Lexer.p = Lexer.p - 1 t = "SLASH" v = ch l = Lexer.line end
     
     elseif ch == "%" then
     
     Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析%=
     if chr == "=" then t = "REMAINDER_ASSIGN" v = ch .. chr l = Lexer.line
       
       --解析%
       else Lexer.p = Lexer.p - 1 t = "REMAINDER" v = ch l = Lexer.line end
     
     elseif ch == "&" then
     
      Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析&指针
     if "a" <= chr and chr <= "z" or "A" <= chr and chr <= "Z" then t = "QUOTE" v = Lexer:Identifier() l = Lexer.line
     
       --解析&^
       elseif chr == "^" then t = "AND_NOT" v = ch .. chr l = Lexer.line
       
       --解析&=
       elseif chr == "=" then t = "AND_ASSIGN" v = ch .. chr l = Lexer.line
       
       --解析&&
       elseif chr == "&" then t = "LOGICAL_AND" v = ch .. chr l = Lexer.line
       
       --解析&
       else Lexer.p = Lexer.p - 1 t = "AND" v = ch l = Lexer.line end
     
     elseif ch == "|" then
     
     Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析|=
     if chr == "=" then t = "OR_ASSIGN" v = ch .. chr l = Lexer.line
       
       --解析||
       elseif chr == "|" then t = "LOGICAL_OR" v = ch .. chr l = Lexer.line
       
       --解析|
       else Lexer.p = Lexer.p - 1 t = "OR" v = ch l = Lexer.line end
     
     elseif ch == "^" then t = "EXCLUSIVE_OR" v = ch l = Lexer.line
     
     elseif ch == "=" then
     
     Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析==
     if chr == "=" then
       
       Lexer.p = Lexer.p + 1
       
       local chrs = string.char(string.byte(Lexer.src,Lexer.p))
       
       --解析===
       if chrs == "=" then t = "STRICT_EQUAL" v = ch .. chr .. chrs l = Lexer.line
         
         --解析==
         else Lexer.p = Lexer.p - 1 t = "EQUAL" v = ch .. chr l = Lexer.line end
       
       --解析=
       else Lexer.p = Lexer.p - 1 t = "ASSIGN" v = ch l = Lexer.line end
     
     elseif ch == "<" then
       
       Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析<=
     if chr == "=" then t = "LESS_OR_EQUAL" v = ch .. chr l = Lexer.line
       
       --解析<<
       elseif chr == "<" then t = "SHIFT_LEFT" v = ch .. chr l = Lexer.line
       
       --解析<
       else Lexer.p = Lexer.p - 1 t = "LESS" v = ch l = Lexer.line end
     
     elseif ch == ">" then
     
     Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析>=
     if chr == "=" then t = "GREATER_OR_EQUAL" v = ch .. chr l = Lexer.line
       
       --解析>>
       elseif chr == ">" then t = "SHIFT_RIGHT" v = ch .. chr l = Lexer.line
       
       --解析>
       else Lexer.p = Lexer.p - 1 t = "GREATER" v = ch l = Lexer.line end
     
     elseif ch == "!" then
     
     Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析!=
     if chr == "=" then
       
       Lexer.p = Lexer.p + 1
       
       local chrs = string.char(string.byte(Lexer.src,Lexer.p))
       
       --解析!==
       if chrs == "=" then t = "STRICT_NOT_EQUAL" v = ch .. chr .. chrs l = Lexer.line
         
         --解析!=
         else Lexer.p = Lexer.p - 1 t = "NOT_EQUAL" v = ch .. chr l = Lexer.line end
       
       --解析!
       else Lexer.p = Lexer.p - 1 t = "NOT" v = ch l = Lexer.line end
     
     --解析~
     elseif ch == "~" then t = "BITWISE_NOT" v = ch l = Lexer.line
     
     --解析(
     elseif ch == "(" then t = "LEFT_PARENTHESIS" v = ch l = Lexer.line
     
     --解析[
     elseif ch == "[" then t = "LEFT_BRACKET" v = ch l = Lexer.line
     
     --解析{
     elseif ch == "{" then t = "LEFT_BRACE" v = ch l = Lexer.line
     
     --解析)
     elseif ch == ")" then t = "RIGHT_PARENTHESIS" v = ch l = Lexer.line
     
     --解析]
     elseif ch == "]" then t = "RIGHT_BRACKET" v = ch l = Lexer.line
     
     --解析}
     elseif ch == "}" then t = "RIGHT_BRACE" v = ch l = Lexer.line
     
     --解析,
     elseif ch == "," then t = "COMMA" v = ch l = Lexer.line
     
     elseif ch == "." then
     
     Lexer.p = Lexer.p + 1
     
     local chr = string.char(string.byte(Lexer.src,Lexer.p))
     
     --解析..
     if chr == "." then t = "CONCAT" v = ch .. chr l = Lexer.line
       
       --解析.
       else Lexer.p = Lexer.p - 1 t = "PERIOD" v = ch l = Lexer.line end
     
     --解析;
     elseif ch == ";" then t = "SEMICOLON" v = ch l = Lexer.line
     
     --解析:
     elseif ch == ":" then t = "COLON" v = ch l = Lexer.line
     
     --解析?
     elseif ch == "?" then t = "QUESTION_MARK" v = ch l = Lexer.line
     
     else
     
     if Lexer.err == true and ch ~= "" then Lexer.errors = "词法分析错误:在第" .. Lexer.line .. "行,error数据[" .. ch .. "],具体代码--->" .. Lexer.list[Lexer.line] .. Lexer:Line() return nil end
     
     end
   
   Lexer.err = true
   
   Lexer.p = Lexer.p + 1
   
   --存储每行代码
     if lines then str = lines else str = v end
     
     if Lexer.list[l] == nil then Lexer.list[l] = "" end
     
     Lexer.list[l] = Lexer.list[l] .. str
   
   return {token=t,value=v,line=l}
   
end

--解析一行
function Lexer:Line()
  
  local result = ""
  
  while true do
    
    local chr = string.char(string.byte(Lexer.src,Lexer.p))
    
    if chr == "\x0a" or chr == "" then return result
      
      else result = result .. chr Lexer.p = Lexer.p + 1 end
    
    end
  
  end

--整体标识符解析
function Lexer:Identifier()

   local result = ""

   local code = true

   while code do

   local chr = string.char(string.byte(Lexer.src,Lexer.p))

   if chr == nil or chr == "" then code = false break end

   if ("a" <= chr and chr <= "z") or ("A" <= chr and chr <= "Z") or ("0" <= chr and chr <= "9") then

   result = result .. chr

   Lexer.p = Lexer.p + 1

   else

   code = false

   end

   end

   Lexer.p = Lexer.p - 1

   return result

end

--判断关键字
function Lexer:Keyword(str)
  
  local keyword = Lexer.keyword
  
  for key,value in pairs(keyword) do
    
    if value == str then
        
        return key
        
        end
  
  end

  return false
  
  end


--解析字符串
function Lexer.String()

  local p = string.char(string.byte(Lexer.src,Lexer.p))

  Lexer.p = Lexer.p + 1

  local result = ""

  local code = true

  while code do

  local chr = string.char(string.byte(Lexer.src,Lexer.p))

  if chr == "\x0a" then Lexer.line = Lexer.line + 1 end

  if chr == "" then break end

  if chr ~= p then

  result = result .. chr

  Lexer.p = Lexer.p + 1

  else

  code = false;

  end

end

return result

end

--整体数字解析
function Lexer:Number()

   local result = ""

   local code = true

   while code do

   local chr = string.char(string.byte(Lexer.src,Lexer.p))

   if chr == nil or chr == "" then code = false break end

   if "0" <= chr and chr <= "9" then

   result = result .. chr

   Lexer.p = Lexer.p + 1

   else

   code = false

   end

   end

   Lexer.p = Lexer.p - 1

   return result

end

return Lexer

(文章暂时停更,作者有空再继续讲解上面代码具体有什么用)

上一篇下一篇

猜你喜欢

热点阅读