Kotlin你不知道的秘密(二)

小明为什么要说*** 因为小明不知道你在说什么他不理解你说的是不是一句话而且在结构式也构不成一句话。何为一句正确的话?我们看到小红说的话是有多个词语组成的,词语之间没有任何连贯也组合不成句子所有小明就很蒙又加上他最近可能大姨夫来了所以才表现的比较亢奋。但是程序是没有情绪科可言的,不管你怎么对他,他都是不冷不热的样子。比如我们常见的:

1617085964(1).jpg

可以看到我们只输入一个if表达式,studio会给我们一个错误提示,这个提示什么意思那?大概可以理解为期望一个()并在括号在输入条件,我们按照他的提示我们输入括号

1617086431(1).jpg

他又是提示我们期待一个表达式,从这个时候看到它不像小明那样很暴躁直接来句***。而是会一步一步提示我们它想要的是什么,而当你输入表达式后它又说没有内容,它希望你输入内容来起到他的作用。感兴趣的可以一步一步尝试下。这时候可以我就有一个疑问:他为什么能知道他想要的? 因为他有语法分析器。

语法分析器

public class KotlinParser implements PsiParser {

@NotNull
public ASTNode parse(IElementType iElementType, PsiBuilder psiBuilder, PsiFile psiFile) {
KotlinParsing ktParsing = KotlinParsing.createForTopLevel(new SemanticWhitespaceAwarePsiBuilderImpl(psiBuilder));
String extension = FileUtilRt.getExtension(psiFile.getName());
if (extension.isEmpty() || extension.equals(KotlinFileType.EXTENSION) || (psiFile instanceof KtFile && ((KtFile) psiFile).isCompiled())) {
ktParsing.parseFile();
} else {
ktParsing.parseScript();
}
return psiBuilder.getTreeBuilt();
}
}

可以看到Kotlin的语法分析是通过KotlinParsing进行的,在parse方法中创建KotlinParsing然后把要分析的文件传递过去,这里的文件也就是我们熟悉的以 .kt结尾的文件。当然也不局限于kt文件。接着我们跟进下ktParsing.parseFile();

public class KotlinParsing extends AbstractKotlinParsing {
void parseFile() {
PsiBuilder.Marker fileMarker = mark();
//分析类的注释、package、import*
parsePreamble();
while (!eof()) {
//分析包、类、方法的声明方法,例如:package、class、function
parseTopLevelDeclaration();
}
checkUnclosedBlockComment();
fileMarker.done(KT_FILE);
}
}

parseFile中做的.kt类中的声明分析,这些声明也就是上一篇提到的KtTokens中定义的关键字和操作符之类的。顺便提一下语法分析大概分为两类:

自顶向下分析:根据形式语法规则,在语法分析树的自顶向下展开中搜索输入符号串可能的最左推导。单词按从左到右的​
顺序依次使用。

自底向上分析:语法分析器从现有的输入符号串开始,尝试将其根据给定的形式语法规则进行改写,最终改写为语法的起始符号。

可以看到Koltin中是使用的自顶向下分析法,这种分析法也比较适合我们的编码习惯。 到这基本上有了语法分析的大概,但是没有看到我们前面举例的if和括号使用的分析。其实在KotlinParser中会创建KotlinExpressionParsing类,这个类中主要处理的也是一些和表达式相关的分析。

public class KotlinExpressionParsing extends AbstractKotlinParsing {

private boolean parseAtomicExpression() {
boolean ok = true;
if (at(LPAR)) {
parseParenthesizedExpression();
}else if (at(LBRACKET)) {
parseCollectionLiteralExpression();
} else if (at(IF_KEYWORD)) {
parseIf();
}

return ok;
}

private void parseIf() {
advance();
parseCondition();
PsiBuilder.Marker thenBranch = mark();
if (!at(ELSE_KEYWORD) && !at(SEMICOLON)) {
parseControlStructureBody();
}
if (at(SEMICOLON) && lookahead(1) == ELSE_KEYWORD) {
advance(); // SEMICOLON
}
thenBranch.done(THEN);
}

private void parseCondition() {
myBuilder.disableNewlines();
if (expect(LPAR, “Expecting a condition in parentheses ‘(…)’”, EXPRESSION_FIRST)) {
PsiBuilder.Marker condition = mark();
parseExpression();
condition.done(CONDITION);
expect(RPAR, “Expecting ')”);
}
myBuilder.restoreNewlinesState();
}
}

最后

小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

资料⬅专栏获取
的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

资料⬅专栏获取

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值