学了编译原理能否用 Java 写一个编译器或解释器?

16 个回答

默认排序?

RednaxelaFX

JavaScript编译原理编程 等 7 个话题的优秀回答者

282 人赞同了该回答

能。我一开始学编译原理的时候就是用Java写了好多小编译器和解释器。其实用什么语言来实现编译器并不是最重要的部分(虽然Java也不是实现编译器最方便的语言),最初用啥语言都可以。

我在大学的时候,我们的软件工程和计算机科学的编译原理课的作业好像都是可以用Java来写的。反正我印象中我给这两门课写的作业都是用的Java。

================================================

关于书

用Java写编译器/解释器的话题主可以试试从ANTLR的作者Terence Parr所写的《Language Implementation Patterns》开始读,跟着它做实验。如果是一开始对编译原理还没啥头绪、而又已经对Java的使用比较熟悉的话,跟着这本书做实验会能学习到不少知识面。不过要把这些知识点都学习扎实了的话还是得进一步读别的书。

我推荐的书单里《自制编译器》那本书的类C语言编译器也是用Java实现的:学习编程语言与编译优化的一个书单。以这本为第一本书也行。侧重点跟上面那本不太一样。

其它用Java作为范例实现语言的编译原理书还有若干,例如正统系编译原理教材:

不过比起上面那些,我还是更推荐EAC2作为学习编译原理的“第二本书”:
Engineering a Compiler》Second Edition

================================================

关于现有的实现

其实现实生活中大家用得多的、用Java写的编译器还真不少。也举几个例子吧。

教学用编译器

偏重学术研究的用Java实现的编译器 / 编译器框架:

在实际产品中用Java实现的编译器 / 解释器:

  • javac [Oracle/Sun]
  • ECJ: Eclipse Compiler for Java [Eclipse]
  • Groovy
  • JRuby
  • Jython
  • Nashorn [Oracle]
  • Rhino [Mozilla]
  • DynJS
  • Graal [Oracle]
  • RoboVM
  • asc: ActionScript 3 Compiler [Adobe]
  • GWT [Google]
  • Google Closure Compiler [Google]
  • Quercus [Caucho]
  • …同样,还有很多,暂时列举这么多

比较简易/玩具性质的:

正则表达式库:

词法/语法分析器生成器(parser generator):

  • ANTLR
  • JavaCC
  • Jay
  • CUP
  • JLex
  • JMeta

汇编器库:

编辑于 2016-07-29

?赞同 282??17 条评论

?分享

?收藏?感谢收起?

知乎用户

62 人赞同了该回答

2016.2.12更新:
其实仅仅是一个玩具级的编译器前端,并没有太高的技术含量,本人菜鸟一枚,并非大神^_^
这两天整理了一下源码,已发布到Github,有兴趣的同学欢迎关注^_^
源码链接:GitHub - kasonyang/kalang: A toy compiler front-end

-----------------以下原回答-----------------------

大赞

@RednaxelaFX

的回答。

最近用java折腾了一个类java的编译器前端,说说本人的思路:

词法语法分析->构建抽象语法树(AST)->类型检查->生成目标代码

1. 首先,第一步是词法语法分析,这一块我采用的是antlr。antlr项目里有很多语言的文法实现可供参考:GitHub - antlr/grammars-v4: Grammars written for ANTLR v4; expectation that the grammars are free of actions.

2. 语法分析后,接下来就是构建抽象语法树。这一步就是将parser(由antlr生成)的输出(ParseTree)进行进一步的处理,得到AST,以便更好的对语法进行分析,同时可以对语法树就行标志或者转换等操作。在构建语法树的过程中,可以对ParseTree和AST进行映射,这样对AST进行分析时如果有任何问题可以由AST反推回去ParseTree,以便定位错误的位置。

3. 得到抽象语法树后,如果你的编译器是静态类型安全的,那么还需要对语法树进行类型检查,在做类型检查的时候可以顺便把语法糖处理了,比如说Integer i=3,这个赋值是类型不匹配的,你需要将其转换为:Integer i=new Integer(3),这样就类型匹配了。

