豆包写的LISP解释器,共200多行
这才是真神
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <stdexcept>
// 定义 Token 类型
enum TokenType {
LEFT_PAREN,
RIGHT_PAREN,
NUMBER,
SYMBOL
};
// 定义 Token 结构体
struct Token {
TokenType type;
std::string value;
};
// 判断字符串是否全为数字的辅助函数
bool isAllDigits(const std::string& str) {
for (std::string::size_type i = 0; i < str.length(); ++i) {
if (!isdigit(str)) {
return false;
}
}
return true;
}
// 词法分析函数,添加调试输出
std::vector<Token> tokenize(const std::string& input) {
std::vector<Token> tokens;
std::string tokenStr;
std::cout << "Tokenizing input: " << input << std::endl;
for (size_t i = 0; i < input.length(); ++i) {
char c = input;
if (c == ' ') {
if (!tokenStr.empty()) {
Token token;
if (isAllDigits(tokenStr)) {
token.type = NUMBER;
token.value = tokenStr;
} else {
token.type = SYMBOL;
token.value = tokenStr;
}
tokens.push_back(token);
std::cout << "Found token: type=";
switch (token.type) {
case LEFT_PAREN: std::cout << "LEFT_PAREN"; break;
case RIGHT_PAREN: std::cout << "RIGHT_PAREN"; break;
case NUMBER: std::cout << "NUMBER"; break;
case SYMBOL: std::cout << "SYMBOL"; break;
}
std::cout << ", value=" << token.value << std::endl;
tokenStr.clear();
}
} else if (c == '(') {
if (!tokenStr.empty()) {
Token token;
if (isAllDigits(tokenStr)) {
token.type = NUMBER;
token.value = tokenStr;
} else {
token.type = SYMBOL;
token.value = tokenStr;
}
tokens.push_back(token);
std::cout << "Found token: type=";
switch (token.type) {
case LEFT_PAREN: std::cout << "LEFT_PAREN"; break;
case RIGHT_PAREN: std::cout << "RIGHT_PAREN"; break;
case NUMBER: std::cout << "NUMBER"; break;
case SYMBOL: std::cout << "SYMBOL"; break;
}
std::cout << ", value=" << token.value << std::endl;
tokenStr.clear();
}
Token token;
token.type = LEFT_PAREN;
token.value = "(";
tokens.push_back(token);
std::cout << "Found token: type=LEFT_PAREN, value=(" << std::endl;
} else if (c == ')') {
if (!tokenStr.empty()) {
Token token;
if (isAllDigits(tokenStr)) {
token.type = NUMBER;
token.value = tokenStr;
} else {
token.type = SYMBOL;
token.value = tokenStr;
}
tokens.push_back(token);
std::cout << "Found token: type=";
switch (token.type) {
case LEFT_PAREN: std::cout << "LEFT_PAREN"; break;
case RIGHT_PAREN: std::cout << "RIGHT_PAREN"; break;
case NUMBER: std::cout << "NUMBER"; break;
case SYMBOL: std::cout << "SYMBOL"; break;
}
std::cout << ", value=" << token.value << std::endl;
tokenStr.clear();
}
Token token;
token.type = RIGHT_PAREN;
token.value = ")";
tokens.push_back(token);
std::cout << "Found token: type=RIGHT_PAREN, value=)" << std::endl;
} else {
tokenStr += c;
}
}
if (!tokenStr.empty()) {
Token token;
if (isAllDigits(tokenStr)) {
token.type = NUMBER;
token.value = tokenStr;
} else {
token.type = SYMBOL;
token.value = tokenStr;
}
tokens.push_back(token);
std::cout << "Found token: type=";
switch (token.type) {
case LEFT_PAREN: std::cout << "LEFT_PAREN"; break;
case RIGHT_PAREN: std::cout << "RIGHT_PAREN"; break;
case NUMBER: std::cout << "NUMBER"; break;
case SYMBOL: std::cout << "SYMBOL"; break;
}
std::cout << ", value=" << token.value << std::endl;
}
return tokens;
}
// 定义 AST 节点类型
struct ASTNode {
std::string value;
std::vector<ASTNode> children;
};
// 语法分析函数,添加调试输出
ASTNode parse(const std::vector<Token>& tokens, size_t& pos, int depth = 0) {
std::string indent(depth * 2, ' ');
std::cout << indent << "Parsing at position " << pos << std::endl;
ASTNode node;
const Token& token = tokens;
if (token.type == LEFT_PAREN) {
std::cout << indent << "Found left parenthesis, starting sub - expression" << std::endl;
while (tokens.type != RIGHT_PAREN) {
node.children.push_back(parse(tokens, pos, depth + 1));
}
std::cout << indent << "Found right parenthesis, ending sub - expression" << std::endl;
pos++; // 跳过右括号
} else if (token.type == NUMBER || token.type == SYMBOL) {
node.value = token.value;
std::cout << indent << "Found " << (token.type == NUMBER ? "number" : "symbol") << ": " << node.value << std::endl;
}
return node;
}
// 将字符串转换为整数的辅助函数
int stringToInt(const std::string& str) {
int result = 0;
std::istringstream iss(str);
iss >> result;
return result;
}
// 解释执行函数,添加调试输出
int evaluate(const ASTNode& node, int depth = 0) {
std::string indent(depth * 2, ' ');
std::cout << indent << "Evaluating node: ";
if (node.children.empty()) {
std::cout << "Leaf node with value " << node.value << std::endl;
try {
int val = stringToInt(node.value);
std::cout << indent << "Value of leaf node: " << val << std::endl;
return val;
} catch (...) {
throw std::runtime_error("Invalid number: " + node.value);
}
}
std::string op = node.children.value;
std::cout << "Operator node with op " << op << std::endl;
if (op == "+") {
int result = 0;
std::cout << indent << "Performing addition" << std::endl;
for (size_t i = 1; i < node.children.size(); ++i) {
int childResult = evaluate(node.children, depth + 1);
result += childResult;
std::cout << indent << "Adding child result " << childResult << ", current sum: " << result << std::endl;
}
std::cout << indent << "Final result of addition: " << result << std::endl;
return result;
} else if (op == "-") {
std::cout << indent << "Performing subtraction" << std::endl;
if (node.children.size() == 2) {
int childResult = evaluate(node.children, depth + 1);
std::cout << indent << "Result of subtraction: " << childResult << std::endl;
return childResult;
} else {
int result = evaluate(node.children, depth + 1);
std::cout << indent << "Initial value for subtraction: " << result << std::endl;
for (size_t i = 2; i < node.children.size(); ++i) {
int childResult = evaluate(node.children, depth + 1);
result -= childResult;
std::cout << indent << "Subtracting child result " << childResult << ", current result: " << result << std::endl;
}
std::cout << indent << "Final result of subtraction: " << result << std::endl;
return result;
}
} else {
throw std::runtime_error("Unsupported operator: " + op);
}
}
int main() {
std::string input;
std::cout << "Enter a LISP expression: ";
std::getline(std::cin, input);
try {
std::vector<Token> tokens = tokenize(input);
size_t pos = 0;
std::cout << "Starting parsing..." << std::endl;
ASTNode ast = parse(tokens, pos);
std::cout << "Starting evaluation..." << std::endl;
int result = evaluate(ast);
std::cout << "Result: " << result << std::endl;
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}
代码生成/调试过程
https://www.doubao.com/thread/wcd00bbdbbc68a282 不大长的代码,用AI的确是OK了,我昨天把协议给DS,人家就给出代码,直接就成功了:
------------------------------------------------------------
TCP通讯协议:
字节位 0、 ASCII 字符’V’,整数 86。
字节位 1、 ASCII 字符’Z’,整数 90.
字节位 2、 Data 数据类型
0X00 数据包。
0X01 心跳包,数据长度为 0, DATA 为空
字节位 3、 包序号,包序列号为递增的数值,用于对应请求命令与返回命
令;例如发送一个请求命令到服务器端,服务器端在返回结果时,会将请求命令中
的包序列号填充到返回数据包的包序列号中,便于客户端这边将返回结果与请求命
令进行对应。如果不存在对应问题,则设置为 0 即可。如果编号到 255,则从 0 开
始重新编号。
字节位 4 – 7、一共四位,代表接下来的数据长度。这个数据是网络字节序,
在接收的时候务必调用 htol 这样的函数将网络字节序转换成主机字节序。数据的长
度不要大于 1024 * 1024 = 1MB。服务器将不会接收超过 1MB 大小的数据,同样服务
器也不会发送超过 1MB 大小的数据包。理论上,除了心跳包之外,其它所有数据的
长度都不会是 0。
字节位 8 以后是数据包
数据包,就发送这个:
{"cmd": "getsn","id":"123456"}
麻烦用python写一段代码, 发送上面的一段指令给 192.168.1.100:8131
----------------------------------------
import socket
import struct
import json
# 目标地址和端口
HOST = '192.168.1.100'
PORT = 8131
# 构造协议头
header = bytearray()
# 字节位0-1:固定头
header.append(ord('V'))# 0x56
header.append(ord('Z'))# 0x5A
# 字节位2:数据类型(0x00数据包)
header.append(0x00)
# 字节位3:包序号(设为0)
header.append(0x00)
# 构造数据部分
data = json.dumps({"cmd": "getsn", "id": "123456"}).encode('utf-8')
# 字节位4-7:数据长度(网络字节序)
data_length = struct.pack('>I', len(data))# 大端无符号整型
header.extend(data_length)
# 组合完整数据包
packet = header + data
# 创建socket并发送
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.sendall(packet)
print("数据已发送")
# 可选:接收响应(根据实际情况处理)
# response = s.recv(1024)
# print("收到响应:", response) bigluo 发表于 2025-3-6 15:40
不大长的代码,用AI的确是OK了,我昨天把协议给DS,人家就给出代码,直接就成功了:
-------------------- ...
现在AI太强,严重加速了历史进程,嗅探到了危险的气息 ;P 能将Fortran77源代码转换成python代码吗? girlexplorer 发表于 2025-3-6 23:36
能将Fortran77源代码转换成python代码吗?
肯定可以,这难度不高 俺提个意见,啊不,建议啊。
现在写代码一般都不用 8 个字符的缩进了,普遍用 4 个字符甚至 2 个字符。 scoopydoo 发表于 2025-3-7 00:12
俺提个意见,啊不,建议啊。
现在写代码一般都不用 8 个字符的缩进了,普遍用 4 个字符甚至 2 个字符。
原文内容是4个空格缩进,论坛自动转了码 我想找一款LISP解释器,怀念一下约30多年前上人工智能课,在DOS下使用lisp做符号处理的感觉。LISP语言编程,给人另外一种思维,这是我当时的感觉。
页:
[1]