(1)一直以來,我都想寫一門語言,但無從下手。
(2)我找到了很多編譯原理的教程,但始終覺得內容晦澀,理解不了,所以先嘗試寫乙個簡單的,比如:計算器。
(3)網上有很多關於計算器的實現,但大多需要有編譯原理的基礎,對於我這種小白實在難以理解。
(4)我決定採用暴力模擬的方式,需要用正規表示式,但我不想自己實現,所以用js。
計算器接受一串字元,處理後返回結果。
我們來看一下要做什麼:
首先需要知道有哪些「元素」,比如「12+34×56"的元素有整數12,加號,整數34,乘號,整數56,這個過程稱為詞法分析。
然後根據符號的優先順序進行組合,其過程相當於加括號,12+(34*56),這個過程稱為語法分析。
借用正規表示式,可以簡單暴力的實現詞法分析。
正規表示式的概念,和編譯原理一樣,都要費好大功夫來理解,當初也是各種查資料。
盡量簡單的講一講吧。
定義:正規表示式是一種生成器,可以生成大量相同模式的字串。
字串的概念大家都懂,來看一下正規表示式是怎麼生成字串的。
例子:正規表示式 ab* 可以生成'a' , 'ab' , 'abb' , 'abbb' ...
正規表示式有三種規則(並,或,閉包),其他規則都是由這三個規則組合而成。
並,直接連在一起,表示相連,例如:abc 生成』abc'
或,以符號|分隔,表示或,例如:a|b生成'a','b'
閉包,加符號*,表示重複任意次,例如:a* 生成 '','a', 'aa', 'aaa'...
一些常用的規則:
,例如:[abcd]等價於a|b|c|d
+,例如:a+等價於aa*
?,例如:a?等價於 a|空
\d,等價於[0123456789],還可以用[0-9]
\w,等價於[a-za-z0-9]
\w,非\w
\b,表示\w與\w的交界處
計算器用到的正規表示式:
number:\b\d+\b
注意:規則中有的字元要轉義,如:+
不斷用正則來匹配輸入的字串,就可以。
使用js來實現:
1 function get_words(buf)對於'12+34 * (78-56)',會得到:26 }
27 }
28 return words;
29 }
number,12至此,詞法分析完成。+,nan
number,34
*,nan
(,nan
number,78
-,nan
number,56
),nan
我們採用類似於正則的方式來描述語法分析的過程,可稱其為文法。
分析一波。
括號優先順序最高,所以遇見括號就要計算,文法為:
=> ( '(' ')' ) | 'number'
引號的稱終結符,尖括號的稱非終結符。
非終結符表示可以繼續推導,終結符表示推導終點。
其中表示整個算式
乘除優先順序比加法高,所以遇見乘除就要計算,文法為:
然後是加減:
這些都可以用正則來理解。
其中每個非終結符都做成乙個函式,翻譯過來就成。
1 function parse(words)寫完了,哈哈。11 function match(sym)
15 console.log('\nerror\n');
16 }
17 function expr() else
27 }
28 return value;
29 }
30 function term() else
40 }
41 return value;
42 }
43 function factor() else if (type() == 'number')
51 return value;
52 }
53
54 return expr();
55 }
用node.js可以簡單的跑起來:
摺起來吧,效果在前面。
實現乙個計算器
一直以來,我都想寫一門語言,但無從下手。我找到了很多編譯原理的教程,但始終覺得內容晦澀,理解不了,所以先嘗試寫乙個簡單的,比如 計算器。網上有很多關於計算器的實現,但大多需要有編譯原理的基礎,對於我這種小白實在難以理解。我決定採用暴力模擬的方式,需要用正規表示式,但我不想自己實現,所以用js。計算器...
Pythons實現乙個計算器
coding utf 8 from tkinter import def calculate result eval equ.get equ.set equ.get n str result def show buttonstring content equ.get if content 0 con...
堆疊實現乙個整型計算器
計算器特性 支援整型運算 能夠處理運算子和運算元間的空格,支援括號 實現思路 利用乙個運算元堆疊dgt和乙個運算子堆疊ops實現 1 從左至右掃瞄運算表示式輸入,若為運算元則直接壓入dgt堆疊 2 若為運算子則判斷ops中是否已經存在運算子,不存在則直接壓入,存在則與棧頂運算子比較優先順序,優先順序...