Skip to content

2022

C++实现解释器(5): 功能扩展

参照《Writing An Interpreter/Compiler In Go》,改用C++实现。

项目源码: https://github.com/LeslieZhu/monkey-cpp

引言

本篇对应的源码位于目录: src/04/

04
 |token
 | |token.hpp
 |evaluator
 | |evaluator.hpp
 | |builtins.hpp
 |CMakeLists.txt
 |test
 | |lexer_test.hpp
 | |parser_test.hpp
 | |evaluator_test.hpp
 | |objects_test.hpp
 | |ast_test.hpp
 | |main.cpp
 |lexer
 | |lexer.hpp
 |repl
 | |repl.hpp
 |objects
 | |objects.hpp
 | |environment.hpp
 |parser
 | |parser.hpp
 | |parser_tracing.hpp
 |ast
 | |ast.hpp
 |main
 | |monkey.cpp

这篇主要在现有框架上扩展一些功能:

  • 字符串
  • 内置函数: len,first,rest,push,puts
  • 数组
  • 字典或哈希表
  • 索引表达式

C++实现解释器(4):求值

参照《Writing An Interpreter/Compiler In Go》,改用C++实现。

项目源码: https://github.com/LeslieZhu/monkey-cpp

引言

本篇对应的源码位于目录: src/03/

03
 |token
 | |token.hpp
 |evaluator
 | |evaluator.hpp
 |CMakeLists.txt
 |test
 | |lexer_test.hpp
 | |parser_test.hpp
 | |evaluator_test.hpp
 | |ast_test.hpp
 | |main.cpp
 |lexer
 | |lexer.hpp
 |repl
 | |repl.hpp
 |objects
 | |objects.hpp
 | |environment.hpp
 |parser
 | |parser.hpp
 | |parser_tracing.hpp
 |ast
 | |ast.hpp
 |main
 | |monkey.cpp

求值(Evaluation)是解释器处理源代码过程的最后一步,求值过程决定了一门编程语言的解释方式。

C++实现解释器(3):语法分析与普拉特解析

参照《Writing An Interpreter/Compiler In Go》,改用C++实现。

项目源码: https://github.com/LeslieZhu/monkey-cpp

引言

本篇对应的源码位于目录: src/02/

02
 |token
 | |token.hpp
 |CMakeLists.txt
 |test
 | |lexer_test.hpp
 | |parser_test.hpp
 | |ast_test.hpp
 | |main.cpp
 |lexer
 | |lexer.hpp
 |repl
 | |repl.hpp
 |parser
 | |parser.hpp
 | |parser_tracing.hpp
 |ast
 | |ast.hpp
 |main
 | |monkey.cpp

语法分析器将输入的内容转换为对应的数据结构,具体就是将词法分析器得到的一系列词法Token转换为对应的数据结构,形成抽象语法树(AST)

使用yaccbisonANTLR等语法分析器生成器工具,可以根据BNF或EBNF形式描述的语法构成,自动生成语法分析器。为了理解语法分析器的工作原理,不使用这些工具。

这里准备编写的语法分析器是递归下降语法分析器,具体就是基于自上而下的运算符优先级分析法,其发明人是普拉特,又称普拉特语法分析器

Docker镜像里为什么Linux无法安装Man Pages?

引言

Man Pages是Linux系统常用的在线文档手册。

常说在Linux里不需要记住软件命令的用法,只要会找男人就行了,指的就是查看这个man pages文档。

Docker是比较常用的容器,常用于部署应用或作为开发环境,但一般的Docker镜像为了减少体积,不会带有Man Pages文档手册。

有时候哪怕按照一般的做法使用yum安装了man-pages软件包,发现还是没有按预期安装文档,这是怎么回事呢?

Linux如何通过PAM管理授权?

引言

https://github.com/linux-pam/linux-pam

PAM指的是Pluggable Authentication Modules,以可插拔模块的形式来帮助Linux管理系统的授权。

PAM将系统授权相关的逻辑功能做成共享链接库(/usr/lib64/security/)的形式,然后其他需要授权操作的程序只需要调用这个共享库即可。

对于管理员来说,正确的设置复杂授权等工作就变成了一个简单的管理配置文件的工作了。

Linux如何设置用户长时间不操作就自动登出?

引言

当我们登录Linux系统后,如果长时间不操作,比如忘记关闭终端窗口了,怎么做到用户自动退出登录呢?

$ ls -l /etc/profile
-rw-r--r-- 1 root root 1819 Apr  1  2020 /etc/profile

这个文件是系统环境变量的配置文件,并且只有root有修改权限;如果能够在这个文件里面做一些设置,那么每个用户登录后都会加载里面的配置。

C++疑难杂症(1): 小心std::variant中的bool类型值

引言

比如有这样一段代码:

#include <iostream>
#include <string>
#include <variant>
#include <cassert>

int main(){

  std::variant<std::string, int ,bool, long long int> value{"y"};

  if(std::holds_alternative<std::string>(value)){
    std::cout << "it's  a std::string: " << std::get<std::string>(value) << std::endl;
  }else if (value.index() == 0){
    std::cout << "it's a string: " << std::get<std::string>(value) << std::endl;
  }else if (value.index() == 1){
    std::cout << "it's a int: " << std::get<int>(value) << std::endl;
 }else if (value.index() == 2){
    std::cout << "it's a bool: " << std::get<bool>(value) << std::endl;
  }
}

C++实现解释器(2): 词法分析

参照《Writing An Interpreter/Compiler In Go》,改用C++实现。

项目源码: https://github.com/LeslieZhu/monkey-cpp

引言

本篇对应的源码位于目录: src/01/

src
 |01
 | |token
 | | |token.hpp
 | |CMakeLists.txt
 | |test
 | | |main.cpp
 | | |lexer_test.cpp
 | |lexer
 | | |lexer.hpp
 | |repl
 | | |repl.hpp

将源代码转换为词法单元,这个过程叫词法分析,完成这个过程的叫词法分析器(tokenizer/scanner)

C++实现解释器(1): 开篇

参照《Writing An Interpreter/Compiler In Go》,改用C++实现。

项目源码: https://github.com/LeslieZhu/monkey-cpp

引言

实现解释器有很多教程,看了这个基于Go语言的版本后,将采用C++17来重新实现一遍,以体验两种不同编程语言的风格差异。

将采用测试驱动开发(TDD)形式,先写测试用例,再实现代码。

使用的是来自谷歌的gtest(GoogleTest)开源测试框架。