前言:
如今咱们对“c语言编程魔法书”可能比较看重,小伙伴们都想要了解一些“c语言编程魔法书”的相关文章。那么小编在网络上网罗了一些关于“c语言编程魔法书””的相关文章,希望各位老铁们能喜欢,姐妹们一起来学习一下吧!诗三百者,一门运行于JVM虚拟机之上,蕴含中国传统文化基因,顺应中文写作习惯,优美雅致、韵味悠长的编程语言。
大家好,欢迎关注极客架构师,极客架构师——专注架构师成长,我是码农老吴。
本节是《架构师基本功之设计模式》第13期-第1节
在第12期,我给大家分享了行为型设计模式中的责任链模式(Chain of Responsibility pattern),基于责任链模式,重构了电商营销活动中,常见的会员资格校验功能。
如下所示,在上期的后续规划中,我给大家许下了豪言壮语……
具体到下一期,我计划给大家分享的是,有点偏门的,有点难度的解释器模式,为了讲解这个设计模式,我想玩个大的,专门设计一个自己的“编程语言”,来配合讲解解释器模式,需要准备的时间可能稍微长一些,大家敬请期待(万一搞不出来,码农老吴丢人就丢出银河系啦)。
结果给自己挖了个坑,一个深不见底的坑。
从国庆前夕,直至10月8号,整整10天时间。我切断所有通讯,关闭所有神识,收回所有位面的分身,进入我的空间法宝“心流塔”中,闭关研发新的编程语言。
“心流塔”被我停泊在银河系边缘的柯伊伯带陨石群中,一旦新的编程语言研发失败,我就驾驶“心流塔”,逃离银河系,向距离银河系最近的,大约200万光年之外的仙女星系进发,找我的仙女去。
国庆期间,由于受太阳风的影响,我的“心流塔”与地球的通讯信号受到影响,没发一篇文章,没录一个视频,没回复一个留言,请大家见谅。
万幸啊,万幸啊,多亏夫子他老人家保佑,终于在10月8号下午,我的第一个开发语言,呱呱落地了。我给她取名为——诗三百。
夫子曰:
诗三百,一言以蔽之,思无邪。
名字的由来
“诗三百”,并非取自妇孺皆知的《唐诗三百首》之名,而是来源于《诗经》。
《诗经》,是我国古代诗歌的源头,传闻是夫子他老人家,汇集了西周至春秋时期的311篇诗歌而成,在先秦时期,称为《诗》,或取其整数称《诗三百》。
其中,对于中国人耳熟能详的“关关雎鸠,在河之洲,窈窕淑女,君子好逑”,即取自《诗经》的第一首诗歌——《周南·关雎》。
关关雎鸠,在河之洲。窈窕淑女,君子好逑。
参差荇菜,左右流之。窈窕淑女,寤寐求之。
求之不得,寤寐思服。悠哉悠哉,辗转反侧。
参差荇菜,左右采之。窈窕淑女,琴瑟友之。
参差荇菜,左右芼之。窈窕淑女,钟鼓乐之。
《诗经》中的诗歌,典故,词语,被后世无数的诗人,词人,文学家,理学家所引用。
取名《诗三百》,寓意天下所有的程序员,编写的代码,都能被当世和后世,无数的程序员引用,能服务于更为广大的人民群众。
处女秀
学习一门新的编程语言,按照行规,一般是编写一个“Hello World”即可。但是,对于“诗三百”语言的处女秀,这样做就有些太Low啦,不能体现出她的优美雅致,韵味十足。
君子,当:
不鸣则已,一鸣惊人;
一出手就要惊艳群芳;
就要有诗仙李太白“笔落惊风雨,诗成泣鬼神”的气势;
就要充满诗情画意,
就要满满的中国风,
就要表现出中国人的文化自信。
不吹啦,不吹啦,再吹夫子他老人家都看不下去啦,君子当讷于言而敏于行,上源代码吧。
源代码
/**《李白、杜甫,你独爱谁?》作者:吴念,开发语言:诗三百**/文字之 诗人;整数之 李白得票数;整数之 杜甫得票数;整数之 投票数;阴阳之 是否继续;是否继续 等于 阳;轮回 ( 是否继续 ) 晚照 书写 : "李白、杜甫,你独爱谁?";阅读 : 诗人; 书写 : "愿为他投票几何?";阅读 : 投票数; 倘若 (诗人 等乎 "李白") 云 书写 : "城边有古树,日夕连秋声。"; 李白得票数 等于 李白得票数 加 投票数; 书写 : "李白得票数:"; 书写 : 李白得票数; 雨 否则 雪 书写 : "笔落惊风雨,诗成泣鬼神。"; 杜甫得票数 等于 杜甫得票数 加 投票数; 书写 : "杜甫得票数:"; 书写 : 杜甫得票数; 风 书写 : "是否继续";阅读 : 是否继续;晴空书写 : "投票结束";
这是源代码呢,一个英文单词都没有,运算符也是中文的,连Java编程中,常见的“{}”都没有。看起来是不是更像一首诗,一篇优美的散文,上面的话可不是吹得哦。
这段代码,是一段给李白和杜甫两位诗人投票的代码,里面包含了变量定义语句,赋值语句,循环语句,条件语句,输入输出函数等等,一个编程语言中,应该具备的基础功能。
大家自己分析分析,应该可以理解的八九不离十,我在后面的视频中,也会详细讲解。
另外,
城边有古树,日夕连秋声。来自李白赠杜甫的一首诗
《沙丘城下寄杜甫》
我来竟何事,高卧沙丘城。
城边有古树,日夕连秋声。
鲁酒不可醉,齐歌空复情。
思君若汶水,浩荡寄南征。
笔落惊风雨,诗成泣鬼神。取自杜甫赞美李白的一首诗
《寄李十二白二十韵》
昔年有狂客,号尔谪仙人。
笔落惊风雨,诗成泣鬼神。
声名从此大,汩没一朝伸。
文彩承殊渥,流传必绝伦。
龙舟移棹晚,兽锦夺袍新。
白日来深殿,青云满后尘。
乞归优诏许,遇我宿心亲。
未负幽栖志,兼全宠辱身。
剧谈怜野逸,嗜酒见天真。
醉舞梁园夜,行歌泗水春。
才高心不展,道屈善无邻。
处士祢衡俊,诸生原宪贫。
稻粱求未足,薏苡谤何频。
五岭炎蒸地,三危放逐臣。
几年遭鵩鸟,独泣向麒麟。
苏武先还汉,黄公岂事秦。
楚筵辞醴日,梁狱上书辰。
已用当时法,谁将此义陈。
老吟秋月下,病起暮江滨。
莫怪恩波隔,乘槎与问津。
抽象语法树(AST,Abstract Syntax Tree)片段
编译器的基本流程:
词法分析阶段:源代码 ->Token
语法分析阶段: Token -> 抽象语法树
解释执行阶段:基于解释器设计模式,解释执行抽象语法树
测试类
package com.geekarchitect.ssb.parser;import junit.framework.TestCase;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.StringReader;public class SSBParserTest extends TestCase { private static final Logger LOG = LoggerFactory.getLogger(SSBParserTest.class); SSBParser ssbParser; public void setUp() throws Exception { super.setUp(); } public void tearDown() throws Exception { } public void testVirginShow(){ String fileContent="文字之 诗人;\n" + "整数之 李白得票数;整数之 杜甫得票数;整数之 投票数;\n" + "阴阳之 是否继续;\n" + "是否继续 等于 阳;\n" + "轮回 ( 是否继续 ) 晚照\n" + " 书写 : \"李白、杜甫,你独爱谁?\";阅读 : 诗人;\n" + " 书写 : \"愿为他投票几何?\";阅读 : 投票数;\n" + "\n" + " 倘若 (诗人 等乎 \"李白\") 云 \n" + " 书写 : \"城边有古树,日夕连秋声。\";\n" + " 李白得票数 等于 李白得票数 加 投票数;\n" + " 书写 : \"李白得票数:\"; \n" + " 书写 : 李白得票数;\n" + " 雨 \n" + " 否则 云 \n" + " 书写 : \"笔落惊风雨,诗成泣鬼神。\";\n" + " 杜甫得票数 等于 杜甫得票数 加 投票数;\n" + " 书写 : \"杜甫得票数:\";\n" + " 书写 : 杜甫得票数;\n" + " 雨\n" + " 书写 : \"是否继续\";阅读 : 是否继续;\n" + "晴空\n" + "书写 : \"投票结束\";"; LOG.info("源代码:\n{}",fileContent); JavaCharStream javaCharStream=new JavaCharStream(new StringReader(fileContent)); SSBParserTokenManager ssbParserTokenManager=new SSBParserTokenManager(javaCharStream); this.ssbParser=new SSBParser(ssbParserTokenManager); try { this.ssbParser.CompilationUnit(); ((SimpleNode)this.ssbParser.jjtree.rootNode()).dump(">"); this.ssbParser.jjtree.rootNode().interpret(); } catch (ParseException e) { e.printStackTrace(); } } }
运行结果语法说明
由于是第一个版本,所以支持的功能还很有限,有待后期的完善。
其实我原本还可以做的更多一些,更好一些。只是……
我的空间法宝“心流塔”,以前是有时间加速功能的,即所谓的“塔中已千年,人间方一日”。可惜,在它陪我与九六魔君(九六魔君,原名九五真君,因在人间历练期间,不幸有一世,做了码农,被九九六法则侵袭,一念成魔)的常年征战中损坏了。本来我和九六魔君实力不相上下,多年的争斗,我只是掉了几根头发而已,奈何,后来九六魔君被某位大能施展了“福报”法则,功力大增,我才棋差一着,败下阵来,导致“心流塔”功能受损,不然,可以给大家提供一个更加完善的“诗三百”。
项目架构技术选型
编译器生成器——JavaCC
“诗三百”编程语言,在编译器生成器的技术选型方面,采用的是Java领域广受欢迎的JavaCC(Java Compiler Compiler)编译器生成器。而业内另外一款著名的,重量级的编译器生成器YACC(Yet Another Compiler Compiler),则侧重C系编程语言的生成,还需要Lex配合,稍显复杂。
官网:
项目类图词法规范(Lexical specification)片段
SKIP : /* WHITE SPACE */{ " "| "\t"| "\n"| "\r"| "\f"}/* RESERVED WORDS AND LITERALS */TOKEN :{ < IF: "\u5018\u82e5" >| < ELSE: "\u5426\u5219" > // else 否则| < WHILE: "\u8f6e\u56de" >// while 轮回| < TRUE: "\u9633" >| < FALSE: "\u9634" >| < READ: "\u9605\u8bfb" >| < WRITE: "\u4e66\u5199" >| < LBRACE: "\u665a\u7167" > // { 晚照| < RBRACE: "\u6674\u7a7a" > // } 晴空| < LBRACE_YUN: "\u4e91" > // { 云| < RBRACE_YU: "\u96e8" > // } 雨| < LBRACE_XUE: "\u96ea" > // { 雪| < RBRACE_FENG: "\u98ce" > // } 风| < PLUS: "\u52a0" > //+ 加| < MINUS: "\u51cf" > //- 减| < ASSIGN: "\u7b49\u4e8e" > // = 等于| < EQ:"\u7b49\u4e4e"> // == 等乎| < GT: "\u5927\u4e4e" > // > 大乎}TOKEN : /* Types */{ < INT: "\u6574\u6570\u4e4b" > | < BOOL: "\u9634\u9633\u4e4b" > | < STRING: "\u6587\u5b57\u4e4b" >}TOKEN : /* LITERALS */{ < INTEGER_LITERAL: (<DIGIT>)+ > | < #DIGIT: [ "0"-"9"] > | < STRING_LITERAL: "\"" ( (~["\"","\\","\n","\r"]) | ("\\" ( ["n","t","b","r","f","\\","'","\""] | ["0"-"7"] ( ["0"-"7"] )? | ["0"-"3"] ["0"-"7"] ["0"-"7"] ) ) )* "\"" >}
语法规范(Syntactic specification)片段
/** Compilation unit. */void CompilationUnit() :{ String name; Token t;}{ ( VarDeclaration() ";" | Statement() )* <EOF>}/** Variable declaration. */void VarDeclaration() :{ Token t; }{ ( "\u9634\u9633\u4e4b" { jjtThis.type = BOOL; } | "\u6574\u6570\u4e4b" { jjtThis.type = INT; } | "\u6587\u5b57\u4e4b" { jjtThis.type = STRING; } ) t = <IDENTIFIER> { jjtThis.name = t.image; }}/** An if statement. */void IfStatement() :{}{ <IF> "(" Expression() ")" Statement() [ LOOKAHEAD(1) <ELSE> Statement() ]}/** A while statement. */void WhileStatement() :{}{ <WHILE> "(" Expression() ")" Statement()}/** An IO statement. */void IOStatement() #void :{ String name; }{ ReadStatement() | WriteStatement()}/** A read statement. */void ReadStatement() :{ Token t; }{ <READ> ":" t = <IDENTIFIER> { jjtThis.name = t.image; }}/** A write statement. */void WriteStatement() :{ Token t; }{ //todo 需要支持变量 <WRITE> ":" Expression()}心中夙愿
从事软件开发行业,已一十八载,一直以来,心有夙愿。
他日若能使用上由中国自主研发设计的,符合中文写作习惯的编程语言,足慰平生。前几年,听说华为已经自研了一套自己的编程语言,并且命名为“仓颉”,还有传言“仓颉”是一套中文的编程语言(后来有人辟谣并非如此),心中甚为欣慰,是否中文开发并不太重要,只要是中国自主产权的即可。
起初,对于中文编程,我是不屑一顾的,用英文多方便。然而夜深人静之时,冷静下来想想,我现在所理解的英文编程的“方便”,是不是只是一种惯性而已。如果软件开发语言,从一开始,就使用中文编写,是不是情况会有所不同。我的文化自信,是不是就是这样,在不知不觉中丧失的。
不知从哪一年开始,汉服热在中国兴起,看到无数的俊男靓女,身着汉服,衣带飘飘,宛如仙人,中国的文化自信油然而生。
近几年,世界一直不太平,全球化进程受到了挑战(惭愧,对于两耳不问窗外事,家里酱油瓶子倒了,都不扶起来的码农,说这些话,我都有些魔幻现实主义了)。由于众所周知的原因,某国被制裁了,某某大帝被制裁了,更可笑的是,制裁的不仅仅是经济,军事,还包括猫,树,芭蕾舞,艺术家,当然还有软件行业。我国的高端芯片行业,也正在被人慢慢的卡紧脖子了。
这些都需要引起我辈的重视,假如有一天,我们中国的软件行业面临同样的境地,github被封了,编程语言被禁了,我们该何去何从。我们这些软件行业的从业者,是不是该干点什么,该提前准备些什么。
然而,我并不是编译器方面的专家,也没有这方面的从业经验,在编译器领域,实属小白一枚。多年前,为了研究JVM的内部原理,顺带学习了一些编译器的知识,所知实在有限。可是,位卑未敢忘忧国,事定犹须待阖棺,即使是一只虫子,也要有看一眼星空的勇气(说不定,就因为这一眼,虫族诞生了,虫族文明崛起了)。
今天,我就斗胆班门弄斧,做个尝试,权当抛砖引玉吧,看看用中文编程,到底是一种什么感觉,同时,也是向华为即将发布的“仓颉”语言致敬,向任正非老爷子致敬,华为的鸿蒙生态,说不定能给中国的软件行业,带来新的契机。
后续规划
正如开篇所说的,我开发“诗三百”编程语言,起因是为了更好的讲解设计模式中的解释器模式,后面的分享,主要精力,还是放在设计模式上。对于“诗三百”这个项目,我在优化完单元测试及文档之后,会发布到github上,大家感兴趣可以看看,手痒的话,还可以一起完善这个项目的功能。
下期,我将结合“诗三百”项目,讲解解释器模式。
极客架构师,专注架构师成长。
关注我,我将持续分享更多架构师的相关文章和视频,我们下期见。
参考文献
《两周自制脚本语言》
《Generating parsers with javacc》
《Compiler construction Using Java Javacc and Yacc》
《诗经选》,人民文学出版社
《唐诗三百首》,中华书局
《笠翁对韵,声律启蒙》,中国文联出版社
标签: #c语言编程魔法书