程序员要如何创建一门编程语言?
旺道朋友圈广告 -> 最新发布

图片

者 | Md Shuvo       译者 | 弯月
出品 | CSDN(ID:CSDNnews)

虽然每位开发人员都掌握了一种甚至多种编程语言,但你是否曾想过自己动手创建一种编程语言?

首先,我们来看看什么是编程语言:

编程语言是用来定义计算机程序的形式语言。它是一种被标准化的交流技巧,用来向计算机发出指令,一种能够让程序员准确地定义计算机所需要使用数据的计算机语言,并精确地定义在不同情况下所应当采取的行动。

简而言之,编程语言就是一组预定义的规则。然后,我们需要通过编译器、解释器等来解释这些规则。所以我们可以简单地定义一些规则,然后,再使用任何现有的编程语言来制作一个可以理解这些规则的程序,也就是我们所说的解释器。

编译器:编译器能够将代码转换为处理器可以执行的机器代码(例如 C++ 编译器)。

解释器:解释器能够逐行遍历程序并执行每个命令。

下面,我们来试试看创建一个超级简单的编程语言,在控制台中输出洋红色的字体,我们给它起个名字:Magenta(洋红色)。

图片


图片

建立编程语言

在本文中,我将使用 Node.js,但你可以使用任何语言,基本思路依然是一样的。首先,我们来创建一个 index.js 文件。

class Magenta {  constructor(codes) {    this.codes = codes  }  run() {    console.log(this.codes)  }} // For now, we are storing codes in a string variable called `codes`// Later, we will read codes from a fileconst codes =`print "hello world"print "hello again"`const magenta = new Magenta(codes)magenta.run()

这段代码声明了一个名为 Magenta 的类。该类定义并初始化了一个对象,而该对象负责将我们通过变量 codes 提供的文本显示到控制台。我们在文件中直接定义了变量 codes:几个带有“hello”的消息。

图片

下面,我们来创建词法分析器。

什么是词法分析器?

我们拿英文举个例子:How are you?

此处,“How”是副词,“are”是动词,“you”是代词。最后还有一个问号(?)。我们可以按照这种方式,通过JavaScript编程将句子或短语划分为多个语法组件。还有一种方法是,将这些句子或短语分割成一个个标记。将文本分割成标记的程序就是词法分析器。

图片

由于我们的这个编程语言非常小,它只有两种类型的标记,每一种只有一个值:

1. keyword

2. string

我们可以使用正则表达式,从字符串 codes 中提取标记,但性能会非常慢。更好的方法是遍历字符串 codes 中的每个字符并提取标记。下面,我们在 Magenta 类中创建一个方法tokenize(这就是我们的词法分析器)。

完整的代码如下:

