矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
查看: 820|回复: 7

豆包写的LISP解释器,共200多行

[复制链接]
     
发表于 2025-3-6 13:53:46 | 显示全部楼层 |阅读模式
微信图片_20250306135105.png
这才是真神
  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. #include <sstream>
  5. #include <stdexcept>

  6. // 定义 Token 类型
  7. enum TokenType {
  8.         LEFT_PAREN,
  9.         RIGHT_PAREN,
  10.         NUMBER,
  11.         SYMBOL
  12. };

  13. // 定义 Token 结构体
  14. struct Token {
  15.         TokenType type;
  16.         std::string value;
  17. };

  18. // 判断字符串是否全为数字的辅助函数
  19. bool isAllDigits(const std::string& str) {
  20.         for (std::string::size_type i = 0; i < str.length(); ++i) {
  21.                 if (!isdigit(str[i])) {
  22.                         return false;
  23.                 }
  24.         }
  25.         return true;
  26. }

  27. // 词法分析函数,添加调试输出
  28. std::vector<Token> tokenize(const std::string& input) {
  29.         std::vector<Token> tokens;
  30.         std::string tokenStr;
  31.         std::cout << "Tokenizing input: " << input << std::endl;
  32.         for (size_t i = 0; i < input.length(); ++i) {
  33.                 char c = input[i];
  34.                 if (c == ' ') {
  35.                         if (!tokenStr.empty()) {
  36.                                 Token token;
  37.                                 if (isAllDigits(tokenStr)) {
  38.                                         token.type = NUMBER;
  39.                                         token.value = tokenStr;
  40.                                 } else {
  41.                                         token.type = SYMBOL;
  42.                                         token.value = tokenStr;
  43.                                 }
  44.                                 tokens.push_back(token);
  45.                                 std::cout << "Found token: type=";
  46.                                 switch (token.type) {
  47.                                 case LEFT_PAREN: std::cout << "LEFT_PAREN"; break;
  48.                                 case RIGHT_PAREN: std::cout << "RIGHT_PAREN"; break;
  49.                                 case NUMBER: std::cout << "NUMBER"; break;
  50.                                 case SYMBOL: std::cout << "SYMBOL"; break;
  51.                                 }
  52.                                 std::cout << ", value=" << token.value << std::endl;
  53.                                 tokenStr.clear();
  54.                         }
  55.                 } else if (c == '(') {
  56.                         if (!tokenStr.empty()) {
  57.                                 Token token;
  58.                                 if (isAllDigits(tokenStr)) {
  59.                                         token.type = NUMBER;
  60.                                         token.value = tokenStr;
  61.                                 } else {
  62.                                         token.type = SYMBOL;
  63.                                         token.value = tokenStr;
  64.                                 }
  65.                                 tokens.push_back(token);
  66.                                 std::cout << "Found token: type=";
  67.                                 switch (token.type) {
  68.                                 case LEFT_PAREN: std::cout << "LEFT_PAREN"; break;
  69.                                 case RIGHT_PAREN: std::cout << "RIGHT_PAREN"; break;
  70.                                 case NUMBER: std::cout << "NUMBER"; break;
  71.                                 case SYMBOL: std::cout << "SYMBOL"; break;
  72.                                 }
  73.                                 std::cout << ", value=" << token.value << std::endl;
  74.                                 tokenStr.clear();
  75.                         }
  76.                         Token token;
  77.                         token.type = LEFT_PAREN;
  78.                         token.value = "(";
  79.                         tokens.push_back(token);
  80.                         std::cout << "Found token: type=LEFT_PAREN, value=(" << std::endl;
  81.                 } else if (c == ')') {
  82.                         if (!tokenStr.empty()) {
  83.                                 Token token;
  84.                                 if (isAllDigits(tokenStr)) {
  85.                                         token.type = NUMBER;
  86.                                         token.value = tokenStr;
  87.                                 } else {
  88.                                         token.type = SYMBOL;
  89.                                         token.value = tokenStr;
  90.                                 }
  91.                                 tokens.push_back(token);
  92.                                 std::cout << "Found token: type=";
  93.                                 switch (token.type) {
  94.                                 case LEFT_PAREN: std::cout << "LEFT_PAREN"; break;
  95.                                 case RIGHT_PAREN: std::cout << "RIGHT_PAREN"; break;
  96.                                 case NUMBER: std::cout << "NUMBER"; break;
  97.                                 case SYMBOL: std::cout << "SYMBOL"; break;
  98.                                 }
  99.                                 std::cout << ", value=" << token.value << std::endl;
  100.                                 tokenStr.clear();
  101.                         }
  102.                         Token token;
  103.                         token.type = RIGHT_PAREN;
  104.                         token.value = ")";
  105.                         tokens.push_back(token);
  106.                         std::cout << "Found token: type=RIGHT_PAREN, value=)" << std::endl;
  107.                 } else {
  108.                         tokenStr += c;
  109.                 }
  110.         }
  111.         if (!tokenStr.empty()) {
  112.                 Token token;
  113.                 if (isAllDigits(tokenStr)) {
  114.                         token.type = NUMBER;
  115.                         token.value = tokenStr;
  116.                 } else {
  117.                         token.type = SYMBOL;
  118.                         token.value = tokenStr;
  119.                 }
  120.                 tokens.push_back(token);
  121.                 std::cout << "Found token: type=";
  122.                 switch (token.type) {
  123.                 case LEFT_PAREN: std::cout << "LEFT_PAREN"; break;
  124.                 case RIGHT_PAREN: std::cout << "RIGHT_PAREN"; break;
  125.                 case NUMBER: std::cout << "NUMBER"; break;
  126.                 case SYMBOL: std::cout << "SYMBOL"; break;
  127.                 }
  128.                 std::cout << ", value=" << token.value << std::endl;
  129.         }
  130.         return tokens;
  131. }

  132. // 定义 AST 节点类型
  133. struct ASTNode {
  134.         std::string value;
  135.         std::vector<ASTNode> children;
  136. };

  137. // 语法分析函数,添加调试输出
  138. ASTNode parse(const std::vector<Token>& tokens, size_t& pos, int depth = 0) {
  139.         std::string indent(depth * 2, ' ');
  140.         std::cout << indent << "Parsing at position " << pos << std::endl;
  141.         ASTNode node;
  142.         const Token& token = tokens[pos++];
  143.         if (token.type == LEFT_PAREN) {
  144.                 std::cout << indent << "Found left parenthesis, starting sub - expression" << std::endl;
  145.                 while (tokens[pos].type != RIGHT_PAREN) {
  146.                         node.children.push_back(parse(tokens, pos, depth + 1));
  147.                 }
  148.                 std::cout << indent << "Found right parenthesis, ending sub - expression" << std::endl;
  149.                 pos++; // 跳过右括号
  150.         } else if (token.type == NUMBER || token.type == SYMBOL) {
  151.                 node.value = token.value;
  152.                 std::cout << indent << "Found " << (token.type == NUMBER ? "number" : "symbol") << ": " << node.value << std::endl;
  153.         }
  154.         return node;
  155. }

  156. // 将字符串转换为整数的辅助函数
  157. int stringToInt(const std::string& str) {
  158.         int result = 0;
  159.         std::istringstream iss(str);
  160.         iss >> result;
  161.         return result;
  162. }

  163. // 解释执行函数,添加调试输出
  164. int evaluate(const ASTNode& node, int depth = 0) {
  165.         std::string indent(depth * 2, ' ');
  166.         std::cout << indent << "Evaluating node: ";
  167.         if (node.children.empty()) {
  168.                 std::cout << "Leaf node with value " << node.value << std::endl;
  169.                 try {
  170.                         int val = stringToInt(node.value);
  171.                         std::cout << indent << "Value of leaf node: " << val << std::endl;
  172.                         return val;
  173.                 } catch (...) {
  174.                         throw std::runtime_error("Invalid number: " + node.value);
  175.                 }
  176.         }

  177.         std::string op = node.children[0].value;
  178.         std::cout << "Operator node with op " << op << std::endl;
  179.         if (op == "+") {
  180.                 int result = 0;
  181.                 std::cout << indent << "Performing addition" << std::endl;
  182.                 for (size_t i = 1; i < node.children.size(); ++i) {
  183.                         int childResult = evaluate(node.children[i], depth + 1);
  184.                         result += childResult;
  185.                         std::cout << indent << "Adding child result " << childResult << ", current sum: " << result << std::endl;
  186.                 }
  187.                 std::cout << indent << "Final result of addition: " << result << std::endl;
  188.                 return result;
  189.         } else if (op == "-") {
  190.                 std::cout << indent << "Performing subtraction" << std::endl;
  191.                 if (node.children.size() == 2) {
  192.                         int childResult = evaluate(node.children[1], depth + 1);
  193.                         std::cout << indent << "Result of subtraction: " << childResult << std::endl;
  194.                         return childResult;
  195.                 } else {
  196.                         int result = evaluate(node.children[1], depth + 1);
  197.                         std::cout << indent << "Initial value for subtraction: " << result << std::endl;
  198.                         for (size_t i = 2; i < node.children.size(); ++i) {
  199.                                 int childResult = evaluate(node.children[i], depth + 1);
  200.                                 result -= childResult;
  201.                                 std::cout << indent << "Subtracting child result " << childResult << ", current result: " << result << std::endl;
  202.                         }
  203.                         std::cout << indent << "Final result of subtraction: " << result << std::endl;
  204.                         return result;
  205.                 }
  206.         } else {
  207.                 throw std::runtime_error("Unsupported operator: " + op);
  208.         }
  209. }

  210. int main() {
  211.         std::string input;
  212.         std::cout << "Enter a LISP expression: ";
  213.         std::getline(std::cin, input);

  214.         try {
  215.                 std::vector<Token> tokens = tokenize(input);
  216.                 size_t pos = 0;
  217.                 std::cout << "Starting parsing..." << std::endl;
  218.                 ASTNode ast = parse(tokens, pos);
  219.                 std::cout << "Starting evaluation..." << std::endl;
  220.                 int result = evaluate(ast);
  221.                 std::cout << "Result: " << result << std::endl;
  222.         } catch (const std::exception& e) {
  223.                 std::cerr << "Error: " << e.what() << std::endl;
  224.         }

  225.         return 0;
  226. }
