{{word.word}}
摘要:架構(gòu)分析進(jìn)行文件數(shù)據(jù)處理進(jìn)行視圖的呈現(xiàn)作為客戶端語法解析效果展示讀取形式按照代碼行進(jìn)行讀取每次讀取到一行就進(jìn)行遍歷分析關(guān)鍵字與特殊符號(hào)建立映射關(guān)鍵字特殊字符遍歷分析過程代碼注釋匹配當(dāng)讀到一行中包含的兩個(gè)字符時(shí)候這時(shí)把代碼注釋的標(biāo)志
架構(gòu)分析
Node進(jìn)行文件數(shù)據(jù)處理
Vue.js進(jìn)行視圖的呈現(xiàn)
Electron作為客戶端
C++語法解析 效果展示 讀取形式按照代碼行進(jìn)行讀取, 每次讀取到一行就進(jìn)行遍歷分析
關(guān)鍵字與特殊符號(hào)建立映射/** * 關(guān)鍵字 */ let keyWords = [ "asm", "auto", "bool", "break", "case", "catch", "char", "class", "const", "continue", "cin", "cout", "default", "delete", "do", "double", "define", "else", "enum", "except", "explicit", "extern", "endl", "false", "finally", "float", "for", "friend", "goto", "if", "inline", "int", "include", "long", "mutable", "main", "namespace", "new", "operator", "private", "protectde", "public", "printf", "register", "return", "short", "signed", "szieof", "static", "struct", "string", "switch", "std", "scanf", "template", "this", "throw", "true", "try", "typedef", "typename", "union", "unsigned", "using", "virtual", "void", "while" ] /** * 特殊字符 */ let specialWords = [ ",", ";", "(", ")", "{", "}", "#", "^", "?", ":", ".", "[", "]", "+", "-", "*", "/", "%", "=", ">", "<", "!", "~", "|", "&", "&&", "||", "==", ">=", "<=", "!=", "++", "--", "::", "<<", ">>", "+=", "-=", "*=", "/=", "%=", "&=", "^=", "->" ] keyWords.forEach(word => { wordsMap.set(word, "keyWord") }) specialWords.forEach(word => { wordsMap.set(word, "specialWord") })遍歷分析過程
代碼注釋匹配
當(dāng)讀到一行中包含/*的兩個(gè)字符時(shí)候, 這時(shí)把代碼注釋的標(biāo)志設(shè)置為true, 然后一直讀取,知道遇到*/的時(shí)候就把標(biāo)志重新置為false
判斷是否可以構(gòu)成單詞,成立的條件是不以數(shù)字開頭,并且只包含數(shù)字, 下劃線, 以及字母, 可以通過正則來/[a-z]|[A-z]|_/匹配
判斷是否為字符串或者字符, 成立條件是以","開頭
判斷是否為數(shù)字
判斷是否為特殊字符, 這時(shí)就通過建立的映射進(jìn)行關(guān)鍵字查找
判斷空格
代碼解釋
判斷工具函數(shù)
//判斷是否是字母與下劃線 function judgeWord(word) { let wordPatten = /[a-z]|[A-z]|\_/ return wordPatten.test(word) } //判斷是否為數(shù)字 function judgeNumber(number) { let numberPatten = /[0-9]/ return numberPatten.test(number) } //判斷是否為特殊字符 function judgeSpecialWord(letter) { return wordsMap.get(letter) === "specialWord" ? true : false } //判斷是否為關(guān)鍵詞 function judgeKeyWord(letter) { return wordsMap.get(letter) === "keyWord" ? true : false }
行分析函數(shù)
exports.analysisLine = (line, annotation) => { let oneLine = [] let word = "" let i = 0 let includeFile = false while (i < line.length) { //注釋代碼的優(yōu)先級(jí)最高,需要先進(jìn)行判斷 if (line[i] === "/" && line[i + 1] === "*") { word += line[i] i++ annotation = true; } if (!annotation) { //表示不是注釋內(nèi)容 if (judgeWord(line[i])) { //表示是屬于字母與下劃線 word += line[i] while (i + 1 < line.length && (judgeNumber(line[i + 1]) || judgeWord(line[i + 1]))) { i++ word += line[i] } if (judgeKeyWord(word)) { //判斷單詞是否屬于關(guān)鍵詞 oneLine.push({ word: word, type: "keyWord" }) } else { //不為關(guān)鍵詞, 則為標(biāo)識(shí)符 oneLine.push({ word: word, type: "identifier" }) } //由于include是屬于頭文件的引入, 需要對(duì)頭文件進(jìn)行特殊處理 if (word === "include") { includeFile = true } word = "" i++ } else if (line[i] === """) { //字符串判斷 while (i + 1 < line.length && line[i + 1] !== """) { word += line[i] i++ } word += (line[i] || "" )+ (line[i + 1] || "") oneLine.push({ word: word, type: "string" }) word = "" i += 2 } else if (line[i] === """) { //字符判斷 while (i + 1 < line.length && line[i + 1] !== """) { word += line[i] i++ } word += (line[i] || "" )+ (line[i + 1] || "") oneLine.push({ word: word, type: "char" }) word = "" i += 2 } else if (judgeNumber(line[i])) { //數(shù)字判斷 word += line[i] while (i + 1 < line.length && (judgeNumber(line[i + 1]) || line[i + 1] === ".")) { i++ word += line[i] } oneLine.push({ word: word, type: "number" }) word = "" i++ } else if (judgeSpecialWord(line[i])) { //特殊字符判斷 if (line[i] === "<" && includeFile) { //處理頭文件的引入 oneLine.push({ word: line[i], type: "specialWord" }) i++ word += line[i] while (i + 1 < line.length && line[i + 1] !== ">") { i++ word += line[i] } oneLine.push({ word: word, type: "libraryFile" }) word = "" i++ } else { //處理//的注釋代碼 if (line[i] === "/" && line[i + 1] === "/") { i++ while (i + 1 < line.length) { i++ word += line[i] } oneLine.push({ word: word, type: "Annotations" }) word = "" i += 3 } else { word += line[i] while (i + 1 < line.length && (judgeSpecialWord(word + line[i + 1]))) { i++ word += line[i] } oneLine.push({ word: word, type: "specialWord" }) word = "" i++ } } } else if (line[i] === " ") { oneLine.push({ word: line[i], type: "space" }) i++ } } else { //表示注釋內(nèi)容 while (i + 1 < line.length && (line[i + 1] !== "*" && line[i + 2] !== "/")) { word += line[i] i++ } word += line[i] + (line[i + 1] || "") + (line[i + 2] || "") oneLine.push({ word: word, type: "Annotations" }) annotation = false; word = "" i += 3 } } return oneLine }界面實(shí)現(xiàn)過程
Electron, Vue搭建
具體的搭建過程省略, 可查看源碼或自行查找資料
動(dòng)態(tài)編輯顯示
數(shù)據(jù)綁定, 使用v-model結(jié)合watch進(jìn)行數(shù)據(jù)監(jiān)控, 當(dāng)數(shù)據(jù)發(fā)生變化的時(shí)候重新分析每行數(shù)據(jù)
二維數(shù)組保存分析的數(shù)據(jù), 使用二維數(shù)組保存分析完的詞法, 保留原生的代碼行
通過v-bind:class對(duì)不同類型的詞法進(jìn)行代碼高亮的簡單呈現(xiàn)
  {{word.word}}
文件的讀取和寫入
使用Electron中引入Node的fs模塊來進(jìn)行文件讀取寫入處理
使用Electron的Dialog控件選取文件
import Promise from "bluebird" import electron from "electron" const {dialog} = electron.remote const fs = Promise.promisifyAll(require("fs")); const writePackage = (filePath, data) => { return fs.writeFileAsync(filePath, JSON.stringify(data, null, 2)).catch(err => { return Promise.reject(err) }); } const readPackage = (filePath) => { return fs.readFileAsync(filePath, "utf-8").catch(err => { return Promise.reject(err) }); } const openDialog = () => { return new Promise((resolve, reject) => { dialog.showOpenDialog({ properties: [ "openFile", ] }, (res) => { if(!res) { return reject("404") } return resolve(res[0]) }); }) } export default { writePackage, readPackage, openDialog }
對(duì)此, 一個(gè)簡單的C++詞法分析就完成了, 過程并不復(fù)雜, 只要理解了優(yōu)先級(jí)和并列情況的區(qū)分就比較清晰的寫出, 由于
個(gè)人匆匆寫完這個(gè)程序, 并沒有對(duì)js部分的代碼進(jìn)行優(yōu)化, 質(zhì)量過低, 僅供參考
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/82199.html
摘要:對(duì)應(yīng)多種語法規(guī)則可以為指定樣式。渲染頁面繪制到屏幕后,頁面結(jié)構(gòu)的改變也有可能導(dǎo)致渲染樹重新計(jì)算,其中重排和重繪是最耗時(shí)的部分。 寫了這么多class,color,background,display...; 也許有時(shí)候會(huì)疑惑,怎么就顯示在頁面上,改變元素的樣式。 本文簡明介紹整個(gè)解析,匹配,渲染過程 css 描述 css 是Cascading Style Sheets的簡寫,是一種樣式...
摘要:類將源代碼解釋并構(gòu)建成抽象語法樹,使用類來創(chuàng)建它們,并使用類來分配內(nèi)存。類抽象語法樹的訪問者類,主要用來遍歷抽象語法樹。在該函數(shù)中,先使用類來生成抽象語法樹再使用類來生成本地代碼。 通過上一篇文章,我們知道了JavaScript引擎是執(zhí)行JavaScript代碼的程序或解釋器,了解了JavaScript引擎的基本工作原理。我們經(jīng)常聽說的JavaScript引擎就是V8引擎,這篇文章我們...
摘要:執(zhí)行過程引擎會(huì)加載源代碼,把它分解成字符串又叫做分詞,再把這些字符串轉(zhuǎn)換成編譯器可以理解的字節(jié)碼,然后執(zhí)行這些字節(jié)碼。接著四個(gè)進(jìn)程開始參與進(jìn)來,分析和執(zhí)行解析器所生成的字節(jié)碼。 JavaScript運(yùn)行原理 知其然,也要知其所以然,這里主要談一談對(duì)JavaScript運(yùn)行原理的理解。 JAVA虛擬機(jī) 首先我們從JAVA虛擬機(jī)說起。 首先說一下為什么要做成虛擬機(jī),因?yàn)闄C(jī)器不同,如果沒有虛...
摘要:更好的安全性隨著的發(fā)布,從升級(jí)到了,更安全且更易配置。通過使用,程序可以減少握手所需時(shí)間來提升請求性能。提供診斷報(bào)告有一項(xiàng)實(shí)驗(yàn)功能,根據(jù)用戶需求提供診斷報(bào)告,包括崩潰性能下降內(nèi)存泄露使用高等等。前端精讀幫你篩選靠譜的內(nèi)容。 1. 引言 Node12 發(fā)布有幾個(gè)月了,讓我們跟隨 Nodejs 12 一起看看 Node12 帶來了哪些改變。 2. 概述 Node12 與以往的版本不同,帶來...
閱讀 3012·2021-11-24 10:22
閱讀 3058·2021-11-23 10:10
閱讀 1367·2021-09-28 09:35
閱讀 1761·2019-08-29 13:16
閱讀 1400·2019-08-26 13:29
閱讀 2798·2019-08-26 10:27
閱讀 687·2019-08-26 10:09
閱讀 1450·2019-08-23 18:05