不积小流,无以成江海
结构的悖论

The paradox of structure is that, whatever its nature, any structure is both enabling and limiting at the same time.

每一种结构既会赋予能力,同时又会限制能力。最近在网易公开课看了这节 结构的悖论,是宾夕法尼亚大学的公开课《创造、创新和改变》中的一节。这里的结构可以代指任何事物,例如法律,例如公司的制度,我们应该如何对待生活中的结构呢?

写一个 Mustache 模板引擎

前几天在伯乐在线上看到 介绍 mustache.js 的文章Mustache 是一种模板语言,语法简单,功能强大,已经有各个语言下的实现。那么我们今天就用 python 来一步步实现它吧!

Hexo 自动部署到 Github

使用 Hexo 写博客是十分惬意的事。唯一有点不爽的,就是每次修改后都要重新生成并部署到 Github 上,这也是所有静态博客生成工具的通病。那么本文我们就利用 Travis CI 来完成自动部署,解决心中最后一处搔痒。

手把手教你构建 C 语言编译器(9)- 总结

恭喜你完成了自己的 C 语言编译器,本章中我们发一发牢骚,说一说编写编译器值得注意的一些问题;编写编译器时遇到的一些难题。

手把手教你构建 C 语言编译器(8)- 表达式

这是整个编译器的最后一部分,解析表达式。什么是表达式?表达式是将各种语言要素的一个组合,用来求值。例如:函数调用、变量赋值、运算符运算等等。

表达式的解析难点有二:一是运算符的优先级问题,二是如何将表达式编译成目标代码。我们就来逐一说明。

手把手教你构建 C 语言编译器(7)- 语句

整个编译器还剩下最后两个部分:语句和表达式的解析。它们的内容比较多,主要涉及如何将语句和表达式编译成汇编代码。这章讲解语句的解析,相对于表达式来说它还是较为容易的。

手把手教你构建 C 语言编译器(6)- 函数定义

由于语法分析本身比较复杂,所以我们将它拆分成 3 个部分进行讲解,分别是:变量定义、函数定义、表达式。本章讲解函数定义相关的内容。

手把手教你构建 C 语言编译器(5)- 变量定义

本章中我们用 EBNF 来大致描述我们实现的 C 语言的文法,并实现其中解析变量定义部分。

由于语法分析本身比较复杂,所以我们将它拆分成 3 个部分进行讲解,分别是:变量定义、函数定义、表达式。

手把手教你构建 C 语言编译器(4)- 递归下降

本章我们将讲解递归下降的方法,并用它完成一个基本的四则运算的语法分析器。

手把手教你构建 C 语言编译器(3)- 词法分析器

本章我们要讲解如何构建词法分析器。

手把手教你构建 C 语言编译器(2)- 虚拟机

这是“手把手教你构建 C 语言编译器”系列的第三篇,本章我们要构建一台虚拟的电脑,设计我们自己的指令集,运行我们的指令集,说得通俗一点就是自己实现一套汇编语言。它们将作为我们的编译器最终输出的目标代码。

手把手教你构建 C 语言编译器(1)- 设计

这是“手把手教你构建 C 语言编译器”系列的第二篇,我们要从整体上讲解如何设计我们的 C 语言编译器。

手把手教你构建 C 语言编译器(0)- 前言

“手把手教你构建 C 语言编译器” 这一系列教程将带你从头编写一个 C 语言的编译器。希望通过这个系列,我们能对编译器的构建有一定的了解,同时,我们也将构建出一个能用的 C 语言编译器,尽管有许多语法并不支持。

Vim 小技巧——合并行块

看教程时,自己动手输入教程的例子有助于学习和理解。但有时会发现自己输入的代码跑不通,而粘贴的代码是正确的。这时我们希望能一行行地对比自己输入的代码和原始代码。用 Vim 怎么做到呢?

Vim 小技巧-删除行末空格

在编写代码时,我们时常一不留神就在行末多打了几个空格。却又看不出来,即使用 vim-airline 之类的插件能知道有行末空格(trailing spaces),删除起来也特别麻烦。本文就介绍一个我就常用的 vim 快捷键:删除行末空格。