See代码阅读
一、概述:
See是github上用ANTLR实现的开源脚本语言,网址在
https://github.com/MihaiB/mihaib的forge/antlr-ex/old-see下
https://github.com/MihaiB/see(已失效)
https://github.com/MihaiB/antlr-ex(失效)
它的语法像C,或者说像JavaScript。
例如:
void main()
{
int i = 0;
while(i < 10)
{
print(i);
i = i + 1;
}
}
输出:
0123456789
二、符号信息:
表示符号信息的类集中在see.symbol包中
1. Symbol(接口类,代表符号)
getName : 名称(String)
setType / getType : 类型(Type)
getScope : 作用域(Scope)
getDefNode : 定义ID的节点,用于数组类型(SeeAST)
getDefLocation : 定义的位置(String)
2. Type(接口类,继承自Symbol接口,代表类型符号)
getTypeIndex : 类型索引
3. Scope(代表可向上查找的符号表信息,是作用域树的一个节点)
name : 作用域名称(String)
parent : 父级(Scope)
members : 符号表(私有),String->Symbol(Map)
Scope : 受保护,确保Scope只能用于继承。
define : 在作用域中创建符号
getOrderedMembers : 把符号表转为Set
resolve : 把符号名转为Symbol对象(可能需要向上查找父级Scope)。
resolveMember : 把符号名转为Symbol对象(不向上查找)
4. NamedSymbol(包内可见的类,继承自Symbol,表示没有嵌套符号的符号)
NamedSymbol内部不能有其它Symbol。
例如ArrayType是NamedSymbol,但FunctionSymbol不是。
构造函数封装名称(非空)、作用域(非空)、SeeAST节点(可以为空),
如果SeeAST节点为空,则判断它是否为内置类型或内置类型的数组。
5. SymbolTable(符号表,单实例)
全局的符号信息,包含内置符号和脚本中的符号。
还包含语法信息。
作为单实例,用在语法解析器和运行解析器。
6. TypeTables(类型表)
一些语法信息,用于SymbolTable。
7. ArrayType(继承NamedSymbol,实现Type,单实例)
作为单实例用于构造指定Type和维数的数组。
同时它代表了带[]的数组类型节点.
它的SeeAST节点由参数的Type决定
8. BuiltInType(继承NamedSymbol,实现Type)
在SymbolTable中构造实例。
用于加入内置类型,例如boolean。
它不需要SeeAST节点.
9. FunctionSymbol(继承Scope,实现Symbol)
代表函数定义。
NamedSymbol是成员变量(相当于多继承)
它是Scope,所以可以嵌套其它Symbol。
10. StructType(继承Scope,实现Symbol)
代表结构体定义。
NamedSymbol是成员变量(相当于多继承)
它是Scope,所以可以嵌套其它Symbol。
11. VariableSymbol(继承NamedSymbol)
代表变量定义
它不能嵌套Symbol
三、运行时解析器
与运行时解析器相关的类定义在see.interp包中
1. FunctionReturnException(继承RuntimeException)
当return执行完后抛出(见Interpreter.java:returnStat)
2. UserArrayIndexOutOfBoundsException(继承ArrayIndexOutOfBoundsException)
当数组元素赋值或索引时下标超出范围时抛出。
(见Interpreter.java:arrayElemAssign和Interpreter.java:index)
3. UserNullPointerException(继承RuntimeException)
当操作数出现null时抛出(null通常来自用户类型实例的默认值或null关键词)
(见Interpreter.java中的arrayElemAssign,fieldAssign,index,lenOp,loadField)
4. MemorySpace
变量实例表(?)
5. Interpreter
运行时解析器(相当于虚拟机)。
运行SeeAST根节点。
入口点在run(),
Interpreter内部根据SeeAST节点的类型进行跳转和递归调用。
四、AST生成
1. Def(继承TreeFilter)
由Def.g生成
2. Ref(继承TreeFilter)
由Ref.g生成
3. Types(继承TreeFilter)
由Trees.g生成
4. SeeLexer(继承Lexer)
由See.g生成
5. SeeParser(继承Parser)
由See.g生成
6. SeeAST(继承CommonTree)
7. ErrorNode(继承SeeAST)
8. Listener
错误输出(包括位置和消息)
9. Main
程序主入口
五、关键代码:
1. see.symbol.SymbolTable.java:makeSingleton
& see.symbol.SymbolTable.java:SymbolTable
创建global作用域,
构造内置类型。
SymbolTable的作用是处理SeeLexer产生的Token流,
在SeeParser启动前完成符号表的构建。
2. Interpreter.java:exec
AST语法成分判断分支
3. Main.java:main
主入口
六、技术细节:
1. 使用SeeParser.setTreeAdaptor()更改默认的树适配器
由于默认生成的SeeParser的适配器是CommonTreeAdaptor。
需要用这种方法把Token封转为SeeAST(CommonTree的子类),
携带更多信息。
CommonTreeAdaptor的代码注释中是这样说明的:
To get your parser to build nodes of a different type, override
create(Token), errorNode(), and to be safe, YourTreeClass.dupNode().
dupNode is called to duplicate nodes during rewrite operations.
【翻译】为了使你的解析器构建不同类型的节点,请覆盖create(Token)和errorNode(),
还有出于安全起见,覆盖<你的树类>.dupNode()。
调用dupNode是为了在重写操作期间复制节点。
更多信息见官网介绍:
Using custom AST node types
http://www.antlr.org/wiki/display/ANTLR3/Tree+construction
2. Main类中获取流的情况:
CommonTokenStream tokens = new CommonTokenStream(lexer);
从SeeLexer中获取CommonTokenStream
CommonTree t = parser.program().tree;
CommonTreeNodeStream nodes = new CommonTreeNodeStream(t);
nodes.setTokenStream(tokens);
从SeeParser中获取CommonTree,再获取CommonTreeNodeStream。
然后把CommonTokenStream放进CommonTreeNodeStream中
3. 树解析器(tree grammar)的使用。
(1) Def:符号定义。
(2) Ref:解析引用,把它们指向SymbolTable的Symbol(不能向前引用)。
(3) Types:计算引用类型(向前引用?)和表达式。
共通之处:
1. nodes.reset(); 在执行树解析器前重置CommonTreeNodeStream
2. TreeFilter.downup(t); 让每个树解析器运行(自下而上,深度遍历)
3. 逐个用downup写入CommonTree,最后把CommonTree传给Interpreter运行虚拟机。
4. 树模式匹配
官方介绍:
Tree pattern matching
http://www.antlr.org/wiki/display/ANTLR3/Tree+pattern+matching
它的明显特征是使用在.g文件中使用filter=true;的options选项:
这样,生成代码的树解析器类不是继承自TreeParser,而是继承自TreeFilter
TreeFilter实际上是TreeParser的子类,拥有执行downup的能力。
(TODO)
相关推荐
这是关于论文Learning to See in the Dark. CVPR 2018的相关代码值得学习
INCU V1.0有以下几大功能: 1.远程桌面鼠标控制 2.远程驱动器文件浏览与上传下载 3.文本消息传递 4.远程关机 5.多线程一网段同时控制 6.客户端控制服务端升级更新 INCU V1.0的特点: ...
Kinect技术开发非常好的书籍《Making Things See》的随书源码,是Java的
pytorch-Learning-to-See-in-the-Dark代码,CVPR论文 亲测,可行
这是关于学术论文Learning to See in the Dark的相关代码
C#实现远程桌面共享源代码,本源代码分为客户端和服务器端,实现客户端连接服务器端,对服务器端桌面进行远程共享,在此基础上可添加部分权限控制实现远程桌面控制。
Looksee的构建完全不会影响您的布局。 如果确实如此,请通过下面的支持链接与我联系。 示例:-在输入字段中键入div将为活动选项卡上的每个div添加边框-键入*将为html文档中的所有内容添加边框-键入p,h3,div> ...
【R213】The Worlds I See 我看见的世界【Fei-Fei_Li 李飞飞】
iOS游戏应用源代码——akopanev-iOS-Scratch-n-See-6ca51ac.zip
数据挖掘中的决策树生成的经典的see5软件的源代码。
代码片段: <title>jQuery多文件上传并获取大小与格式代码</title> [removed][removed] [removed][removed] <link rel="stylesheet" href="style/uploadW.css?3.1.64"> </head> ...
(安卓APP项目源代码)竖直SeekBar源码(安卓APP项目源代码)竖直SeekBar源码(安卓APP项目源代码)竖直SeekBar源码(安卓APP项目源代码)竖直...源码(安卓APP项目源代码)竖直SeekBar源码(安卓APP项目源代码)竖直See
Java中的look in dark
卷积神经网络的源代码 ConvNet - C++ Convolutional Neural Network Library Description of the contents: compile.sh script that compiles the ConvNet library CMakeLists.txt main file describing build ...
对于MIPS体系结构当前发展的资料是最新的,相对于第一版而言,增加了许多新材料,包括对MIPS...此外,该次修订在书后增加了《译者补遗》一节,介绍了几条与PC代码有关的 MIPS汇编指小语句的说明,希望对部分读者有所帮助。
C5.0(See5)决策树的Windows版源代码,适合于致力研究决策树的同学们
minilzo C语言源代码,有测试程序,可以直接拿来用。The LZO library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ...
See published demo file for more information. 2) Minimise geometric distance - i.e. the sum of squared distance from the data points to the ellipse. This is a more desirable fit, as it has some ...
一个3D国际象棋游戏的源代码,用c++和directX写的,效果很好看-a 3D chess game of the source code used to write c and directX the good results, see
这是我自己制作的游戏原代码你们可以去 # To enable ProGuard in your project, edit project.properties # to define the proguard.config property as described in that file. # # Add project specific ProGuard...