markdown引入代码_初探代码编译 中篇

前言

----------------------------------------

    上一篇 初探代码编译  -  上篇 简单介绍了编译器的执行过程与原理,

这一篇 来简单的实践一下,考虑到编译器实现的复杂度,这里选择以markdown 文本语言作为对象进行介绍。

正文

-----------------------------------------

1. 什么是 markdown?

定义:

Markdown是一种轻量级标记语言,创始人为约翰·格鲁伯。它允许人们使用易读易写的纯文本格式编写文档,然后转换成有效的XHTML(或者HTML)文档。

由于Markdown的轻量化、易读易写特性,并且对于图片、图表、数学式、代码块都有支持,目前许多网站都广泛使用Markdown来撰写帮助文档或是用于论坛上发表消息。

标准化:

随着时间的推移,Markdown 已经成为典型的转换为HTML的非正式规范和参考实现,出现了许多Markdown实现。人们开发这些主要是由于在基本语法之上需要额外的功能 - 如表格,脚注,定义列表(技术上的HTML描述列表)和HTML块内的Markdown。与此同时,非正式规范中的一些含糊不清引起了人们的注意。这些问题促使Markdown解析器的一些开发人员努力实现标准化。

2016年3月发布了RFC 7763和RFC 7764。RFC 7763 从原始变体引入了MIME类型 text/markdown。RFC 7764讨论并注册了MultiMarkdown、GitHub Flavored Markdown (GFM)、Pandoc、CommonMark及Markdown等变体。

2. markdowm 与 html 的关系

下面列举了 部分 markdown语法 与 html 语法的对应关系

markdown 语法html 语法
# 标题1

标题

## 标题2

标题2

空白行分隔 表示段落

行末尾 两个空格  表示换行 
_斜体_斜体
**粗体**粗体
`代码`代码
---

*  1

*  2

*  3

  • 1
  • 2
  • 3

由于篇幅有限 ,这里先列举这么多语法,其他更多语法可以参考《了不起的Markdown》。

现在已经知道来 markdown 与 html 的语法对应关系出来,那么应该如何实现一个 compiler 编译器(解析器) 去进行语法识别和转换呢 ?

3.  markdowm 词法分析

有了 markdown 的语法标准,就可以进行语法的分析,也就是这里的词法分析,下面以 heading 为例,

首先需要一个 词法解析器,按照 heading 的语法规则 生产出对应的 tokens 序列。

// 词法解析器Class Lexer {   constructor(options) {        this.tokens = [];        this.tokens.links = Object.create(null);        this.options = options || {};        this.rules = {           // heading 匹配规则           heading: /^ {0,3}(#{1,6}) +([^\n]*?)(?: +#+)? *(?:\n+|$)/           // ...        };    }    // 生成 token 序列    token(src) {        while (src) {            // heading            if (cap = this.rules.heading.exec(src)) {                src = src.substring(cap[0].length);                this.tokens.push({                    type: 'heading',                    depth: cap[1].length,                    text: cap[2]                });                continue;            }            // other            // ...        }        return this.tokens;    }}

4. markdown 编译(解析)成 html 

上面已经拿到了 markdown 的 tokens 序列,下面还需要把它按照 html 的语法解析成对应的标签, 如下

// 解析器  - Parsing & Compilingclass Parser {    constructor(options) {        this.tokens = [];        this.token = null;        this.options = options || {};        this.renderer = new Renderer();    }    parse(src) {        this.tokens = src.reverse(); // 先进先出        var out = '';        while (this.next()) {            out += this.tok();        }        return out;    }    next() {        this.token = this.tokens.pop();        return this.token;    }    tok() {        switch (this.token.type) {         // ...        case 'heading': {            return this.renderer.heading(                this.token.text,                this.token.depth            )        }        // ...        }    }}// 渲染器(代码生产器) class Renderer {    constructor(options) {        this.options = options || {};    }    heading(text, level, raw) {        if (this.options.headerIds) {            return '            + level            + ' id="'            + this.options.headerPrefix            + '">'            + text            + '            + level            + '>\n';        }        return ' + level + '>' + text + ' + level + '>\n';    };}

后记

-----------------------------------------

     由于 markdown 是一种标记文本语言,因此这里代码解析转换时候  不需要对其进行 抽象语法树的分析(生成/分析 AST 的环节),相当于只进行了词法分析和代码生成的过程。其编译解析过程相对 图灵完备的语言 较简单。

思考题:

根据 javascript 语法 加减乘除 优先级,是否可以构建一个简单的文法解析器呢?

例如:var a = 1 + 3 *  2;

ps:如有不足 欢迎指正

------------------------------

一只前端小菜鸟  |  求知若渴  |  梦想与爱皆不可辜负

-----------------------------

bab2b42c82699f4f5b30b00027d30c17.png

点个关注   点个在看吧 0423fab183aca4624c712dbbdb1fcda7.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值