W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
其他人需要以控制方式運(yùn)行你的一部分代碼。相對(duì)地,你選擇的語言不能以一種簡潔的方式表達(dá)問題域。
使用解釋器模式來創(chuàng)建一個(gè)你翻譯為特定代碼的領(lǐng)域特異性語言(domain-specific language)。
我們來做個(gè)假設(shè),例如用戶希望在你的應(yīng)用程序中執(zhí)行數(shù)學(xué)運(yùn)算。你可以讓他們正向運(yùn)行代碼來演算指令(eval)但這會(huì)讓他們運(yùn)行任意代碼。相反,你可以提供一個(gè)小型的“堆棧計(jì)算器(stack calculator)”語言,用來做單獨(dú)分析,以便只運(yùn)行數(shù)學(xué)運(yùn)算,同時(shí)報(bào)告更有用的錯(cuò)誤信息。
class StackCalculator
parseString: (string) ->
@stack = [ ]
for token in string.split /\s+/
@parseToken token
if @stack.length > 1
throw "Not enough operators: numbers left over"
else
@stack[0]
parseToken: (token, lastNumber) ->
if isNaN parseFloat(token) # Assume that anything other than a number is an operator
@parseOperator token
else
@stack.push parseFloat(token)
parseOperator: (operator) ->
if @stack.length < 2
throw "Can't operate on a stack without at least 2 items"
right = @stack.pop()
left = @stack.pop()
result = switch operator
when "+" then left + right
when "-" then left - right
when "*" then left * right
when "/"
if right is 0
throw "Can't divide by 0"
else
left / right
else
throw "Unrecognized operator: #{operator}"
@stack.push result
calc = new StackCalculator
calc.parseString "5 5 +" # => { result: 10 }
calc.parseString "4.0 5.5 +" # => { result: 9.5 }
calc.parseString "5 5 + 5 5 + *" # => { result: 100 }
try
calc.parseString "5 0 /"
catch error
error # => "Can't divide by 0"
try
calc.parseString "5 -"
catch error
error # => "Can't operate on a stack without at least 2 items"
try
calc.parseString "5 5 5 -"
catch error
error # => "Not enough operators: numbers left over"
try
calc.parseString "5 5 5 foo"
catch error
error # => "Unrecognized operator: foo"
作為一種替代編寫我們自己的解釋器的選擇,你可以將現(xiàn)有的CoffeeScript解釋器與更自然的(更容易理解的)表達(dá)自己的算法的正常方式相結(jié)合。
class Sandwich
constructor: (@customer, @bread='white', @toppings=[], @toasted=false)->
white = (sw) ->
sw.bread = 'white'
sw
wheat = (sw) ->
sw.bread = 'wheat'
sw
turkey = (sw) ->
sw.toppings.push 'turkey'
sw
ham = (sw) ->
sw.toppings.push 'ham'
sw
swiss = (sw) ->
sw.toppings.push 'swiss'
sw
mayo = (sw) ->
sw.toppings.push 'mayo'
sw
toasted = (sw) ->
sw.toasted = true
sw
sandwich = (customer) ->
new Sandwich customer
to = (customer) ->
customer
send = (sw) ->
toastedState = sw.toasted and 'a toasted' or 'an untoasted'
toppingState = ''
if sw.toppings.length > 0
if sw.toppings.length > 1
toppingState = " with #{sw.toppings[0..sw.toppings.length-2].join ', '} and #{sw.toppings[sw.toppings.length-1]}"
else
toppingState = " with #{sw.toppings[0]}"
"#{sw.customer} requested #{toastedState}, #{sw.bread} bread sandwich#{toppingState}"
send sandwich to 'Charlie' # => "Charlie requested an untoasted, white bread sandwich"
send turkey sandwich to 'Judy' # => "Judy requested an untoasted, white bread sandwich with turkey"
send toasted ham turkey sandwich to 'Rachel' # => "Rachel requested a toasted, white bread sandwich with turkey and ham"
send toasted turkey ham swiss sandwich to 'Matt' # => "Matt requested a toasted, white bread sandwich with swiss, ham and turkey"
這個(gè)實(shí)例可以允許功能層實(shí)現(xiàn)返回修改后的對(duì)象,從而外函數(shù)可以依次修改它。示例通過借用動(dòng)詞和介詞的用法,把自然語法提供給結(jié)構(gòu),當(dāng)被正確使用時(shí),會(huì)像自然語句一樣結(jié)束。這樣,利用CoffeeScript語言技能和你現(xiàn)有的語言技能可以幫助你關(guān)于捕捉代碼的問題。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: