lang 使用BNF正規化設計乙個文法

2021-09-29 11:52:32 字數 4358 閱讀 9272

上個月買了本《兩周自製指令碼語言》,雖然我是不信這種鬼話的。買了後也不信,兩周的時間是假的,但是知識還是有的。這一篇不會實現任何匹配,而是如何用數學點的方法定義自己要求的語言。

bnf正規化是一種描述程式語言的數學方法,可讀性接近自然語言。

這裡指變數的命名,即識別符號!

變數開頭不能是數字,可以是字母和下劃線。變數其他字元可以是數字、字母、下劃線。

(letter、digit、underline這類簡單的單詞表達的意思就不用解釋了!)

var          ::= prechar[otherchar]          

prechar ::= letter|underline

otherchar ::=

(letter|digit|underline)

[otherchar]

表示式可以指資料,變數存放的資料!

二元表示式和一元表示式,判斷式,四則表示式。

無效值nil和用兩個點連線字串都是lua語法,在進行設計的時候盡量考慮的簡單點,所以使用一些lua、python、c等語言的語法。

exp           ::= nil|

false

|true

|unop exp|exp binop exp|number|string|var

unop ::=

"+"|

"-"|

"~"|not

binop ::=

"+"|

"-"|

"*"|

"/"|

"//"

|"%"

|"^"

|"&"

|and|

"|"|or|

">"

|"<"

|"=="

|"<="

|">="

|".."

number ::= digit

["." digit

]string ::=

""" everyletter "

""

每個語句塊用花括號包起來。每句話可以以分號或者換行結束,}左邊的第一條語句可以不用分號和換行結束。

語句塊內可以巢狀語句塊。

賦值語句左邊可以是乙個變數,或者用逗號分隔的幾個變數。

當型迴圈用while關鍵字,滿足條件就進入迴圈。

直到型迴圈用until關鍵字,滿足條件就跳出迴圈。

區分區域性變數和全域性變數,如果是類或者函式內的,就是預設區域性變數。

凡是可以用賦值式的地方,等於號都能用is關鍵字代替。

block          ::="[

stat

]"}"|""

varlist ::= var

explist ::= exp

stat ::=

[ local ] varlist (

"="| is ) explist |

if exp block

[else block ]

|for var (

"=" is ) exp "," exp [

"," exp ] block |

while exp block |

do block until exp |

break

|continue

endstat ::=

";"|newline

三個連續的點表示任意數量、任意型別的引數。

引數內可傳遞變數、函式名、表示式。

因為沒有設計執行這麼自定義語言可以巢狀定義函式,所以函式體不涵蓋在block裡了。

返回引數可以為零,可以是一串引數。

funcname       ::= var

args ::=

( var | funcname | exp )

["," args ]

arglist ::= args [

",""..."]|

"..."

paramlist ::=

"("[ arglist ]

")"functiondef ::= def funcname paramlist block

stat ::=

return

[explist]

| functioncall

functioncall ::= funcname "("

[ args ]

")"

這裡點操作符只能用在例項物件或者包(package/module)的相關使用上。現在暫時就不管包了。

語句stat增加了建立例項物件這一句!直接用類名賦值就是建立了,簡單易懂。

增加this關鍵字,指向本身。

classname      ::= var

classdef ::= class classname [ extends classname ] classbody

classbody ::=

""}"

exp ::= classname

var ::= var

this ::= classname

陣列內部可以巢狀陣列!元素間用逗號分開。元素可以是表示式不能是賦值式子。

增加了in關鍵字。

陣列的使用可以遞迴?就是不止一維陣列,可以有許多維度。

括號後面可以跟方括號,但是方括號後面不能跟括號,因為這裡沒有設計陣列中可以存放變數——現在陣列中只能放置常量。

arrayname      ::= var

elements ::= number | string

arraydef ::=

"[""]"

|"[" arraydef "]"

exp ::= var in arrayname | arraydef

var ::= var

在lua裡只有表這個資料結構,但是也能通過setmetatable方法實現物件導向。

因為陣列和類的功能有重疊,都能存放資料,所以可以把二者合二為一。讓陣列可以存放函式,並且可以擁有繼承和多型!!

下面的陣列允許多繼承,存放變數、賦值式、函式。

訪問陣列元素可通過索引[2]點操作符.a加引號的元素名"a",函式.fun()必須用點操作符來呼叫!

elements       ::= var | 

functiondef |

varlist (

"="| is ) explist

arraynamelist ::= arrayname

arraydef ::=

[ extends arraynamelist with ]

("["

"]"|

"[" arraydef "]"

) var ::= var

this ::= arrayname

沒有包就不能靈魂,雞蛋都放在乙個籃子裡是不對的!

可以通過乙個變數來接收這個包,用這個變數來訪問包內的元素,當然也可以直接訪問。引用時可以引用整個包,或者包內的某個元素——為了使其他包內未引用的元素不被訪問到,需要遮蔽。

%import        ::=

import

""" dir/packname [ "

." var ] "

""exp ::= %import

var ::=

[ packname "."

] var

functioncall ::=

[ packname "."

] funcname "("

[ args ]

")"

實現不實現暫時不管了,就做個夢吧(笑)

設計乙個類

1 設計乙個不能被繼承的類 1 將建構函式設為私有 此時子類不能訪問基類的建構函式,因此建立子類時就會報錯 無法訪問private成員 class base uninherit base uninherit const base uninherit rhs base uninherit operat...

資料庫設計正規化 如何設計乙個資料庫結構

正規化 英文名稱是 normal form,它是英國人 e.f.codd 關聯式資料庫的老祖宗 在上個世紀70年代提出關聯式資料庫模型後總結出來的,正規化是關聯式資料庫理論的基礎,也是我們在設計資料庫結構過程中所要遵循的規則和指導方法。目前有跡可尋的共有8種正規化,依次是 1nf,2nf,3nf,b...

設計乙個使用外掛程式的c 程式

首先要公布介面,讓外掛程式通過這個介面實現功能,介面設計成類庫對外公布命名為hostapi.dll,類庫見 using system namespace hostapi 我們嘗試著設計乙個dll,取名dosomea,如下 using hostapi using system namespace do...