4. 类型检查完后,就可以生成目标代码了。目标代码可以生成本地的二进制代码,也可以生成java的字节码,甚至可以生成另一种高级语言的表示。刚开始时我是直接生成java的class二进制文件的,后来发现因为自己在这方面没什么经验,生成的代码老是有各种问题,每次出问题调试起来非常费劲,有好几次找bug找半天没找出来,信心大受打击,直接想放弃了。后来痛定思痛,把直接生成class文件的功能暂时先砍掉了,而是生成另一种高级语言java的表示,这样有什么bug,找起来就方便多了。

编译写完后,总觉得还缺点什么,然后我又给自己的语言写了个IDE插件。

编辑于 2016-02-12

?赞同 62??11 条评论

?分享

?收藏?感谢收起?

冒泡

IT为主,兴趣广泛,爱好强答

跟语言没关系,原则上你用什么语言都能搞,只是麻不麻烦,是否有必要的区别了

发布于 2016-01-26

?赞同??添加评论

?分享

?收藏?感谢

Belleve

编程 话题的优秀回答者

6 人赞同了该回答

咦,龙书最后不就附带了一个 java 写的吗?

发布于 2016-02-11

?赞同 6??1 条评论

?分享

?收藏?感谢

王召德

严于律己,宽以待人

12 人赞同了该回答

当然可以啦,编译原理课的实验就是用Java实现一个PL/0语言的编译器,感觉比C语言实现起来要简单,毕竟Java可用的方法比较多嘛
建议你也可以试试写一下PL/0语言的编译器,原因是比较简单容易入手而且自顶向下的PL/0编译器的实现网上有很多资料
下面是题目要求:

Pl/0语言文法的BNF表示:
<字母> → a|b|c…x|y|z
 <数字> → 0|1|2…7|8|9
 <无符号整数> → <数字>{<数字>}
<标识符> → <字母>{<字母>|<数字>}
1.A→B.
〈程序〉→〈分程序>.
2.B→CEFH|H|CH|EH|FH|CFH|CEH|EFH
〈分程序〉→ [<常量说明部分>][<变量说明部分>][<过程说明部分>]〈语句〉 3.C→CD;|c
<常量说明部分> → CONST<常量定义>{ ,<常量定义>};
4.D→b=a
<常量定义> → <标识符>=<无符号整数>
5.E→Eb;|d
<变量说明部分> → VAR<标识符>{ ,<标识符>};
6.F→GB;F
<过程说明部分> → <过程首部><分程序>;{<过程说明部分>}
7.G→eb;
<过程首部> → procedure<标识符>;
8.H→I|R|T|S|U|V|J|ε
<语句> → <赋值语句>|<条件语句>|<当型循环语句>|<过程调用语句>|<读语句>|<写语句>|<复合语句>|<空>
9.I→b:=L
<赋值语句> → <标识符>:=<表达式>
10.J→fWg
<复合语句> → begin<一个或多个语句><end>
11.K→LQL|hL
<条件> → <表达式><关系运算符><表达式>|ood<表达式>
12.L→LOM|M|-M|+M
<表达式> → [+|-]<项>{<加减运算符><项>}
13.M→MPN|N
<项> → <因子>{<乘除运算符><因子>}
14.N→b|a|(L)
<因子> → <标识符>|<无符号整数>|(<表达式>)
15.O→+|-
<加减运算符> → +|-
16.P→*|/
<乘除运算符> → *|/
17.Q→=|#|<|<=|>|>=
<关系运算符> → =|#|<|<=|>|>=
18.R→pKqH
<条件语句> → if<条件>then<语句>

19.S→mb
<过程调用语句> → call<标识符>
20.T→nKoH
<当型循环语句> → while<条件>do<语句>
21.U→i(X)
<读语句> → read(<一个或多个标识符>)
22.V→j(X)
<写语句> → write(<一个或多个标识符>)
23.W→W;H|H
 <一个或多个语句>→<语句>{ ;<语句>}
 24.X→X,b|b
 <一个或多个标识符>→<标识符>{,<标识符>}