class Magenta {  constructor(codes) {    this.codes = codes  }  tokenize() {    const length = this.codes.length    // pos keeps track of current position/index    let pos = 0    let tokens = []    const BUILT_IN_KEYWORDS = ["print"]    // allowed characters for variable/keyword    const varChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_'    while (pos < length) {      let currentChar = this.codes[pos]      // if current char is space or newline,  continue      if (currentChar === " " || currentChar === "\n") {        pos++        continue      } else if (currentChar === '"') {        // if current char is " then we have a string        let res = ""        pos++        // while next char is not " or \n and we are not at the end of the code        while (this.codes[pos] !== '"' && this.codes[pos] !== '\n' && pos < length) {          // adding the char to the string          res += this.codes[pos]          pos++        }        // if the loop ended because of the end of the code and we didn't find the closing "        if (this.codes[pos] !== '"') {          return {            error: `Unterminated string`          }        }        pos++        // adding the string to the tokens        tokens.push({          type: "string",          value: res        })      } else if (varChars.includes(currentChar)) {        let res = currentChar        pos++        // while the next char is a valid variable/keyword charater        while (varChars.includes(this.codes[pos]) && pos < length) {          // adding the char to the string          res += this.codes[pos]          pos++        }        // if the keyword is not a built in keyword        if (!BUILT_IN_KEYWORDS.includes(res)) {          return {            error: `Unexpected token ${res}`          }        }        // adding the keyword to the tokens        tokens.push({          type: "keyword",          value: res        })      } else { // we have a invalid character in our code        return {          error: `Unexpected character ${this.codes[pos]}`        }      }    }    // returning the tokens    return {      error: false,      tokens    }  }  run() {    const {      tokens,      error    } = this.tokenize()    if (error) {      console.log(error)      return    }    console.log(tokens)  }}

在终端中运行node index.js,就会看到控制台中输出的标记列表。

图片

图片

定义规则和语法

我们想看看 codes 的顺序是否符合某种规则或语法。但首先我们需要定义这些规则和语法是什么。由于我们的这个编程语言非常小,它只有一种简单的语法,即关键字 print 后跟一个字符串。

keyword:print string

因此,我们来创建一个 parse 方法,循环遍历 codes 并提取标记,看看是否形成了有效的语法,并根据需要采用采取必要的行动。

class Magenta {  constructor(codes) {    this.codes = codes  }  tokenize(){    /* previous codes for tokenizer */  }  parse(tokens){    const len = tokens.length    let pos = 0    while(pos < len) {      const token = tokens[pos]      // if token is a print keyword      if(token.type === "keyword" && token.value === "print") {        // if the next token doesn't exist        if(!tokens[pos + 1]) {          return console.log("Unexpected end of line, expected string")        }        // check if the next token is a string        let isString = tokens[pos + 1].type === "string"        // if the next token is not a string        if(!isString) {          return console.log(`Unexpected token ${tokens[pos + 1].type}, expected string`)        }        // if we reach this point, we have valid syntax        // so we can print the string        console.log('\x1b[35m%s\x1b[0m', tokens[pos + 1].value)        // we add 2 because we also check the token after print keyword        pos += 2      } else{ // if we didn't match any rules        return console.log(`Unexpected token ${token.type}`)      }    }  }  run(){    const {tokens, error} = this.tokenize()    if(error){      console.log(error)      return    }    this.parse(tokens)  }}

如下所示,我们的编程语言已经能够正常工作了!

图片

由于字符串变量 codes 是硬编码的,因此输出其中包含的字符串意义也不大。因此,我们将codes 放入一个名为 code.m 的文件中。这样,变量 codes(输出数据)与编译器的实现逻辑就互相分离了。我们使用 .m 作为文件扩展名,以此来表明该文件包含 Magenta 语言的代码。

下面,我们来修改代码,从该文件中读取codes:

// importing file system moduleconst fs = require('fs')//importing path module for convenient path joiningconst path = require('path')class Magenta{  constructor(codes){    this.codes = codes  }  tokenize(){    /* previous codes for tokenizer */ }  parse(tokens){    /* previous codes for parse method */ }  run(){    /* previous codes for run method */  }} // Reading code.m file// Some text editors use \r\n for new line instead of \n, so we are removing \rconst codes = fs.readFileSync(path.join(__dirname, 'code.m'), 'utf8').toString().replace(/\r/g, "")const magenta = new Magenta(codes)magenta.run()

图片

创建一门编程语言

到这里,我们就成功地从零开始创建了一种微型编程语言。其实,编程语言也可以非常简单。当然,像 Magenta 这样的语言不太可能用于实践,也不足以成为流行框架,但我们可以通过这个例子学习如何创建一门编程语言。

原文地址:https://css-tricks.com/lets-create-a-tiny-programming-language/

— 推荐阅读 —
☞35岁程序员炒Luna代币千万资产3天归零;俄罗斯调查谷歌等科技公司;Linux 5.19加入了50万行图形驱动代码|极客头条
JavaScript持续霸榜、开发者性格大揭秘,调查了19000位开发者有这些发现
万字分析全球 1000 款 DevOps 工具,中国开发工具究竟缺什么?

图片

一键三连 「分享」「点赞」「在看」

成就一亿技术人

教育培训机构-如何策划节日招生?
做教育培训,最重要的事情莫过于招生了。面对不同的学员,招生方…于招生。目标不同,活动策划也会不一样。② 活动主题要鲜明不仅主题要鲜明,主题之间要有连续性。就像看连续剧一样,一集接一集,一环扣一环。策划好一系列活动,一个接一个来,从多个角度延续活动的宣传,突出主题,引起关注度。常用的招生方式有:体验课招…-------------想要获得更多运营技巧、doc文案,
教育培训:如何提高满班率和续班率
什么是满班率?就是实际人数除以计划招生人数,这个值就是满班率…员有流失是正常的,但要保证一个概率。在保障老学员续期的基础上,我们也要大胆创新,开设网络课程,拓宽招生区域。实地课程录制后,进一步发行到商弈云课上,通过商弈云课系统转成真实流量,网上有人点击观看,点赞,可以按点播量分佣金。助你在日常的营销推…-----------------------想要获得更多运
培训机构难盈利的问题出在哪里,如何实现盈利?
竞争白热化实地培训班、托管辅导班竞争白热化了,利润越来越稀薄…现没有多少盈利。还有一部分负责人在刚招生时,掌握了不少资金,开始盲目扩张,盲目做课程推广,以期待获得更多生源和收费,从而使培训班陷入了这种恶性循环的陷阱里。其实这些到手的钱,并不是你的利润,而是你未来要支出的钱。如遇到行业快速发展时期,或者…-----想要获得更多运营技巧、doc文件,请“关注”并“转
“差异化”经营是网络培训赚钱的关键所在
“差异化经营”这个词,相信大多数人都耳熟能详,但要做到的却是…。在现有的基础上更新升级或者资源整合就是对现有的产品或者技术,进行升级版本,或者通过一些资源整合,成一个项目。你的技能以前是用来生产或制造产品,现在是把技能升级成知识培训,转换云课堂。直白一点就是可以让老师自行录好课程并上传到学校的商弈云课…在着缺点和不足之处。在创新改革时,要从功能、服务、价格等方面
教育培训行业是如何运作的?
以前读书时,学校附近有个小摊卖鸡蛋灌饼。刚开始的时候只有一家….%,剩下的一对一和多人大班其实市场份额都很小。家长报培训班,是希望孩子能够学到知识。老师通过课上教学和课后辅导来满足孩子的需求,达到成绩提高的目标。我见过上百人的大培训班,为什么一个班这么多人?因为是名师讲课,但人太多坐后面,基本听不到重…是你的核心竞争力。想要得到用户的认同,你就必须做到产品质量好
旺道:实体店怎么做网络营销?
年纪大了,体力不好了,便赚不了什么钱了。所以,一定要在年轻的…写文案都是非常头痛的事情,那么下面我会给大家提供一个解决方案。在互联网营销系统里面有很多细节营销,软文营销就是其中一种,但好多小白头痛写文章,所以可以用这个方法也一样可以植入广告语,或者是图片广告,轮显切换广告,使用 旺道营销系统,也就是每…以帮你吸引海量精准粉丝。有了粉丝,你通过广告、产品、服务就可
旺道:圈里圈外,铁饭碗距离瓷饭碗究竟有多远?
中国人爱混圈子,从线下一直混到线上,各种奇形怪状的圈子勾勒出…不能推则敷衍了事,盼着混到主任科员退休;一种是老黄牛式,踏踏实实、兢兢业业工作,但拙于人际关系,活干得最多,但依旧不见晋升迹象;还有一种是提线木偶式,你扯一下线他动一下,好像脑子和身体是分离的。我突然一拍脑袋,这是提前衰老的迹象啊,工作内容…即使选择留在铁饭碗圈里,也应保有随时离开的思想警惕和进行必要
旺道:微信要双开了,朋友圈推广更好做了
现在手机只能登一个微信,如两个,三个微信的小伙伴们就只能退出…动推广工具、 设置头像点击头像图标,点“+”选择图片,可以上传你的企业,个人头像,产品服务等。旺道微信朋友圈广告免费朋友圈广告-旺道、 设置推广主题点“广告”,再点“+”设置推广的主题(类别),填好中文主题,以及你的网址。教你不花一分钱做朋…简直就是一劳永逸哟。如果你点开发布的文章看不到广告,那就是你
旺道:如何能让网站多个关键词排名百度首页?
最近接了一个单,做婴儿游泳馆加盟的。优化推广范围是全国,但是…泳馆加盟哪家好”、“婴儿游泳加盟多少钱”这类与我息息相关的词。如何能让网站多个关键词排名百度首页?但客户并不认同,客户说这个词指数低,或者说搜的人不多。是,这是一方面原因。但是,指数低有什么关系,你是卖产品还是卖指数。搜的人不多有什么关系,…实现广告效果最大化,来满足大众化的广告需求。对于这样的四两拔
旺道:如何成为网络营销达人?这个技能帮你节省80%的时间
在某次名师讲坛上,听到了一个让人警醒的故事。说有个村子缺水,…准的产品。现在已经不是新鲜事物,好多企业因为百度竞价的高额费用,头疼不已,所以做网站关键词优化排名,成为了企业必选的推广项目。做优化也要做到有成效,不然就是一分钱也是昂贵的。用 旺道智能机器人 就可以持续代替人工去做,它非常聪明,只要你够耐…手,设备先进,你多努力奔跑也于事无补。简单说,要去一个地方,

此文章来源来互联网,如果你有任何版权冲突,可以联络我们,微信号:WANCOME,QQ:1444641。加我们时,请说明来意,我们将优先处理你的问题。




商弈云推  | 一键推  | 随手推  | 圈推广  | 跨圈推
粤ICP备10213132号
旺道商标注册证号:8608864
Copyright © 2016 环企网络信息科技有限公司 版权所有