复制代码

代码生成/调试过程
https://www.doubao.com/thread/wcd00bbdbbc68a282

评分

2

查看全部评分

     
发表于 2025-3-6 15:40:57 | 显示全部楼层
不大长的代码,用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)
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2025-3-6 16:06:35 | 显示全部楼层
bigluo 发表于 2025-3-6 15:40
不大长的代码,用AI的确是OK了,我昨天把协议给DS,人家就给出代码,直接就成功了:
-------------------- ...

现在AI太强,严重加速了历史进程,嗅探到了危险的气息
回复 支持 反对

使用道具 举报

发表于 2025-3-6 23:36:11 | 显示全部楼层
能将Fortran77源代码转换成python代码吗?
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2025-3-6 23:40:17 | 显示全部楼层
girlexplorer 发表于 2025-3-6 23:36
能将Fortran77源代码转换成python代码吗?

肯定可以,这难度不高
回复 支持 反对

使用道具 举报

     
发表于 2025-3-7 00:12:32 | 显示全部楼层
俺提个意见,啊不,建议啊。

现在写代码一般都不用 8 个字符的缩进了,普遍用 4 个字符甚至 2 个字符。
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2025-3-7 00:36:05 | 显示全部楼层
scoopydoo 发表于 2025-3-7 00:12
俺提个意见,啊不,建议啊。

现在写代码一般都不用 8 个字符的缩进了,普遍用 4 个字符甚至 2 个字符。

原文内容是4个空格缩进,论坛自动转了码
回复 支持 反对

使用道具 举报

     
发表于 2025-3-7 07:34:34 | 显示全部楼层
我想找一款LISP解释器,怀念一下约30多年前上人工智能课,在DOS下使用lisp做符号处理的感觉。LISP语言编程,给人另外一种思维,这是我当时的感觉。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2025-4-30 21:20

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表