一.	为PL/0语言建立一个词法分程序GETSYM(函数)
把关键字、算符、界符称为语言固有的单词,标识符、常量称为用户自定义的单词。为此设置三个全程量:SYM,ID,NUM 。
 SYM:存放每个单词的类别,为内部编码的表示形式。
 ID:存放用户所定义的标识符的值,即标识符字符串的机内表示。
 NUM:存放用户定义的数。
 GETSYM要完成的任务:
1.	滤掉单词间的空格。
2.	识别关键字,用查关键字表的方法识别。当单词是关键字时,将对应的类别放在SYM中。如IF的类别为IFSYM,THEN的类别为THENSYM。
3.	识别标识符,标识符的类别为IDENT,IDRNT放在SYM中,标识符本身的值放在ID中。关键字或标识符的最大长度是10。
4.	拼数,将数的类别NUMBER放在SYM中,数本身的值放在NUM中。
5.	拼由两个字符组成的运算符,如:>=、<=等等,识别后将类别存放在SYM中。
6.	打印源程序,边读入字符边打印。
由于一个单词是由一个或多个字符组成的,所以在词法分析程序GETSYM中定义一个读字符过程GETCH。
二.	为PL/0语言建立一个语法分析程序BLOCK(函数)
PL/0编译程序采用一遍扫描的方法,所以语法分析和代码生成都有在BLOCK中完成。BLOCK的工作分为两步:
a)	说明部分的处理
说明部分的处理任务就是对每个过程(包括主程序,可以看成是一个主过程)的说明对象造名字表。填写所在层次(主程序是0层,在主程序中定义的过程是1层,随着嵌套的深度增加而层次数增大。PL/0最多允许3层),标识符的属性和分配的相对地址等。标识符的属性不同则填写的信息不同。
所造的表放在全程量一维数组TABLE中,TX为指针,数组元素为结构体类型数据。LEV给出层次,DX给出每层的局部量的相对地址,每说明完一个变量后DX加1。
例如:一个过程的说明部分为:
  const a=35,b=49;
  var c,d,e;
  procedure p;
var g;
对它的常量、变量和过程说明处理后,TABLE表中的信息如下:

NAME: a
NAME: b
NAME: c
NAME: d
NAME: e
NAME: p	KIND: CONSTANT
KIND: CONSTANT
KIND: VARIABLE
KIND: VARIABLE
KIND: VAEIABLE
KIND: PROCEDURE	VAL: 35
VAL: 49
LEVEL: LEV
LEVEL: LEV
LEVEL: LEV
LEVEL: LEV	

ADR: DX
ADR: DX+1
ADR: DX+2
ADR:
NAME: g
。
。
。	KIND: VARIABLE
        。
        。
        。	LEVEL: LEV+1
。
。
。	ADR: DX
。
。
     。
对于过程名的ADR域,是在过程体的目标代码生成后返填过程体的入口地址。
TABLE表的索引TX和层次单元LEV都是以BLOCK的参数形式出现,在主程序调用BLOCK时实参的值为0。每个过程的相对起始位置在BLOCK内置初值DX=3。
2.语句处理和代码生成
对语句逐句分析,语法正确则生目标代码,当遇到标识符的引用则去查TABLE表,看是否有过正确的定义,若有则从表中取出相关的信息,供代码生成用。PL/0语言的代码生成是由过程GEN完成。GEN过程有三个参数,分别代表目标代码的功能码、层差、和位移量。生成的目标代码放在数组CODE中。CODE是一维数组,数组元素是结构体类型数据。
PL/0语言的目标指令是一种假想的栈式计算机的汇编语言,其格式如下:

