寫一個簡單的詞法、語法分析器,來最終分析出整數四則運算表達式的結果。函數
爲了簡化詞語法分析咱們只容許出現0~9,+,-,*,/,空格,\r, \n這幾個字符spa
詞法分析:code
方法1. 狀態機blog
咱們先準備3個判斷方法:token
// 是不是數字 function isNum(letter) { return letter === '0' || letter === '1' || letter === '2' || letter === '3' || letter === '4' || letter === '5' || letter === '0' || letter === '6' || letter === '7' || letter === '8' || letter === '9' } // 是不是運算符 function isOperater(letter) { return letter === '+' || letter === '-' || letter === '*' || letter === '/' } // 是不是間隔符 function isEmptyLetter(letter) { return letter === ' ' || letter === '\r' || letter === '\n' }
定義生成token的函數:字符串
const tokenList = [] function generateToken(type, token) { console.log("生成token: " + token); tokenList.push({type, token}); }
定義狀態轉移函數:it
let token = [] function startToken(letter) { if (isNum(letter)) { // 若是是數字,則進入inNumber狀態 token.push(letter) return inNumber } else if (isOperater(letter)) { // 若是是+-*/, 就立刻生成一個token generateToken('operator', letter) return startToken } else if (isEmptyLetter(letter)) { // 若是是空白字符,則跳過 return startToken } else { // 若是是其餘字符則報錯 throw new Error('出現意外字符') } } function inNumber(letter) { if (isNum(letter)) { token.push(letter) return inNumber } else { // 直到遇到非數字, 把前面push的數字生成一個數字token, 而後清空token generateToken('number', token.join('')) token = [] // 最後讓新的letter立刻執行一次startToken return startToken(letter) } }
開始詞法分析:io
// 要詞法分析的字符串 const str = '123* 656 - 644 + 3131' // 分割成一個個字母 let strArr = str.split(''); // 定義狀態機 let state = startToken // 遍歷字母,不停地更新狀態機 for(let letter of strArr) { state = state(letter) }
得出結果:console
方法2. 正則分析function
// 要詞法分析的字符串 let str = '123* 656 - 644 + 3131' // 過濾間隔符 str = str.replace(/[\r\n ]/g, '') const operatorRegExp = /[+\-*/]/g // 獲取運算的數字token let numList = str.split(operatorRegExp) // 獲取運算符token let operatorList = str.match(operatorRegExp) const tokenList = [] numList.forEach((item, idx) => { tokenList.push({type: 'number', token: item}) if (idx !== numList.length - 1) { tokenList.push({type: 'operator', token: operatorList[idx]}) } }) console.log(tokenList)
得出結果:
到這裏詞法分析就已經完成了。