这部分代码是需求动态生成的,语法剖析
"compile-antlr-windows": "@powershell -NoProfile -ExecutionPolicy Unrestricted -Command ./compile-antlr.ps1",
Set-Location "syntaxes"
Remove-Item "../src/_generated" -Recurse -ErrorAction Ignore
npx antlr4ts -o "../src/_generated" "AntlrGlslLexer.g4"
npx antlr4ts -o "../src/_generated" -no-listener -visitor "AntlrGlslParser.g4"
ANTLR是基于LL算法实现的语法解析器生成器
源码剖析
当插件发动后就会剖析确诊当前翻开的文档内容,根据antlr的ast笼统语法树,对整个代码进行剖析
当鼠标hover后,语法接下内容后,判断当前鼠标处的内容是什么,变量函数?然后查找对应的hover提示内容,
一切的根底都是那个antlr
antlr4ts -o ./src/antlr -no-listener -visitor ./syntaxes/CocosEffect.g4
ANTLR Parser Generator Version 4.9.0-SNAPSHOT
-o ___ specify output directory where all output is generated
-no-listener don't generate parse tree listener
-visitor generate parse tree visitor
语法遍历解说
grammar CocosEffect;
prog: (expr NEWLINE)* ;
expr: expr ('*'|'/') expr
| expr (' '|'-') expr
| INT
| '(' expr ')'
;
NEWLINE : [rn] ;
INT : [0-9] ;
antrl生成的ts visitor有对应的回调接口,当检测到文本符合对应的语法时,就会触发对应语法的ts回调接口,举个例子
antlr生成的Visitor代码如下
export interface CocosEffectVisitor<Result> extends ParseTreeVisitor<Result> {
// 这2个都是语法接口,对应g4里边写的语法key,数据类型是grammar key Context
visitProg?: (ctx: ProgContext) => Result;
visitExpr?: (ctx: ExprContext) => Result;
}
咱们只需求继承antlr的Visitor,然后重写对应的回调,即可拿到剖析后的结果
export class Visitor extends AbstractParseTreeVisitor<void> implements CocosEffectVisitor<void> {
visitExpr(ctx: ExprContext): void {
// 编写自己的处理语法逻辑
return;
}
}
注意java version
antlr grammar syntax support
插件主要是语法上色,安装后output窗口有报错
Running Java with parameters:
-jar antlr4ng-cliantlr4-4.13.2-SNAPSHOT-complete.jar
-message-format antlr
-o e:projcocos-effectsyntaxes.antlr
-no-listener -no-visitor -Xexact-output-dir
e:projcocos-effectsyntaxesCocosEffect.g4
Exception in thread "main"
java.lang.UnsupportedClassVersionError: org/antlr/v4/Tool has been
compiled by a more recent version of the Java Runtime (class file version 55.0),
this version of the Java Runtime only recognizes class file versions up to 52.0
java8是52
, java11是55
,切换到java11就正常,发现的确是跟java版本有联系,我用的是java8,切换本机java环境就正常了。
parse tree inspector
这个功能是antlr的jar包自带的,而justAntlr
插件供给了grammar tree inpsepctor
的方便操作。
但是我一直没有成功,翻了下源码,终于了解到了细节:
在选择文件后,履行的java指令,所以这个要求java版本也得匹配,不然还会报上边的过错
会在cwd
目录生成对应的解析器java代码:
同时还有警告信息:
This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason:
extensionHostProcess.js:108
No method for rule -gui or it has arguments
使用指令行我尝试了,只要最后一行的日志信息,查看了下用法,最开端其实我没有以为这是指令行的一部分,主要是因为java的指令行内容太长了
E:projcocos-effectsyntaxes.genCSV>java -cp .;F:projjustAntlrlibantlr-4.10.1-complete.jar org.antlr.v4.gui.TestRig -h
java org.antlr.v4.gui.TestRig GrammarName startRuleName
↑ 包括功能的jar包 ↑ 语法名字 ↑从哪个规矩开端
[-tokens] [-tree] [-gui] [-ps file.ps] [-encoding encodingname]
[-trace] [-diagnostics] [-SLL]
[input-filename(s)]
Use startRuleName='tokens' if GrammarName is a lexer grammar.
Omitting input-filename makes rig read from stdin.
再次看了下输入的指令
-
java -cp
是 Java 指令的一部分,用于指定类途径(class path),这个是java的根底知识,注意这里的.;
,是因为编译需求找到antlr生成的那些代码。
java
-cp .;F:projjustAntlrlibantlr-4.10.1-complete.jar org.antlr.v4.gui.TestRig
CSV # GrammarName
-gui
C:UsersAdministratorDesktopeffect1.csv # input-filename
看了很久,找了很多资料,才发现指令行里边缺少了startRuleName
,翻了下justAntlr
源码,它是经过鼠标选中的内容来确认startRuleName
参数,gif中其实有这个操作,不注意真的看不出来的,而且文档里边也没有阐明这点。
终于出来了,在这个tree上浪费了太多的时刻。
startRuleName
这个参数其实是告知antlr,从哪个规矩开端解析,对应的代码中咱们也要调用生成规矩函数来完结解析,这些都算是antlr的根底概念,建议还是从指令行使用antlr,能够愈加透彻的理解。