其中f代表功能码,l代表层次差,a代表位移量。
目标指令有8条:
① LIT:将常数放到运栈顶,a域为常数。
② LOD:将变量放到栈顶。a域为变量在所说明层中的相对位置,l为调用层与说明层的层差值。
③ STO:将栈顶的内容送到某变量单元中。a,l域的含义与LOD的相同。
④ CAL:调用过程的指令。a为被调用过程的目标程序的入中地址,l为层差。
⑤ INT:为被调用的过程(或主程序)在运行栈中开辟数据区。a域为开辟的个数。
⑥ JMP:无条件转移指令,a为转向地址。
⑦ JPC:条件转移指令,当栈顶的布尔值为非真时,转向a域的地址,否则顺序执行。
⑧ OPR:关系和算术运算。具体操作由a域给出。运算对象为栈顶和次顶的内容进行运算,结果存放在次顶。a域为0时是退出数据区。
三.	建立一个解释执行目标程序的函数
编译结束后,记录源程序中标识符的TABLE表已退出内存,内存中只剩下用于存放目标程序的CODE数组和运行时的数据区S。S是由解释程序定义的一维整型数组。解释执行时的数据空间S为栈式计算机的存储空间。遵循后进先出的规则,对每个过程(包括主程序)当被调用时,才分配数据空间,退出过程时,则所分配的数据空间被释放。
为解释程序定义四个寄存器:
1.	I:指令寄存器,存放当前正在解释的一条目标指令。
2.	P:程序地址寄存器,指向下一条要执行的目标指令(相当于CODE数组的下标)。
3.	T:栈顶寄存器,每个过程运行时要为它分配数据区(或称为数据   段),该数据区分为两部分。
静态部分:包括变量存放区和三个联单元。
动态部分:作为临时工作单元和累加器用。需要时临时分配,用完立即释放。栈顶寄存器T指出了当前栈中最新分配的单元(T也是数组S的下标)。
4.	B:基地址寄存器,指出每个过程被调用时,在数据区S中给出它分配的数据段起始地址,也称为基地址。每个过程被调用时,在栈顶分配三个联系单元。这三个单元的内容分别是:
SL:静态链,它是指向定义该过程的直接外过程运行时数据段的基地址。
DL:动态链,它是指向调用该过程前正在运行过程的数据段的基地址。
RA:返回地址,记录调用该过程时目标程序的断点,即当时的程序地址寄存器P的值。
        具体的过程调用和结束,对上述寄存器及三个联系单元的填写和恢复由下列目标指令完成。
1.	INT  0  a
a:为局部量个数加3
2.	OPR  0  0
恢复调用该过程前正在运行过程(或主程序)的数据段的基地址寄存器的值,恢复栈顶寄存器T的值,并将返回地址送到指令寄存器P中。
3.	CAL  l  a
a为被调用过程的目标程序的入口,送入指令地址寄存器P中。
CAL指令还完成填写静态链,动态链,返回地址,给出被调用过程的基地址值,送入基址寄存器B中。

 例:一个Pl/0源程序及生成的目标代码:
const a=10;
var b,c;
procedure p;
begin
  c:=b+a
end;
2	int  0  3
3	lod  1  3
4	lit  0  10
5	opr  0  2
6	sto  1  4
7	opr  0  0
begin
  read(b);
  while b#0 do
    begin
      call  p;
      write(2*c);
      read(b)
     end
end .
8	int  0  5
9	opr  0  16
10	sto  0  3
11	lod  0  3
12	lit  0  0
13	opr  0  9
14	jpc  0  24
15	cal  0  2
16	lit   0  2
17	lod  0  4
18	opr  0  4
19	opr  0  14
20	opr  0  15
21	opr  0  16
22	sto  0  3
23	jmp  0  11
24	opr  0  0

下面是一些资料

Java版的自顶向下实现:
JAVA课程设计PL0编译器

C语言版的自顶向下实现:
pl/0编译器源码及文档

