C语言解释器-7 一切的基础 Context类
来源:互联网 发布:linux 线程 参数 编辑:程序博客网 时间:2024/06/13 23:11
Context是构建语法树的基础,程序由一个个Context组成,比如变量(申明),语句,块,函数,控制结构等。
看看Context类的Run方法,很能说明问题:
public virtual void Run(Context ctx) { // 正在运行标记 IsRunning = true; foreach (Context stx in Children) { try { if (stx is Statement || stx is Block) { stx.Run(this); } else if (stx is Variable) { //局部变量,需要登记,以便将来释放 LocalVariables.Add(stx.Name); stx.Run(this); } else if (stx is ConstantInitialize) { //常量,出现在全局Context中,需要记录。在运行到最后的时候释放 m_constantVariableDict.Add((stx as ConstantInitialize).VariableName, stx); stx.Run(this); } else if (stx is Function.FunctionDefine) { // 仅运行main函数,其他函数在调用时运行 if (stx.Name == MainFunctionName) { m_mainFunction = stx as Function.FunctionDefine; m_mainFunction.Body.Run(this); } } } catch (RuntimeException re) { if (OnRuntimeError != null) OnRuntimeError(stx, re.Message); } } // foreach // 释放局部变量 FreeLocalVariables(); IsRunning = false; }
设定所有的Context都应该有个Parent,如果Parent为null,则表示为全局的Context。也即Yacc脚本中的Program规则。
主要的属性有:
// Public public Context Parent; public List<Context> Children; public string Name; public List<string> LocalVariables; public bool IsFirstRunning = true; public LocationInfo Location; public event EventHandler<string> OnRuntimeError;
一些全局性的东西,申明为静态,主要与语法分析相关。还包括内部定义函数。
// Static public static string MainFunctionName = "main"; private static int AnonymousVariableCount = 0; private static string AnonymousVariableNamePrefix = "var"; private static bool ContextIsRunning = false; public static Dictionary<string, bool> KeywordDict = new Dictionary<string, bool>(); public static Dictionary<string, PrimitiveDataType> DataTypeKeywordDict = new Dictionary<string, PrimitiveDataType>(); public static Dictionary<string, bool> ControlKeywordDict = new Dictionary<string, bool>(); public static Dictionary<int, short> TypeCombinationDict = new Dictionary<int, short>(); public static Dictionary<string, bool> InternalFunctionDict = new Dictionary<string, bool>(); public static Memory Memory = new Memory(""); public static bool IsRunning { get { return ContextIsRunning; } protected set { ContextIsRunning = value; } } public static string GetAnonymousName() { return string.Format("${0}_{1}$", AnonymousVariableNamePrefix, ++AnonymousVariableCount); } public static string GetAnonymousName(string prefix) { return string.Format("${0}_{1}$", prefix, ++AnonymousVariableCount); } public static string GetAnonymousName(DataTypeInfo dti) { return string.Format("${0}_{1}_{2}{3}$", AnonymousVariableNamePrefix, DataTypeInfo.StringFromType(dti.BaseType), dti.PointerCount > 0 ? "ptr_" : "", ++AnonymousVariableCount); } public static bool IsKeyword(string str) { if (KeywordDict.Count == 0) { // primitive type KeywordDict.Add("void", true); KeywordDict.Add("char", true); KeywordDict.Add("short", true); KeywordDict.Add("int", true); KeywordDict.Add("float", true); KeywordDict.Add("signed", true); KeywordDict.Add("unsigned", true); // control KeywordDict.Add("if", true); KeywordDict.Add("else", true); KeywordDict.Add("for", true); KeywordDict.Add("do", true); KeywordDict.Add("while", true); KeywordDict.Add("switch", true); KeywordDict.Add("case", true); KeywordDict.Add("continue", true); KeywordDict.Add("break", true); KeywordDict.Add("return", true); // misc KeywordDict.Add("sizeof", true); } return KeywordDict.ContainsKey(str); } public static bool IsDataType(string str) { if (DataTypeKeywordDict.Count == 0) { DataTypeKeywordDict.Add("void", PrimitiveDataType.VoidType); DataTypeKeywordDict.Add("char", PrimitiveDataType.CharType); DataTypeKeywordDict.Add("short", PrimitiveDataType.ShortType); DataTypeKeywordDict.Add("int", PrimitiveDataType.IntType); DataTypeKeywordDict.Add("float", PrimitiveDataType.FloatType); DataTypeKeywordDict.Add("signed", PrimitiveDataType.SignedType); DataTypeKeywordDict.Add("unsigned", PrimitiveDataType.UnsignedType); } return DataTypeKeywordDict.ContainsKey(str); } public static bool IsControlFlow(string str) { if (ControlKeywordDict.Count == 0) { ControlKeywordDict.Add("if", true); ControlKeywordDict.Add("else", true); ControlKeywordDict.Add("for", true); ControlKeywordDict.Add("do", true); ControlKeywordDict.Add("while", true); ControlKeywordDict.Add("switch", true); ControlKeywordDict.Add("case", true); ControlKeywordDict.Add("continue", true); ControlKeywordDict.Add("break", true); ControlKeywordDict.Add("return", true); } return ControlKeywordDict.ContainsKey(str); } public static bool IsInternalFunction(string str) { return InternalFunctionDict.ContainsKey(str); } public static void RegisterInternalFunction(string name) { if (!InternalFunctionDict.ContainsKey(name)) InternalFunctionDict.Add(name, true); }
注意到相当多的静态方法使用字符串字典。
另外一个重要的方法是FindByName(string name),该方法用于查找符合指定名字的已定义的Context,这是检查或查找变量、函数的重要手段。
public virtual Context FindByName(string str) { if (m_nameDict.ContainsKey(str)) return m_nameDict[str]; Context stx = this.Parent; if (stx != null) return stx.FindByName(str); return null; }
一些语法结构,如控制结构、函数,需要知道一些额外信息,因此需要以下辅助方法:
public bool IsInFunction { get { Context stx = Parent; while (stx != null) { if (stx is Function.FunctionDefine) return true; stx = stx.Parent; } return false; } } public Function.FunctionDefine ParentFunction { get { Context stx = Parent; while (stx != null) { if (stx is Function.FunctionDefine) return stx as Function.FunctionDefine; stx = stx.Parent; } return null; } } public Block ParentBlock { get { Context stx = Parent; while (stx != null) { if (stx is Block) return stx as Block; stx = stx.Parent; } return null; } } public bool IsInLoop { get { Context stx = Parent; while (stx != null) { if (stx is ControlFlow.ForLoop || stx is ControlFlow.DoWhileLoop || stx is ControlFlow.WhileLoop) return true; stx = stx.Parent; } return false; } } public bool IsInSwitch { get { Context stx = this; while (stx != null) { if (stx is ControlFlow.Switch) return true; stx = stx.Parent; } return false; } } public Context GlobalContex { get { if (this.Parent == null) return this; else return this.Parent.GlobalContex; } }
常量应该在最后一刻释放。相同的还有函数的参数定义。SharpC将函数的参数视为特殊的局部变量:在函数第一次运行时分配空间,而在解释器运行到最后时才释放。也算是一种简单的优化。
~Context() { FreeConstantVariables(); if (Parent == null) { if (m_mainFunction != null) FreeFunctionArguments(m_mainFunction); FreeAllFunctionArguments(this); } }
- C语言解释器-7 一切的基础 Context类
- C语言解释器-4 C程序的结构
- C语言解释器LUA
- xrc C语言解释器
- SylixOS C语言解释器
- Context---Context上下文 你必须知道的一切
- 新的C语言:一切都源于FORTRAN
- 新的C语言:一切都源于FORTRAN
- 你需要知道关于C语言指针的一切
- 你需要知道关于C语言指针的一切
- Java之父:C语言是撑起一切的基石
- 【C语言基础一百题4】31-34题 递归的详细解释
- 只有550行的TCL解释器--C语言源程序
- 做一个简单的解释器----小话c语言
- C语言解释器的实现--序(零)
- Picoc C语言解释器的STM32平台移植
- C语言解释器的实现--序(零)
- ******************** C语言的基础 ********************
- Python学习(二) linux终端下运行.py文件的方法
- JPA使用指南 javax.persistence的注解配置
- Hibernate 面试中最常考察的知识点整合
- 【转】活动历时估算所采用的主要方法和技术
- 有关LINUX及驱动方面的网页搜集
- C语言解释器-7 一切的基础 Context类
- Android4.X在Ubuntu12.04(64位)编译
- C# 占位符补位
- 根据URL地址获取网页信息(GET/POST)
- 程序员老鸟写sql语句的经验之谈
- domino用户服务器邮箱爆满如何快速恢复收发邮件
- 从“不太差”到“卓越”
- IOS中二维坐标变换
- The u32 filter