Linux C编译器从零开发二

自定义分词器
test.c
#include <ctype.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>typedef enum {TK_PUNCT, // PunctuatorsTK_NUM,   // Numeric literalsTK_EOF,   // End-of-file markers
} TokenKind;// Token type
typedef struct Token Token;
struct Token {TokenKind kind; // Token kindToken *next;    // Next tokenint val;        // If kind is TK_NUM, its valuechar *loc;      // Token locationint len;        // Token length
};// Input string
static char *current_input;// Reports an error and exit.
static void error(char *fmt, ...) {va_list ap;va_start(ap, fmt);vfprintf(stderr, fmt, ap);fprintf(stderr, "\n");exit(1);
}// Reports an error location and exit.
static void verror_at(char *loc, char *fmt, va_list ap) {int pos = loc - current_input;fprintf(stderr, "%s\n", current_input);fprintf(stderr, "%*s", pos, ""); // print pos spaces.fprintf(stderr, "^ ");vfprintf(stderr, fmt, ap);fprintf(stderr, "\n");exit(1);
}static void error_at(char *loc, char *fmt, ...) {va_list ap;va_start(ap, fmt);verror_at(loc, fmt, ap);
}static void error_tok(Token *tok, char *fmt, ...) {va_list ap;va_start(ap, fmt);verror_at(tok->loc, fmt, ap);
}// Consumes the current token if it matches `s`.
static bool equal(Token *tok, char *op) {return memcmp(tok->loc, op, tok->len) == 0 && op[tok->len] == '\0';
}// Ensure that the current token is `s`.
static Token *skip(Token *tok, char *s) {if (!equal(tok, s))error_tok(tok, "expected '%s'", s);return tok->next;
}// Ensure that the current token is TK_NUM.
static int get_number(Token *tok) {if (tok->kind != TK_NUM)error_tok(tok, "expected a number");return tok->val;
}// Create a new token.
static Token *new_token(TokenKind kind, char *start, char *end) {Token *tok = calloc(1, sizeof(Token));tok->kind = kind;tok->loc = start;tok->len = end - start;return tok;
}// Tokenize `current_input` and returns new tokens.
static Token *tokenize(void) {char *p = current_input;Token head = {};Token *cur = &head;while (*p) {// Skip whitespace characters.if (isspace(*p)) {p++;continue;}// Numeric literalif (isdigit(*p)) {cur = cur->next = new_token(TK_NUM, p, p);char *q = p;cur->val = strtoul(p, &p, 10);cur->len = p - q;continue;}// Punctuatorif (*p == '+' || *p == '-') {cur = cur->next = new_token(TK_PUNCT, p, p + 1);p++;continue;}error_at(p, "invalid token");}cur = cur->next = new_token(TK_EOF, p, p);return head.next;
}int main(int argc, char **argv) {if (argc != 2)error("%s: invalid number of arguments", argv[0]);current_input = argv[1];Token *tok = tokenize();printf("  .globl main\n");printf("main:\n");// The first token must be a numberprintf("  mov $%d, %%rax\n", get_number(tok));tok = tok->next;// ... followed by either `+ <number>` or `- <number>`.while (tok->kind != TK_EOF) {if (equal(tok, "+")) {printf("  add $%d, %%rax\n", get_number(tok->next));tok = tok->next->next;continue;}tok = skip(tok, "-");printf("  sub $%d, %%rax\n", get_number(tok));tok = tok->next;}printf("  ret\n");return 0;
}
 编译
cc -o test test.c
./test "1 +2  +3"  > tmp.s
cc -o tmp tmp.s
./tmp
echo $?
错误处理

./test "1 + 2 * +3"  > tmp.s
1 + 2 * +3
      ^ invalid token


创作不易,小小的支持一下吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/27940.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于carsim的线控转向仿真(1)--carsim车辆模型目标角度跟踪

一、Rwa转向执行总成建模 Rwa包括齿轮齿条机构、转向组件以及转向执行电机&#xff1b;如下图&#xff0c;电机输出轴通过齿轮减速增扭后&#xff0c;再经过一个半径为rp的小齿轮&#xff0c;直接带动齿条左右移动。齿条的移动通过转向摇臂&#xff0c;带动车轮转动&#xff0c…

使用 Apache SkyWalking 进行 Spring Cloud 应用的分布式追踪与监控:完整教程

使用 Apache SkyWalking 进行 Spring Cloud 应用的分布式追踪与监控&#xff1a;完整教程 SkyWalking 是一款开源的分布式追踪、性能监控和诊断平台&#xff0c;适用于微服务、云原生和容器化应用。它能够在分布式系统中收集和分析各个服务之间的调用关系和性能数据&#xff0…

PySide(PyQt)实现鼠标画框局部放大

按住鼠标左键画框&#xff0c;裁切画面并局部放大&#xff0c;可以用来生成ROI 1、在QtDesigner中创建ui文件&#xff0c;命名为crop.ui&#xff1a; 2、自定义脚本ImageLabel.py &#xff1a; from PySide6.QtCore import Qt, QRect, Signal, QPoint from PySide6.QtGui impo…

Redis高并发高可用

1. 复制机制 在分布式系统中&#xff0c;为了解决单点问题&#xff0c;通常会将数据复制多个副本部署到其他机器&#xff0c;以满足故障恢复和负载均衡等需求。Redis提供了复制功能&#xff0c;实现了相同数据的多个Redis副本。复制功能是高可用Redis的基础&#xff0c;后面的…

Unity 6预览版即将增加对visionOS 2的支持

Unity表示&#xff0c;届时将能帮助你创建更为身临其境的体验&#xff0c;并通过以下主要功能实现更大的视觉多样性&#xff1a; 支持混合形状&#xff0c;以实现更广泛的几何应用&#xff0c;包括变形和平滑&#xff0c;自然的动画。 立体渲染目标&#xff0c;帮助用户实现广…

长亭网络通信基础

长亭笔试之前就已经学过一遍了 这算温故而知新吧 TCP/IP 首先我在这里默写一下之前的7层和4层 应用层 应 【表示层 数据格式转换 传 【会话层 …

Vue 3 的常用响应式 API 总结

在vue3.x版本中&#xff0c;setup函数就是vue3 组合式API的入口&#xff0c;换句话说就是在setup中的写的代码&#xff0c;就是组合式API 的写法。下面总结常用的与响应式相关的api, 帮助您在 Vue 3 中创建响应式应用程序。 reactive() 和 ref()&#xff1a; 创建响应式对象和…

课设--学生成绩管理系统(一)

欢迎来到 Papicatch的博客 文章目录 &#x1f349;技术核心 &#x1f349;引言 &#x1f348;标识 &#x1f348;背景 &#x1f348;项目概述 &#x1f348; 文档概述 &#x1f349;可行性分析的前提 &#x1f348;项目的要求 &#x1f348;项目的目标 &#x1f348;…

Android 蓝牙配对Settings应用里面的简要流程记录

Android 蓝牙配对Settings应用里面的简要流程记录 文章目录 Android 蓝牙配对Settings应用里面的简要流程记录一、前言二、Settings蓝牙配对的关键代码1、接收蓝牙请求的地方 AndroidManifest.xml2、BluetoothPairingRequest3、BluetoothPairingService4、BluetoothPairingDial…

神经网络-文本-图像-音频-视频基础知识

文本、图像、音频和视频是数字媒体中的四种基本类型&#xff0c;它们各有不同的组成、单位和基础知识。下面我将逐一解释&#xff1a; 文本 组成&#xff1a;文本由字符组成&#xff0c;可以表示字母、数字、标点符号、特殊字符等。单位&#xff1a;文本的单位通常是字符&#…

宿舍用电管理模块一进三出的升级改造

宿舍用电管理模块一进三出石家庄光大远通电气有限公司产品在高校日常管理工作中,宿舍管理是一项重要工作。宿舍管理内容复杂,而且涉及学生的日常生活,意义重大。其中,学生宿舍内漏电,超负荷用电,违规用电等现象一直是困扰后勤管理的普遍问题。随着学生日常生活方式以及生活用品…

驱动开发(五):Linux内核定时器

驱动开发系列文章&#xff1a; 驱动开发&#xff08;一&#xff09;&#xff1a;驱动代码的基本框架 驱动开发&#xff08;二&#xff09;&#xff1a;创建字符设备驱动 驱动开发&#xff08;三&#xff09;&#xff1a;内核层控制硬件层 驱动开发&#xff08;四&#xff…

移动端超超超详细知识点总结(Part4)

rem基础 1. rem单位 rem (root em)是一个相对单位&#xff0c;类似于em&#xff0c;em是父元素字体大小。不同的是rem的基准是相对于html元素的字体大小。比如&#xff0c;根元素&#xff08;html&#xff09;设置font-size12px; 非根元素设置width:2rem;则换成px表示就是24p…

数据防泄漏的六个步骤|数据防泄漏软件有哪些

在当前复杂多变的网络安全环境下&#xff0c;数据防泄漏软件成为了企业信息安全架构中不可或缺的一环。下面以安企神软件为例&#xff0c;告诉你怎么防止数据泄露&#xff0c;以及好用的防泄露软件。 1. 安企神软件 安企神软件是当前市场上备受推崇的企业级数据防泄漏解决方案…

CPU中的寄存器CPU能理解的指令(指令集)

CPU中的寄存器 寄存器有很多种。如指令寄存器&#xff0c;专门存储指令 问&#xff1a;CPU的寄存器存的是什么? 答&#xff1a;CPU寄存器是中央处理器&#xff08;CPU&#xff09;内部的一小部分高速存储资源&#xff0c;用于快速访问和存储各种类型的数据和信息。以下是CPU…

Nvidia TensorRT系列01-TensorRT的功能1

Nvidia TensorRT系列01-TensorRT的功能1 B站&#xff1a;肆十二-的个人空间-肆十二-个人主页-哔哩哔哩视频 (bilibili.com) 博客&#xff1a;肆十二-CSDN博客 问答&#xff1a;(10 封私信 / 72 条消息) 肆十二 - 知乎 (zhihu.com) C和Python API TensorRT的API同时支持C和Pyth…

【网络协议栈】TCP/IP相关知识点收集

TCP/IP知识点收集 1 TCP分段 在TCP/IP协议栈中&#xff0c;“MSS”&#xff08;Maximum Segment Size&#xff09;是一个关键参数&#xff0c;它指定了TCP协议在发送数据时可以使用的最大数据段&#xff08;segment&#xff09;的大小。这个参数是TCP连接建立时通过三次握手&…

web前端任职条件:全面解析

web前端任职条件&#xff1a;全面解析 在当今数字化快速发展的时代&#xff0c;Web前端技术已经成为互联网行业不可或缺的一部分。作为一名Web前端开发者&#xff0c;需要具备哪些任职条件呢&#xff1f;本文将从四个方面、五个方面、六个方面和七个方面为您深入剖析。 四个方…

【ARM-Linux篇】智能家居语音模块配置

1. pin脚配置&#xff1a; 2. 命令词自定义基本信息&#xff1a; 3. 命令词自定控制详情: • 测试&#xff1a;串口模块可先通过串口助手验证每个指令的准确性&#xff0c; 然后运行wiringOP中的serialTest程序(需把/dev/ttyS2改成/dev/ttyS5) 然后语音接收到指令后(比如喊你好…

Ionic 复选框:实现与应用详解

Ionic 复选框&#xff1a;实现与应用详解 Ionic 是一个强大的开源框架&#xff0c;用于构建高性能、高质量的移动和网页应用程序。它结合了 Angular 的强大功能和 Cordova 的设备访问能力&#xff0c;使得开发者能够轻松地创建跨平台的应用程序。在 Ionic 应用中&#xff0c;复…