最后加上我自己实现的,这个是有别于网上的一般实现,采用的SLR(这个具体可以参考编译原理类的书籍)的方法,但是由于时间关系,在代码生成的时候并没有采用标准的语法制导翻译,所以还有待改进,不过整体也算是实现了一个SLR分析方法,而且我实现了读入文法由程序自动的构造SLR分析表,所以文法可以随时修改,相当于实现了一个Yacc的部分功能,也算有一定参考价值,也把代码放在这里吧:
https://github.com/wangzhaode/PL0-compiler-SLR

编辑于 2016-01-27

?赞同 12??7 条评论

?分享

?收藏?感谢收起?

伊格拉修斯

爱学习,爱劳动

1 人赞同了该回答

也可以参考用flex+bison做词法分析和语法分析,用c写语义部分和中间代码生成。

最近用上面的方法写了个类java语言的编译器,有兴趣可以交流。

建议开始入门编译原理不要看龙书,略难,容易在细枝末节处徘徊太长时间。

编辑于 2017-12-05

?赞同 1??添加评论

?分享

?收藏?感谢

刘金城

退出知乎,勿扰。

1 人赞同了该回答

可以,我们那时候的课程就是要我们自己设计一个编程语言,并解析成对应的c语言程序运行出来,虽然那时候写的很差劲,但基本能实现。

发布于 2016-02-11

?赞同 1??添加评论

?分享

?收藏?感谢

黄锐皓

完全不刻苦

1 人赞同了该回答

可以,这个就是鄙校大三编译原理课的大作业

发布于 2016-02-13

?赞同 1??1 条评论

?分享

?收藏?感谢

尚学堂科技

已认证的官方帐号

实现一个编译器并不难,因为我们在学Java之初,就是用记事本进行编译的。当然,如果制作复杂的编译器需要编译器框架,但原理是一样的。

作者:tyler_download

链接:编译原理动手实操,用java实现一个简易编译器1-词法解析入门 - CSDN博客

来源:CSDN博客

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

技术的发展可谓是日新月异,层出不穷,但无论是炙手可热的大数据,还是火热的人工智能,所有这些高大上的尖端科技无不建立在基础技术的根基之上。编译原理,计算机网络,操作系统,便是所有软件技术的基石。在这三根支柱中,维编译原理最为难懂,特别是大学课本那种晦涩难通,不讲人话的言语,更是让人觉得这门基础技术就像九十多岁的老妪,皮肤干巴,老态龙钟,让人提不起一点欲望。除了国内教材,就算是被广为称赞的一千多页的”龙书“,也是满篇理论,让人望而生畏。

味道怎样,咬一口就知道,手感如何,摸一把就晓得。编译原理缺的不是理论概念,而是能够动手实践的流程,代码,很多原理用话语怎么讲都难以明了,但跑一遍代码,基本就水落石出。本文本着动手实操(念第一声)的原则,用java实现一个简单的编译器,让读者朋友能一感编译原理的实质,我秉持一个原则,没有代码可实践的计算机理论,都是耍流氓。

编译器作用就是将一种计算机无法理解的文本,转译成计算机能执行的语句,我们要做的编译器如下,将带有加法和乘法的算术式子,转译成机器能执行的汇编语句,t0, t1 是对寄存器的模拟,上述语句基本上就类似计算机能执行的汇编语句了。本章首先专注于词法解析的探讨。

编译原理由两部分组成,一是词法分析,一是语义分析。先说词法分析,词法分析就是将一个语句分割成若干个有意义的字符串的组合,然后给分割的字符串打标签。例如语句:1+2*3+4; 可以分割成 1+, 2*, 3+, 4; 但这些子字符串没有实质意义,有意义的分割是1, +, 2, * , 3, +, 4, ;. 接着就是给这些分割后的字符串打标签,例如给1, 2, 3, 4 打上的标签是NUM_OR_ID, + 打的标签是PLUS, *的标签是TIMES, ;的标签是SEMI, 好了,看看词法分析的代码,代码中2到6行是对标签的定义,其中LP 代表左括号(, RP代表右括号), EOI 表示语句末尾, 第10行的lookAhead 变量用于表明当前分割的字符串指向的标签值,yytext用于存储当前正在分析的字符串,yyleng是当前分析的字符串的长度,yylineno是当前分析的字符串所在的行号。input_buffer 用于存储要分析的语句例如: 1+2*3+4; isAlNum 用于判断输入的字符是否是数字或字母。lex() 函数开始了词法分析的流程,31到40行从控制台读入语句,语句以"end"表明结束,例如在控制台输入:

