|
目前只支持整数的加,减,乘,除,取余,当然还有括号
本来想加上自定义变量的,不过期末太忙估计是没时间了
加了简单的错误提示,但仅仅是提示,不会中止运算.
[jass]
globals
constant integer MSG_ERROR = 0
constant integer MSG_OUTPUT = 1
constant integer TYPE_SYSTEM = 0
constant integer TYPE_INTEGER = 1
constant integer TYPE_OPERATOR = 2
constant integer SYSTEM_BEGIN = 0
constant integer SYSTEM_END = 1
integer array udg_stackOptr
integer udg_stackOptr_top = -1
integer array udg_stackOpnd
integer udg_stackOpnd_top = -1
integer array udg_line_type
integer array udg_line_index
integer udg_line_top = 8191
integer udg_line_bottom = 0
integer udg_TempA
integer udg_TempB
integer udg_parse_stateA = 0
integer udg_parse_stateB = 0
endglobals
function Console takes integer msg_type, string msg returns nothing
if msg_type == MSG_ERROR then
call BJDebugMsg("|cffff0303错误: "+msg+"|r")
elseif msg_type == MSG_OUTPUT then
call BJDebugMsg("|cff0042ff"+msg+"|r")
endif
endfunction
function stackOptrClear takes nothing returns nothing
set udg_stackOptr_top = -1
endfunction
function stackOptrPush takes integer value returns nothing
if udg_stackOptr_top == 8191 then
return
endif
set udg_stackOptr_top = udg_stackOptr_top + 1
set udg_stackOptr[udg_stackOptr_top] = value
endfunction
function stackOptrPop takes nothing returns integer
if udg_stackOptr_top == -1 then
return 0
endif
set udg_stackOptr_top = udg_stackOptr_top - 1
return udg_stackOptr[udg_stackOptr_top+1]
endfunction
function stackOptrGetTop takes nothing returns integer
return udg_stackOptr[udg_stackOptr_top]
endfunction
function stackOpndClear takes nothing returns nothing
set udg_stackOpnd_top = -1
endfunction
function stackOpndPush takes integer value returns nothing
if udg_stackOpnd_top == 8191 then
return
endif
set udg_stackOpnd_top = udg_stackOpnd_top + 1
set udg_stackOpnd[udg_stackOpnd_top] = value
endfunction
function stackOpndPop takes nothing returns integer
if udg_stackOpnd_top == -1 then
return 0
endif
set udg_stackOpnd_top = udg_stackOpnd_top - 1
return udg_stackOpnd[udg_stackOpnd_top+1]
endfunction
function isLineEmpty takes nothing returns boolean
return udg_line_bottom - udg_line_top == 1 or udg_line_top - udg_line_bottom ==8191
endfunction
function linePush takes integer a, integer b returns nothing
if udg_line_top == 8191 then
set udg_line_top = 0
else
set udg_line_top = udg_line_top + 1
endif
set udg_line_type[udg_line_top] = a
set udg_line_index[udg_line_top] = b
endfunction
function linePop takes nothing returns nothing
set udg_TempA = udg_line_type[udg_line_bottom]
set udg_TempB = udg_line_index[udg_line_bottom]
if udg_line_bottom == 8191 then
set udg_line_bottom = 0
else
set udg_line_bottom = udg_line_bottom + 1
endif
endfunction
function isSpace takes string s returns boolean
return SubString(s, 0, 1)==" "
endfunction
function isDigit takes string s returns boolean
return S2I(s) > 0 or SubString(s, 0, 1)=="0"
endfunction
function parseInteger takes string s, integer index returns integer
local integer i = index
local integer len = StringLength(s)
loop
exitwhen i >= len
if not isDigit(SubString(s, i, i+1)) then
return i
endif
set i = i + 1
endloop
return len
endfunction
function checkStateA takes integer a,integer i returns nothing
if udg_parse_stateA != a then
call Console(MSG_ERROR, "语法错误("+I2S(i)+")!")
endif
endfunction
function parseMain takes string s returns nothing
local integer i = 0
local integer j
local integer len = StringLength(s)
local string c
call linePush(TYPE_SYSTEM, SYSTEM_BEGIN)
set udg_parse_stateA = 0
set udg_parse_stateB = 0
loop
exitwhen i >= len
set c = SubString(s, i, i+1)
if isSpace(c) then
elseif isDigit(c) then
call checkStateA(0, i)
set udg_parse_stateA = 1
set j = parseInteger(s, i)
call linePush(TYPE_INTEGER, S2I(SubString(s, i, j)))
set i = j - 1
elseif c=="+" then
call checkStateA(1, i)
set udg_parse_stateA = 0
call linePush(TYPE_OPERATOR, '+')
elseif c=="-" then
call checkStateA(1, i)
set udg_parse_stateA = 0
call linePush(TYPE_OPERATOR, '-')
elseif c=="*" then
call checkStateA(1, i)
set udg_parse_stateA = 0
call linePush(TYPE_OPERATOR, '*')
elseif c=="/" then
call checkStateA(1, i)
set udg_parse_stateA = 0
call linePush(TYPE_OPERATOR, '/')
elseif c=="%" then
call checkStateA(1, i)
set udg_parse_stateA = 0
call linePush(TYPE_OPERATOR, '%')
elseif c=="(" then
call checkStateA(0, i)
set udg_parse_stateB = udg_parse_stateB + 1
call linePush(TYPE_OPERATOR, '(')
elseif c==")" then
call checkStateA(1, i)
set udg_parse_stateB = udg_parse_stateB - 1
call linePush(TYPE_OPERATOR, ')')
else
call Console(MSG_ERROR, "不合法的字符("+c+")")
endif
set i = i + 1
endloop
if udg_parse_stateB != 0 then
call Console(MSG_ERROR, "括号不匹配!")
endif
call linePush(TYPE_SYSTEM, SYSTEM_END)
endfunction
function Precede takes integer a, integer b returns boolean
local integer alv = 0
local integer blv = 0
if a=='#' then
return true
elseif a=='(' then
return true
elseif b=='(' then
return true
elseif b==')' then
return false
endif
if a=='+' or a=='-' then
set alv = 1
elseif a=='*' or a=='/' or a=='%' then
set alv = 2
endif
if b=='+' or b=='-' then
set blv = 1
elseif b=='*' or b=='/' or b=='%' then
set blv = 2
endif
return alv < blv
endfunction
function Operate takes integer a, integer b, integer op returns integer
if op=='+' then
return a+b
elseif op=='-' then
return a-b
elseif op=='*' then
return a*b
elseif op=='/' then
if b == 0 then
call Console(MSG_ERROR, "除数为零!")
endif
return a/b
elseif op=='%' then
if b == 0 then
call Console(MSG_ERROR, "除数为零!")
endif
return a-a/b*b
endif
return 0
endfunction
function runMain takes nothing returns nothing
local integer count = 0
local integer a
local integer b
loop
exitwhen count == 10 or isLineEmpty()
set count = count + 1
call linePop()
if udg_TempA == TYPE_SYSTEM then
if udg_TempB == SYSTEM_BEGIN then
call stackOptrClear()
call stackOpndClear()
call stackOptrPush('#')
elseif udg_TempB == SYSTEM_END then
loop
exitwhen stackOptrGetTop()=='#'
set a = stackOpndPop()
set b = stackOpndPop()
call stackOpndPush(Operate(b, a, stackOptrPop()))
endloop
call Console(MSG_OUTPUT, I2S(stackOpndPop()))
call stackOptrClear()
call stackOpndClear()
endif
elseif udg_TempA == TYPE_INTEGER then
call stackOpndPush(udg_TempB)
elseif udg_TempA == TYPE_OPERATOR then
loop
if Precede(stackOptrGetTop(), udg_TempB) then
if stackOptrGetTop()=='(' and udg_TempB==')' then
call stackOptrPop()
else
call stackOptrPush(udg_TempB)
endif
exitwhen true
else
set a = stackOpndPop()
set b = stackOpndPop()
call stackOpndPush(Operate(b, a, stackOptrPop()))
endif
endloop
endif
endloop
endfunction
function Trig_test_Action takes nothing returns nothing
call parseMain(GetEventPlayerChatString())
endfunction
function InitTrig_test takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterPlayerChatEvent(t, Player(0), "", false)
call TriggerAddAction(t, function Trig_test_Action)
call TimerStart(CreateTimer(), 0.01, TRUE, function runMain)
set t = null
endfunction
[/jass]
在WE里弄全局变量太麻烦,所以我是用mpq工具导入j文件的,要看代码就用mpq导出j文件吧,we里看不到的......
counter.w3x
(24 KB, 下载次数: 22)
|
评分
-
查看全部评分
|