feat: creat script for comple xshema
This commit is contained in:
		
							parent
							
								
									4530423cb7
								
							
						
					
					
						commit
						a3d034cc63
					
				
							
								
								
									
										118
									
								
								Complie-script/comple/comple-script.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								Complie-script/comple/comple-script.mjs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,118 @@ | ||||
| import fs from 'fs'; | ||||
| import path from 'path'; | ||||
| import { Lexer } from './lexer.mjs';  // 引入 Lexer 类
 | ||||
| 
 | ||||
| // 递归遍历项目目录
 | ||||
| function findXSchemaDirectory(directoryPath) { | ||||
|     fs.readdir(directoryPath, (err, files) => { | ||||
|         if (err) { | ||||
|             console.error('无法读取目录:', err); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // 遍历目录中的所有文件和文件夹
 | ||||
|         files.forEach(file => { | ||||
|             const filePath = path.join(directoryPath, file); | ||||
| 
 | ||||
|             fs.stat(filePath, (err, stats) => { | ||||
|                 if (err) { | ||||
|                     console.error('无法获取文件状态:', err); | ||||
|                     return; | ||||
|                 } | ||||
| 
 | ||||
|                 if (stats.isDirectory()) { | ||||
|                     // 如果是文件夹,检查是否为 xschema 文件夹
 | ||||
|                     if (file === 'xschema') { | ||||
|                         // 找到 xschema 文件夹,继续查找其中的 .xschema.tsx 文件
 | ||||
|                         findXSchemaFiles(filePath); | ||||
|                     } else { | ||||
|                         // 如果是其他文件夹,递归调用
 | ||||
|                         findXSchemaDirectory(filePath); | ||||
|                     } | ||||
|                 } | ||||
|             }); | ||||
|         }); | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| // 查找 xschema 文件夹中的 .xschema.tsx 文件
 | ||||
| function findXSchemaFiles(directoryPath) { | ||||
|     fs.readdir(directoryPath, (err, files) => { | ||||
|         if (err) { | ||||
|             console.error('无法读取目录:', err); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         files.forEach(file => { | ||||
|             const filePath = path.join(directoryPath, file); | ||||
| 
 | ||||
|             // 如果是 .xschema.tsx 文件,进行处理
 | ||||
|             if (file.endsWith('.xschema.tsx')) { | ||||
|                 processFile(filePath); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| // 处理找到的 .xschema.tsx 文件
 | ||||
| function processFile(filePath) { | ||||
|     console.log('找到文件:', filePath); | ||||
| 
 | ||||
|     // 读取文件内容
 | ||||
|     fs.readFile(filePath, 'utf8', (err, data) => { | ||||
|         if (err) { | ||||
|             console.error('无法读取文件:', err); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // 在这里创建一个 Lexer 实例并进行词法分析
 | ||||
|         const lexer = new Lexer(data); // 创建 Lexer 实例
 | ||||
|         const tokens = lexer.lex();  // 获取 tokens
 | ||||
| 
 | ||||
|         // 打印出解析得到的 tokens,或者根据需要进行进一步处理
 | ||||
|         console.log('生成的 Tokens:', tokens); | ||||
|         // 进行编译
 | ||||
|         const compiledData = compileFile(data, tokens); | ||||
| 
 | ||||
|         // 输出编译后的数据并保存为 .tsx 文件(去除 xschema 部分)
 | ||||
|         const outputFilePath = filePath.replace('.xschema.tsx', '.schema.ts'); // 输出文件名去除 xschema 部分,保留 .tsx 后缀
 | ||||
|         fs.writeFile(outputFilePath, compiledData, 'utf8', (err) => { | ||||
|             if (err) { | ||||
|                 console.error('无法写入 TSX 文件:', err); | ||||
|             } else { | ||||
|                 console.log('编译后的文件已保存:', outputFilePath); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| } | ||||
| function compileFile(fileContent, tokens) { | ||||
|     let compiledCode = ''; | ||||
| 
 | ||||
|     tokens.forEach(token => { | ||||
|         if (token === 'startTag') { | ||||
|             // 输出 'startTag' 标记
 | ||||
|             compiledCode += `Start Tag: ${tokens[1]} \n`; | ||||
| 
 | ||||
|             // 输出属性
 | ||||
|             tokens[2].forEach(attr => { | ||||
|                 const key = Object.keys(attr)[0];  // 获取属性名
 | ||||
|                 const value = attr[key];  // 获取属性值
 | ||||
|                 compiledCode += `  Attribute: ${key}="${value}" \n`; | ||||
|             }); | ||||
|         } | ||||
|         else if (token === 'endTag') { | ||||
|             // 输出 'endTag' 标记(如果有的话)
 | ||||
|             compiledCode += `End Tag: ${tokens[1]} \n`; | ||||
|         } | ||||
|         else if (token === 'text') { | ||||
|             // 输出文本内容
 | ||||
|             compiledCode += `Text: ${tokens[1]} \n`; | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     return compiledCode; // 返回生成的简单 token 输出
 | ||||
| } | ||||
| 
 | ||||
| // 启动程序并从根目录开始查找 xschema 文件夹
 | ||||
| const projectRootDirectory = './'; // 设置项目根目录,通常为当前目录
 | ||||
| findXSchemaDirectory(projectRootDirectory); | ||||
							
								
								
									
										130
									
								
								Complie-script/comple/lexer.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								Complie-script/comple/lexer.mjs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,130 @@ | ||||
| // lexer.mjs
 | ||||
| import { token } from './token.mjs'; | ||||
| 
 | ||||
| export class Lexer { | ||||
|     constructor(string) { | ||||
|         this.string = string; | ||||
|         this.pos = 0; | ||||
|     } | ||||
| 
 | ||||
|     advance() { | ||||
|         return this.string[this.pos++]; | ||||
|     } | ||||
| 
 | ||||
|     lookAhead() { | ||||
|         return this.string[this.pos]; | ||||
|     } | ||||
| 
 | ||||
|     trimQuotes(str) { | ||||
|         return str.replace(/^['"]|['"]$/g, '');  // Remove surrounding quotes
 | ||||
|     } | ||||
| 
 | ||||
|     lex() { | ||||
|         let text = ''; | ||||
|         while (true) { | ||||
|             let t = this.advance(); | ||||
|             let tokenResult = ''; // Renamed to avoid conflict with outer token variable
 | ||||
|             switch (t) { | ||||
|                 case '<': | ||||
|                     if (this.lookAhead() === '/') { | ||||
|                         tokenResult = this.handleEndTag(); | ||||
|                     } else { | ||||
|                         tokenResult = this.handleStartTag(); | ||||
|                     } | ||||
|                     break; | ||||
|                 case '\n': | ||||
|                     break; | ||||
|                 case ' ': | ||||
|                     if (text !== '') { | ||||
|                         text += t; | ||||
|                     } else { | ||||
|                         break; | ||||
|                     } | ||||
|                     break; | ||||
|                 case undefined: | ||||
|                     if (this.pos >= this.string.length) { | ||||
|                         tokenResult = [token.eof, 'eof', []]; | ||||
|                         break; | ||||
|                     } | ||||
|                     break; | ||||
|                 default: | ||||
|                     text += t; | ||||
|                     tokenResult = this.handleTextTag(text); | ||||
|                     break; | ||||
|             } | ||||
|             this.string = this.string.slice(this.pos); | ||||
|             this.pos = 0; | ||||
|             if (tokenResult !== '') { | ||||
|                 return tokenResult; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     handleStartTag() { | ||||
|         let idx = this.string.indexOf('>'); | ||||
|         if (idx === -1) { | ||||
|             throw new Error('parse err! miss match ' + '>'); | ||||
|         } | ||||
|         let str = this.string.slice(this.pos, idx); | ||||
|         let s = ''; | ||||
|         if (str.includes(' ')) { | ||||
|             s = str.split(' ')[0]; // Fixed splitting logic
 | ||||
|         } else { | ||||
|             s = str; | ||||
|         } | ||||
|         let type = s.slice(1); | ||||
|         this.pos += type.length; | ||||
|         let props = this.handlePropTag(); | ||||
|         this.advance(); | ||||
|         return [token.startTag, type, props]; | ||||
|     } | ||||
| 
 | ||||
|     handlePropTag() { | ||||
|         let idx = this.string.indexOf('>'); | ||||
|         if (idx == -1) { | ||||
|             throw new Error('parse err! miss match ' + '>'); | ||||
|         } | ||||
|         let string = this.string.slice(this.pos, idx); | ||||
|         let pm = []; | ||||
|         if (string.trim() != '') {  // Checking if string is not empty
 | ||||
|             let props = string.split(' '); | ||||
|             pm = props.filter((prop) => { | ||||
|                 return prop != ''; | ||||
|             }).map((prop) => { | ||||
|                 let kv = prop.split('='); | ||||
|                 let o = {}; | ||||
|                 // Ensure kv[1] exists before calling trimQuotes
 | ||||
|                 if (kv[1]) { | ||||
|                     o[kv[0]] = this.trimQuotes(kv[1]); | ||||
|                 } else { | ||||
|                     o[kv[0]] = '';  // Or assign a default value
 | ||||
|                 } | ||||
|                 return o; | ||||
|             }); | ||||
|             this.pos += string.length; | ||||
|         } | ||||
| 
 | ||||
|         return pm; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     handleEndTag() { | ||||
|         this.advance(); | ||||
|         let idx = this.string.indexOf('>'); | ||||
|         let type = this.string.slice(this.pos, idx); | ||||
|         this.pos += type.length; | ||||
|         if (this.advance() !== '>') { | ||||
|             throw new Error('parse err! miss match ' + '>'); | ||||
|         } | ||||
|         return [token.endTag, type, []]; | ||||
|     } | ||||
| 
 | ||||
|     handleTextTag(text) { | ||||
|         let t = text.trim(); | ||||
|         if (this.lookAhead() === '<') { | ||||
|             return [token.text, t, []]; | ||||
|         } else { | ||||
|             return ''; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										7
									
								
								Complie-script/comple/token.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								Complie-script/comple/token.mjs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| // token.mjs
 | ||||
| export const token = { | ||||
|     startTag: 'startTag', | ||||
|     endTag: 'endTag', | ||||
|     text: 'text', | ||||
|     eof: 'eof' | ||||
| }; | ||||
							
								
								
									
										5
									
								
								Complie-script/xschema/A.schema.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								Complie-script/xschema/A.schema.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| Start Tag: iv  | ||||
|   Attribute: v=""  | ||||
|   Attribute: name="{{jsx-parse}}"  | ||||
|   Attribute: class="{{fuck}}"  | ||||
|   Attribute: id="1"  | ||||
							
								
								
									
										15
									
								
								Complie-script/xschema/A.xschema.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								Complie-script/xschema/A.xschema.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| <div name="{{jsx-parse}}" class="{{fuck}}" id="1"> | ||||
|     Life is too difficult | ||||
|     <span name="life" like="rape"> | ||||
|         <p>Life is like rape</p> | ||||
|     </span> | ||||
|     <div> | ||||
|         <span name="live" do="{{gofuck}}"> | ||||
|             <p>Looking away, everything is sad</p> | ||||
|         </span> | ||||
|         <Counter me="excellent"> | ||||
|             I am awesome | ||||
|         </Counter> | ||||
|     </div> | ||||
| </div> | ||||
| 
 | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user