1+2*3+4;
end

回车后,从52行开始执行词法解析流程。以上面的输入为例,input_buffer 存储语句 1+2*3+4, 由于第一个字符是 1, 在for 循环中,落入switch 的default 部分,isAlNum 返回为真,yyleng 自加后值为1, yytext 存储的字符串就是 "1", current前进一个字符变为+2*3+4, 再次执行lex(), 则解析的字符是+, 在for 循环中,落入switch的case ‘+‘ 分支,于是yytext为"+", 返回的标签就是PLUS依次类推, advance 调用一次, lex()就执行一次词法分析,当lex执行若干次后,语句1+2*3+4;会被分解成1, +, 2, *, 3, +, 4, ; 。字符串1, 2, 3, 4具有的标签是NUM_OR_ID, + 具有的标签是PLUS, *的标签是TIMES, ;的标签是SEMI。

runLexer() 将驱动词法解析器,执行解析流程,如果解析到的当前字符串,其标签不是EOI(end of input), 也就是没有达到输入末尾,那么就打印出当前分割的字符串和它所属的标签,接着调用advance() 进行下一次解析。

发布于 2018-04-26

?赞同??添加评论

?分享

?收藏?感谢收起?

知乎用户

答案是肯定的。我们就是学完了《编译原理》课程,小学期做的实验项目就是实现一个简单的编译器。

发布于 2017-09-13

?赞同??添加评论

?分享

?收藏?感谢

Beta喵

一个安静的学渣。

我天,我们那渣学校让学编译原理时,作业就要求手写lex、递归下降、parser,侧重前端。。项目大作业我偷懒用JAVA Antlr4撸了...
PS,你学了编译原理不是应该知道高级语言都图灵等价了吗?什么语言都能撸的,玩的6了你就会想元编程、FP、C++了。。。。

发布于 2016-02-11

?赞同??添加评论

?分享

?收藏?感谢

知乎用户

Google: Classrooom Object Oriented Language.

https://theory.stanford.edu/~aiken/software/cool/cool-manual.pdf

code:
GitHub - jackzhao-mj/CS164-PA

from: https://www.zhihu.com/question/39835953

原文地址:https://www.cnblogs.com/GarfieldEr007/p/9953883.html

时间: 2024-09-30 06:57:05

学了编译原理能否用 Java 写一个编译器或解释器?的相关文章

用antlr4来实现《按编译原理的思路设计的一个计算器》中的计算器

上次在公司内部讲<词法分析--使用正则文法>是一次失败的尝试--上午有十几个人在场,下午就只来了四个听众. 本来我还在构思如何来讲"语法分析"的知识呢,但现在看来已不太可能. 这个课程没有预想中的受欢迎,其原因可能是: 1.课程内容相对复杂,听众知识背景与基础差异比较大. 2.授课技巧不够,不能把复杂的知识简单化的呈现给基础稍差一点的人. 针对这两个可能的原因,我要尝试做出以下调整: 1.使用antlr来实现词法和语法的部分. 2.暂时把"编译"过程改为

感觉Java写一个窗口真心简单,很易上手

上学期学习了Java ,感觉Java写一个窗口真心简单,很易上手,也就难怪很多开发人员选择Java作为自己的开发编程语言.但是由于自身对windows的热爱,让我觉得c.c++语言才是我亲睐的编程语言,虽然难度大些,但是这才能体现能力所在.其实之前一直想自学一下win32,但是由于时间的显示和种种原因而耽搁了,于是今年暑假决心深入学习win32. 在学习过程中呢,我会在此留下自己的学习心得,当做自己的笔记.初学者可以借鉴,高手可以多多指教,呵呵…… 好了,今天开始做第一课的笔记吧: 学习Win3

