diff --git a/Complie-script/comple/comple-script.mjs b/Complie-script/comple/comple-script.mjs new file mode 100644 index 0000000..d71b4fa --- /dev/null +++ b/Complie-script/comple/comple-script.mjs @@ -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); diff --git a/Complie-script/comple/lexer.mjs b/Complie-script/comple/lexer.mjs new file mode 100644 index 0000000..a9625cc --- /dev/null +++ b/Complie-script/comple/lexer.mjs @@ -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 ''; + } + } +} diff --git a/Complie-script/comple/token.mjs b/Complie-script/comple/token.mjs new file mode 100644 index 0000000..1c6abb7 --- /dev/null +++ b/Complie-script/comple/token.mjs @@ -0,0 +1,7 @@ +// token.mjs +export const token = { + startTag: 'startTag', + endTag: 'endTag', + text: 'text', + eof: 'eof' +}; \ No newline at end of file diff --git a/Complie-script/xschema/A.schema.ts b/Complie-script/xschema/A.schema.ts new file mode 100644 index 0000000..d2fb1ab --- /dev/null +++ b/Complie-script/xschema/A.schema.ts @@ -0,0 +1,5 @@ +Start Tag: iv + Attribute: v="" + Attribute: name="{{jsx-parse}}" + Attribute: class="{{fuck}}" + Attribute: id="1" diff --git a/Complie-script/xschema/A.xschema.tsx b/Complie-script/xschema/A.xschema.tsx new file mode 100644 index 0000000..2c2f8fe --- /dev/null +++ b/Complie-script/xschema/A.xschema.tsx @@ -0,0 +1,15 @@ +
Life is like rape
+ +Looking away, everything is sad
+ +