{{word.word}}
摘要:架構分析進行文件數據處理進行視圖的呈現作為客戶端語法解析效果展示讀取形式按照代碼行進行讀取每次讀取到一行就進行遍歷分析關鍵字與特殊符號建立映射關鍵字特殊字符遍歷分析過程代碼注釋匹配當讀到一行中包含的兩個字符時候這時把代碼注釋的標志
架構分析
Node進行文件數據處理
Vue.js進行視圖的呈現
Electron作為客戶端
C++語法解析 效果展示 讀取形式按照代碼行進行讀取, 每次讀取到一行就進行遍歷分析
關鍵字與特殊符號建立映射/** * 關鍵字 */ 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") })遍歷分析過程
代碼注釋匹配
當讀到一行中包含/*的兩個字符時候, 這時把代碼注釋的標志設置為true, 然后一直讀取,知道遇到*/的時候就把標志重新置為false
判斷是否可以構成單詞,成立的條件是不以數字開頭,并且只包含數字, 下劃線, 以及字母, 可以通過正則來/[a-z]|[A-z]|_/匹配
判斷是否為字符串或者字符, 成立條件是以","開頭
判斷是否為數字
判斷是否為特殊字符, 這時就通過建立的映射進行關鍵字查找
判斷空格
代碼解釋
判斷工具函數
//判斷是否是字母與下劃線 function judgeWord(word) { let wordPatten = /[a-z]|[A-z]|\_/ return wordPatten.test(word) } //判斷是否為數字 function judgeNumber(number) { let numberPatten = /[0-9]/ return numberPatten.test(number) } //判斷是否為特殊字符 function judgeSpecialWord(letter) { return wordsMap.get(letter) === "specialWord" ? true : false } //判斷是否為關鍵詞 function judgeKeyWord(letter) { return wordsMap.get(letter) === "keyWord" ? true : false }
行分析函數
exports.analysisLine = (line, annotation) => { let oneLine = [] let word = "" let i = 0 let includeFile = false while (i < line.length) { //注釋代碼的優先級最高,需要先進行判斷 if (line[i] === "/" && line[i + 1] === "*") { word += line[i] i++ annotation = true; } if (!annotation) { //表示不是注釋內容 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)) { //判斷單詞是否屬于關鍵詞 oneLine.push({ word: word, type: "keyWord" }) } else { //不為關鍵詞, 則為標識符 oneLine.push({ word: word, type: "identifier" }) } //由于include是屬于頭文件的引入, 需要對頭文件進行特殊處理 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])) { //數字判斷 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 { //表示注釋內容 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 }界面實現過程
Electron, Vue搭建
具體的搭建過程省略, 可查看源碼或自行查找資料
動態編輯顯示
數據綁定, 使用v-model結合watch進行數據監控, 當數據發生變化的時候重新分析每行數據
二維數組保存分析的數據, 使用二維數組保存分析完的詞法, 保留原生的代碼行
通過v-bind:class對不同類型的詞法進行代碼高亮的簡單呈現
  {{word.word}}
文件的讀取和寫入
使用Electron中引入Node的fs模塊來進行文件讀取寫入處理
使用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 }
對此, 一個簡單的C++詞法分析就完成了, 過程并不復雜, 只要理解了優先級和并列情況的區分就比較清晰的寫出, 由于
個人匆匆寫完這個程序, 并沒有對js部分的代碼進行優化, 質量過低, 僅供參考
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/82199.html
摘要:對應多種語法規則可以為指定樣式。渲染頁面繪制到屏幕后,頁面結構的改變也有可能導致渲染樹重新計算,其中重排和重繪是最耗時的部分。 寫了這么多class,color,background,display...; 也許有時候會疑惑,怎么就顯示在頁面上,改變元素的樣式。 本文簡明介紹整個解析,匹配,渲染過程 css 描述 css 是Cascading Style Sheets的簡寫,是一種樣式...
摘要:類將源代碼解釋并構建成抽象語法樹,使用類來創建它們,并使用類來分配內存。類抽象語法樹的訪問者類,主要用來遍歷抽象語法樹。在該函數中,先使用類來生成抽象語法樹再使用類來生成本地代碼。 通過上一篇文章,我們知道了JavaScript引擎是執行JavaScript代碼的程序或解釋器,了解了JavaScript引擎的基本工作原理。我們經常聽說的JavaScript引擎就是V8引擎,這篇文章我們...
摘要:執行過程引擎會加載源代碼,把它分解成字符串又叫做分詞,再把這些字符串轉換成編譯器可以理解的字節碼,然后執行這些字節碼。接著四個進程開始參與進來,分析和執行解析器所生成的字節碼。 JavaScript運行原理 知其然,也要知其所以然,這里主要談一談對JavaScript運行原理的理解。 JAVA虛擬機 首先我們從JAVA虛擬機說起。 首先說一下為什么要做成虛擬機,因為機器不同,如果沒有虛...
摘要:更好的安全性隨著的發布,從升級到了,更安全且更易配置。通過使用,程序可以減少握手所需時間來提升請求性能。提供診斷報告有一項實驗功能,根據用戶需求提供診斷報告,包括崩潰性能下降內存泄露使用高等等。前端精讀幫你篩選靠譜的內容。 1. 引言 Node12 發布有幾個月了,讓我們跟隨 Nodejs 12 一起看看 Node12 帶來了哪些改變。 2. 概述 Node12 與以往的版本不同,帶來...
閱讀 2975·2021-11-24 10:22
閱讀 3045·2021-11-23 10:10
閱讀 1353·2021-09-28 09:35
閱讀 1752·2019-08-29 13:16
閱讀 1395·2019-08-26 13:29
閱讀 2782·2019-08-26 10:27
閱讀 678·2019-08-26 10:09
閱讀 1436·2019-08-23 18:05