用java写一个远程视频监控系统,实时监控(类似直播)我想用RPT协议,不知道怎么把RPT协议集成到项目中

我最近在用java写一个远程视频监控系统,实时监控(类似直播)我想用RPT协议,不知道怎么把RPT协议集成到项目中,第一次写项目,写过这类项目的多多提意见,哪方面的意见都行,有代码或者demo的求赏给我,谢谢

用JAVA写一个视频播放器

前言 跳过废话,直接看正文 当年入坑java是因为它的跨平台优势.那时我认为,"编写一次,处处运行."这听上去多么牛逼,应该是所有语言发展的终极之道,java势必会一统天下. 然而事实证明,那时的我还是太年轻. 正所谓鱼和熊掌不可兼得,若要享受跨平台带来的方便,便不可避免地要接受性能上的不足.事实上,java一直在致力于提高虚拟机的性能(JIT等技术),但面对对实时计算性能要求很高或涉及到用硬件优化的任务(视频的硬件编码.解码)时,仍远远比不上c或c++.因此,很少能够看到有人用jav

用JAVA写一个函数,功能如下: 任意给定一组数, 找出任意数相加之后的结果为35(任意设定)的情况

用JAVA写一个函数.功能如下:任意给定一组数,例如{12,60,-8,99,15,35,17,18},找出任意数相加之后的结果为35(任意设定)的情况. 可以递归算法来解: package test1; import java.util.Arrays; public class demo { public static void main(String[] args) { String str = "12,60,-8,99,15,35,17,18,8,10,11,12"; int s

五:用JAVA写一个阿里云VPC Open API调用程序

用JAVA写一个阿里云VPC Open API调用程序 摘要:用JAVA拼出来Open API的URL 引言 VPC提供了丰富的API接口,让网络工程是可以通过API调用的方式管理网络资源.用程序和软件管理自动化管理网络资源是一件显著提升运维效率和网络生产力的事情.产品经理教你写代码系列文章的目标是不懂代码的网络工程师能一步一步的学会用API管理网络. 另外通过文章标题大家也可以看出来,产品经理教你写代码肯定是一个业余班,里面的代码很多写的都不规范,可能也有很多Bug.专业选手可以参考的有限,请

关于java写一个单例类(面试手写题)

package com.shundong.javacore; /** * java写一个简单的单例类 * @author shundong * */ class Singleton { //使用一个类变量来缓存曾经创建的实例 private static Singleton instance; //对构造进行隐藏(private) private Singleton(){} /** * 提供一个静态方法 * 该方法加入了自定义控制 保证只产生一个Singleton对象 * @return 返回S

从零写一个编译器(三):语法分析之几个基础数据结构

项目的完整代码在 C2j-Compiler 写在前面 这个系列算作为我自己在学习写一个编译器的过程的一些记录,算法之类的都没有记录原理性的东西,想知道原理的在龙书里都写得非常清楚,但是我自己一开始是不怎么看得下来,到现在都还没有完整的看完,它像是一本给已经有基础的人写的书. 在parse包里一共有8个文件,就是语法分析阶段写的所有东西啦 Symbols.java Production.java SyntaxProductionInit.java FirstSetBuilder.java Prod

《用Java写一个通用的服务器程序》01 综述

最近一两年用C++写了好几个基于TCP通信类型程序,都是写一个小型的服务器,监听请求,解析自定义的协议,处理请求,返回结果.每次写新程序时都把老代码拿来,修改一下协议解析部分和业务处理部分,然后就一个新的程序就诞生了.如此这般做了几回,就萌生了一个想法:是不是可以做一个通用的服务器程序,每次只要实现很少的代码就可以构建的一个新的服务器程序? 巧的是在用C++写代码的时候,我刚好碰到过一个叫做Push Framework的开源项目(在这里可以找到:www.pushframework.com),就是