前面几篇讲解了词法剖析和语法剖析,在比方中提到的词法和语法规矩也是高度简化的。尽管这些内容便于了解原理,也能完毕一个简略的原型,在实践运用中却远远不够。实践运用中,一个完善的编译程序还要swift代码在词法方面以及语法方面完毕许多工作,如下图能够直观地看一下。
假定让编译程序完windows7结上面这么多工作,彻底手写功率会优先级回转有点儿低,咱们能够凭仗现有的东西。编译器前端东西有许多,比方 Lex(以及 GNU 的版别 Flex)、Yacc(以及 GNU 的版别 Bison)、JavaCC 等等。选择 Antlr 首要有两方面原因:
- 第一个原因是 Antlr 能支撑更广泛的目标言语,swift代码是什么意思包含 Java、C#、JavaScript、Python、Go、C++、Swift。不管你用上面哪种言语,都能够用它生成词法和语法剖析的功用。
- 第二Windows个原因是 Antlr 的语法更加简略。它能把相似左递归的一些常见难点在东西中处理,对进步工作功率有很大的帮助。
初优先级最高的运算符识 Antlr
Antlr 是一个开源的东西,支撑依据规矩文件生成词法剖析器和语法剖析器,它自身是用 Java 完毕的。
能够下载 Antlr语法规矩库到本地,方便检查。
能够下载 Antlr 东西,并依据说明做好装备。一起,swift什么意思你还需求装备好机器上的 Java 环境(能够在Oracle 官网找到最新版其他 J优先级排序表格DK)。
关于Mac电脑为例:
$ cd /usr/local/lib
$ sudo curl -O https://www.开源节流antlr.org/download/antswift结算体系lr-4.9.2-complete.jar
// vim .bash_profile 添加如下内容
$ export CLASSPATH=".:/usr/local/lib/antlr-4.9.2-complete.jar:$CLASSPATH"
$ alias antlr4='java -jar /usr/local/lib/antlr-4.9.2-complpython编程ete.jar'
$ alias gpython培训班学费一般多少run='java org.antlr.v4.gui.TestRigpython123'
$ source .bpython123渠道登录ash_profile
用 Aswift代码ntlr 生成词法剖析器
Antlr 经过解windows10析规矩文件来生成编译器。开源代码网站github规矩文件以.g4 完毕,词法规矩和语法规矩能够放在同一个文件python123里。不过为了清晰起python能够做什么工作见,咱们仍是把它们swift语言分红两个文件,先用一个文开源软件件编写词法规矩。
先做一个简略的操练,创立一个 Hello.g4 文件,用于保存词法规矩,然后把之前用过的一些词法规矩写进去。
lswiftlyexer grammar Hello; //lexer 关键字意味着这是一个词法规矩文件,称谓是 Hello,要与文件名相同
// 关键字
If : 'if';
Int : 'int';
// 字面量
IntLiteral: [0-9]+;
StringLiteral: '"' .*? '"' ; // 字符串字面量
// 操作符
AssignmentOP: '=' ;
RelationalOP: '>'|'>='|'<' |'<=' ;
Star: '*';
Plus: '+';
Sharp: '#';
S开源节流emiCo开源节流是什么意思是什么lon优先级英文: ';';
Dot: '.';
Comm: ',';
LeftBracket : '[windows更新有必要吗';
Riswift代码ghtBracket: ']';
LeftBrace: '{'windows10激活密钥;
RightBrace: '}';
LeftParen: '(';
RightPare优先级回转n: ')';
// 标识符
Id : [a-zA-Z_] ([a-zA-Z_] | [0-9])*;
// 空白字符,丢掉
Whitespace: [ t]python基础教程+ -> skip;
Newline: ( 'r' 'n'?|'n')-&python能够做什么工作gt; skip;
每个词法规矩都是大写字母开端,这是 Antlr 对词法规矩的约好。而语法规矩是以小写字母开端的。其间,每个规矩都是用咱们现已了解的正则表达式编写的。
接windows怎样激活下来,我开源们来编译词法规python培训班学费一般多少则,在终端中输入指令:
antlr4 Hello.g4
这个指令是让 Antlr 编译优先级队列规矩文件,并生成 Hello.java 文件和其他两个辅佐文件。你能够翻开看一看文件里边的内容。接着,我用下面的指令编译 Helswiftlylo.java:
javac *.java
效果会生成 Hello.class 文件,这便是咱们生成的词法剖析器。接下来,咱们来写个脚本文件,让生成的词法剖析器解析一下:
int age = 45;
if (age >= 17+8+20){
printf("H优先级最高的运算符ello old man!");
}
咱们将上面的脚本存成 hello.play 文件,然后在终端输入下面的指令:
grun HellWindowso tokens -tokens hello.play
grun 指令实践上是调用了咱们方才生成的词法剖析器,即 Hello 类,打印出对 hello.play 词法剖析的效果:
从效果中看到,咱们的词法剖析器把每个 Token 都识别了,还记录了它们在代码中的方位、文本值、类别。上面这些都是 Token 的特点。swift结算体系
以第二行 [@1,Swift 4:6=‘age’,<优先级是什么意思 Id >,1:4] 为例,其间 @1 是 Token 的流水编号,标明这是 1 号 Token;4:6 是 Token 在字符流中的开端和完毕方位;age 是文本值,Id 是其 Token 类别;终究的 1:4 表明这个 Token 在源代码中坐落第优先级超过50预约失利 1 行、第 4 列。python能够自学吗
先看看咱们之前写的字符串字面量的规矩:
StringLiteral: '"' .*? '"' ; // 字符串字面量swift语言
我windows10们的版别适开源众包当简化,便是在双引号能够包含任何字符。可这在实践中不大好用,因为连转义功用都没有供应。咱们关于一些不可见的字符,比方回车,要供应转义功用,如“n”。一起,假定字符串里自身有双引号的话,也要将它转义,如“”。Unicode 也要转义。终究,转义字符自身开源也需求转义,如“”。
下面这一段内容是 Java 言语中的字符串字面量的无缺规矩。你能够看一下文稿,这个规矩就开源节流很详尽了,把各种转义的情况都考虑进去了:
STRING_LITERAL: '"' (~["rn] | EscapeSequence)* '"';
fraswift结算体系gment EscapeSequSwiftence
: '' [btnfr"']
| '' ([0-3]? [0-7])? [0-7]
| '' 'u'+ HexDigit H开源exDigit HexDigit HexDigit
;
fragment HexDigit
: [0-9a-fA-F]
;
在这个规矩文件中,fragswift代码是什么意思ment 指的是一个语法片段,是为了让规矩界说更清晰。它自身并不生成 Token,只要 StringLiteral 规矩才会生成 Token。
当然了,除了字符串字面量,数字字面量、标识符的优先级回转规矩也能够界说得更严密
词法规矩中对 Token 归类的问题
在前面操练的规矩文件中,咱们swift选手把 >=、>、<swift代码 都归类为联系运算符,算作windows许可证行将过期怎样办同一类 Token,而 +、* 等都单独Python作为另一类 Token。那么python编程,哪些能够归并成一类,哪些又是需求单独列出的呢?
其实,这首要取决于语法的需python基础教程求。也便是在语法规矩文件里,是否能够swift代码出现在同一条规矩里。它们在语法层面上没有差异,仅仅在语义层面上有差异。比方,加法和减法尽管是不同的运算,但它们能够一起出windows10激活密钥现在同一条语法规矩中,它们在运算时的特性彻底一致,包含优先级和结合性,乘swift选手法和除法能够一起出现在乘法规矩中。你把加号和减号合并成一类开源矿工,把乘号和除号合并成一类是能够的。把这优先级回转 4 个运算符每个都单独作为一类,也是能够的。但Swift是,不能把加号和乘号作为同一类,因为它们在算术运算中的优先级不同,必定出现在不同的语法规矩中。
咱们再来回想一下在“编译原理实战一:如何用JS完毕一个词法优先级排序表格剖析器?”里做词优先级越小越优先吗法剖析时遇到的一个问题。其时,咱们剖析了词法冲突的问题,python123渠道登录即标识符和关键字的规矩是有堆叠的。Aswift代码查询ntlr 是怎样处理这个问题的呢?很简略,它引入了优先级的概念。在 Antlr 的规矩文件中,越是前面声明的规矩,优先级越高。所以优先级排序,咱们把关键字的规矩放在 ID 的规矩前面。算法在履行的时分,会首先检查是否为关键字,然后才会检查是否为 ID,也便是标识符。
这跟咱们其时结构有限主动机做词法剖析是相同的。那时,咱们先判别是不是关键字,假定不是关键字,学识别为标识符。而在 Antswift代码是什么意思lr 里,仅仅经过声明的顺序就处理了这个问题python怎样读,省了许多事windows许可证行将过期怎样办儿啊!
Antlr 生成语法剖析器
现在现已知道如何用 Antlr 做一个词法剖析器,还知道能够学习老到的规矩文件,让自己的词法规矩文件变得更完善、更专swifter业。接下来,试着用 Antlr 生成一个语法剖析器,代替之前手写的语法剖析器吧!
这一次的文件名叫做 PlayScript.g4。PlayScript 是为咱们的脚本言语起的称谓,文件开端是这样的:
grammar PlayScript;
import CommonL开源节流exer; // 导入词法界说
/* 下面python是什么意思的内容加到所生成的 Ja开源我国va 源文件的头部,如包称谓,import 句子等。*/开源软件
@header {
pa开源节流是什么意思是什么ckage antlrtest;
}
然后把之前做过的语法界说放进去。Antlr 内部有主动处理左递归的机制,你能够放心大胆地把语法规矩写成下面的姿态:
expression
: assignmentExpression
| expression ',' assignmentExpression
;
assignmentExpression
: additiveExpression
| Identifwindows怎样激活ier assignmentOperator additiveExpython怎样读presSwiftsion
;
assignmentOperator
: '='
| '*='
| '/='
| '%='
| '+='
| '-='
;
additiveExpression
: multiplicativeExpression
| additiveExpressionpython编程 '+'python基础教程 multiplicativeExpression
| additiveExpression '-' multiplicativeExpression
;
multiplicativeExpression
: primaryExpression
| multiplicativeExprwindows10ession '*' primaryExpression
| multiplicativeExprwindows10ession '/' primpython能够做什么工作aryExpression
| mupython编程ltiplicativeExpression '%' primaryExpression
;
你或许会问:“已然用 Antlr 可windows7以不管左递归问题,那之前为什么要费力气处理它呢?”那是因为当你遇到某些问题却没有现成东西时,仍是要用纯手工的方法去处理问题。并且,有的东swift结算体系西或许没有这么智能,你需求写出契合这个东西的规矩文件,比方说不能Swift有左递归的语法规矩。仍是那句话:懂得基础原理,会让你站python编程得更高。
咱们继续运转下面的指令开源众包,生成语法剖析器:
antlr4 PlayScript.g4
javac antrl_grammer/windows10*.java
然后检验一下生成的语法剖析器:
grun antrl_grammer.PlayScript expression -gui
这个指令的意思是:检验 PlayScript 这个类的 expression 方法,也便是解析表达式的方法,效果用图形化界面闪现。
咱们在控制台界面中输入下面的内容
age + 10 * 2 + 10
^D
其间 ^D 是按下 Ctl 键windows怎样激活的一起按下 D,适当于在终端输入一个 EOF 字符,即文件完毕符号(Windows 操作体系要运用 ^Z)。当然,你也能够提早把这些句子放到文件中,把文件名作为指令参数。之后,语法剖析器会剖析这些语法,并弹出一个窗口来闪现 AST:
看得出来,AST 彻底正确,优先级和结合性也都没错。所以,An优先级回转tlr 生成的语法剖析器仍是很靠谱的。今后,你专心写swift什么意思语法规矩就行了,能够把精力放在言语的规划和运用上。
源码地址 antrl_grammerpython123
课程内容参看windows更新自 极客时间 编译原理课程。