MYC编译器源码分析之程序入口

前文.NET框架源码解读之MYC编译器讲了MyC编译器的架构,整个编译器是用C#语言写的,上图列出了MyC编译器编译一个C源文件的过程,编译主路径如下:

  1. 首先是入口Main函数用来解析命令行参数,读取源文件,并开始编译过程。Main函数在MyC.cs文件,而IO.cs文件主要保存读取源码文件的相关操作。下表是Main函数的源码(批注用注释的方式显示),IO.cs文件用单独的一个小节说明:
public static void Main()
{try
{// 看源码注释,代码是99年写的,也就是说.NET当年正在开发中// 可能那个时候虚拟机都没有做好向Main函数传递命令行参数的开发// 用了下面这个奇葩方法获取程序的命令行参数String[] args = Environment.GetCommandLineArgs();// 初始化读取源文件的IO对象,该对象负责将源文件以字节流的方式// 输出给下一个对象 – 词法分析Io prog = new Io(args);// 词法分析对象,该对象的工作是过滤掉源码中不必要的字符,比如空格// 注释之类的,并且把源码中的字符归类 – Tokenize,以便语法分析器// 更方便的解析语法Tok tok = new Tok(prog);// 语法分析对象,解析完毕后即是代码生成阶段,但一般语法分析过程// 都只会生成语法树,这样的设计可以对接多种结果文件输出手段。比如// 说,本例中生成可执行文件的exe.cs和生成IL源码的asm.cs都是通过// 遍历语法树,使用不同的输出策略生成结果文件的Parse p = new Parse(prog, tok);// 采用自顶向下的方式进行语法解析p.program();// 编译工作已经完成,关闭打开的源文件句柄等资源prog.Finish();}catch (Exception e)
{// 编译过程中有任何错误,即中断处理,打印错误消息并退出程序Console.WriteLine("Compiler aborting: " + e.ToString());}
}

  

  1. MyC的语法很简单,因此编译过程是很干净的词法分析、语法分析、代码生成和结果输出的过程。其中词法分析代码在tok.cs,语法分析代码在parse.cs中,Emit.cs处理代码生成,而Asm.cs和Exe.cs分别根据命令行参数的设置,来生成最终的可执行文件并选择是否输出IL源码。 IO.cs - IO处理 将源文件读取进内存,并采用流式处理的代码都放在IO这个类里面,IO的构造函数解析命令行参数,并打开源文件,等待Tok.cs里面代码的指令将源文件的字符一个个读进内存并处理,下面是它的构造函数的源码:
public Io(String[] a){int i;args = a;// 解析命令行参数,并根据参数打开内部的控制开关,详情请看下面对ParseArgs// 函数的源码解读ParseArgs();// 打开要编译的源文件ifile = new FileStream(ifilename, FileMode.Open,FileAccess.Read, FileShare.Read, 8192);// 如果源文件不存在,报错退出if (ifile == null){Abort("Could not open file '"+ifilename+"'\n");
}// 采用流式处理方式读取源文件rfile = new StreamReader(ifile); // open up a stream for reading// 根据源文件的名称设定结果输出文件的文件名i = ifilename.LastIndexOf('.');if (i < 0)Abort("Bad filename '"+ifilename+"'");int j = ifilename.LastIndexOf('\\');if (j < 0)j = 0;elsej++;classname = ifilename.Substring(j,i-j);// 根据命令行参数决定是生成.exe、.dll等可执行文件,还是输出包含// IL源码的.lst文件 if (genexe)ofilename = classname+".exe";if (gendll)ofilename = classname+".dll";if (genlist)
{
// 如果是要输出IL源码,因为原来的可执行文件也要输出,需要创建一个新的文件lst_ofilename = classname+".lst";lst_ofile = new FileStream(lst_ofilename, FileMode.Create,FileAccess.Write, FileShare.Write, 8192);if (lst_ofile == null)Abort("Could not open file '"+ofilename+"'\n");lst_wfile = new StreamWriter(lst_ofile);}}

  

编译器是在IO类里处理命令行参数的,参数解析实际上是一些字符串处理的活,本文解释下关键代码:

void ParseArgs(){int i = 1;// 程序至少需要两个参数,否则就输出帮助文字并退出if (args.Length < 2){Abort("myc [/debug] [/nodebug] [/list] [/dll] [/exe] [/outdir:path] filename.myc\n");}// 逐个遍历命令行参数while (true){if (args[i][0] != '/')break;// 处理 /? 这个参数,即输出帮助文本if (args[i].Equals("/?")){Console.WriteLine("Compiler options:\n  myc [/debug] [/nodebug] [/list] [/dll] [/exe] [/outdir:path] filename.myc\n");Environment.Exit(1);}
// 如果有 /debug 参数,则打开内部的 gendebug 开关,这个开关在代码生成的过程
// 中会用到if (args[i].Equals("/debug")){gendebug = true;i++;continue;}
// ... ... 跳过类似的代码
// 如果有 /outdir 参数,则获取命令行中指定的目录路径if (args[i].Length > 8 && args[i].Substring(0,8).Equals("/outdir:")){genpath = args[i].Substring(8);i++;continue;}
// 前面那么多的if相当于switch … case … default 块里面的 case 处理路径
// 下面这段代码即是 default 处理路径 – 如果命令行参数符合前面的if条件
// 都会执行里面的 continue 子句跳出循环,能执行到这里,说明参数
// 是无法识别的参数,因此报告错误并退出执行Abort("Unmatched switch = '"+args[i]+"'\nArguments are:\nmyc [/debug] [/nodebug] [/list] [/dll] [/exe] [/outdir:path] filename.myc\n");}// 如果前面的循环执行完毕,还有参数列表未处理,说明输入了不支持的参数if (args.Length-i != 1){Abort("myc [/debug] [/nodebug] [/list] [/dll] [/exe] [/outdir:path] filename.myc\n");
}// 最后一个参数是要编译的源文件路径ifilename = args[args.Length-1]; // filename is last}

  

IO类中大部分函数都是为Tok.cs服务的,因此其它函数在解释词法分析的时候说明

转载于:https://www.cnblogs.com/vowei/p/4329568.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/574752.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

easyui tree动态加载_动态路由:Gin vs SpringMVC

这两天在接触Gin&#xff0c;对它的动态路由功能比较感兴趣&#xff0c;特意做了笔记&#xff0c;顺便跟SpringMVC作下对比。1.简介Gin是使用Go/golang语言实现的HTTP Web框架。接口简洁,性能极高。截止1.4.0版本,包含测试代码,仅14K,其中测试代码9K左右,也就是说框架源码仅5K左…

伍德里奇---计量经济学第6章部分计算机习题详解(stata),伍德里奇---计量经济学第6章部分计算机习题详解(STATA)...

所以&#xff0c;log bwg t7.5840.0180npvis?0.00041npvis20.0254mage?0.00041mage20.1370.00370.000120.0093 (0.00015)n1764&#xff0c;R20.0256&#xff0c;R20.0234。当孩子的出生体重最大时&#xff0c;对应的年龄为mage? β12β20.0254[2?0.00041] 30.96&#xff0c…

经验原石_哔哩哔哩(b站)手机版经验原石怎么样获得?在哪里使用?有期限吗?...

大家都知道原石是一种道具&#xff0c;但是怎么用&#xff0c;有什么用大家却不太清楚接下来我就给大家介绍一下原石有什么用。那就是原石是可以用来增我们加头衔经验的&#xff0c;大家都知道头衔有两种&#xff0c;一种是可以升级的&#xff0c;一种是不可以升级的。我们的这…

vue菜单点击html,基于vue.js实现侧边菜单栏

侧边菜单栏应该是很多项目里必不可少的 自己手写了一个下面是效果图下面就说一下实现的过程 还是比较简单的首先导入一下需要的文件接下来就是我的html主页系统用户管理权限设置操作日志设备运行日志防区 防区管理警报 历史报警曲线报表统计警情处理设备然后是css* {margin: 0;…

centos7 mysql启动失败_Mysql主从复制

​好在&#xff0c;别人如何分析我&#xff0c;跟我本身是一点关系也没有的。(by 三毛)主从复制的常见用途1.数据备份对备份来说,复制是一项很有意义的技术补充,但复制既不是备份也不能取代备份2.负载均衡(读写分离)通过MySQL主从复制,可以把写操作放在主库(master)&#xff0c…

【原创】shadowebdict开发日记:基于linux的简明英汉字典(三)

全系列目录&#xff1a; 【原创】shadowebdict开发日记&#xff1a;基于linux的简明英汉字典&#xff08;一&#xff09;【原创】shadowebdict开发日记&#xff1a;基于linux的简明英汉字典&#xff08;二&#xff09;【原创】shadowebdict开发日记&#xff1a;基于linux的简明…

计算机应用基础知道,谁知道计算机应用基础练习题的答案?

谁知道计算机应用基础练习题的答案&#xff1f;46&#xff0e;简述美籍匈牙利数学家冯诺依曼(Von Neumann)在1946年提出的关于计算机的体系结构和“程序存储”的设计思想。47&#xff0e;简要说明Windows98中安装存放在CD—ROM上的应用程序的操作过程。48&#xff0e;简述Windo…

springboot分页展示功能_springboot实现分页

这里项目是springboot&#xff0c;mybatis&#xff0c;thymeleaf&#xff0c;实现我自制的商城项目后台页面的分页功能。参考我之前总结的分页&#xff0c;简单的处理一下就可以了上代码首先写一个超链接跳转到controller层的方法商品管理然后写后台controller层代码/*** 后台商…

Delphi中的基础数据类型

参考http://www.cnblogs.com/del/archive/2007/12/04/982167.html 在学习之初&#xff0c;在这么多的数据类型中&#xff0c;最好记住这五种标准数据类型&#xff08;整型、实型、字符型、字符串型、布尔类型&#xff09;和这五种类型中的最常用的类型&#xff0c;其他类型在以…

计算机程序编辑器中文版,小说编辑器(Atomic Scribbler)

AtomicScribbler是一款功能强大的电脑小说编辑器&#xff0c;快速编辑、创作你的小说&#xff0c;也可以直接导入文本二次编辑&#xff0c;内置了丰富的文字编辑工具&#xff0c;完全能够满足日常创作小说、编辑文字使用需求。。相关软件软件大小版本说明下载地址AtomicScribbl…

信号与系统sa函数求积分_瞎扯数学分析微积分(1~4)

算法数学之美日期&#xff1a;2019年10月30日正文共&#xff1a;12013字0图预计阅读时间&#xff1a;31分钟来源:豆瓣 wxmang这一篇帖子主要介绍人类如何从一个基于几何直观或直觉的计算技巧或计算方法&#xff0c;进化到逻辑基础严密的公理体系的例子&#xff0c;想说明人类抽…

Cocos2D研究院之CCNode详解(三)

http://www.xuanyusong.com/archives/950 上一章我们了解了cocos2d的项目路径以及工作原理&#xff0c;这次作者要真刀真枪地讲解代码了&#xff0c;咱们先来看看cocos2d最常用、也是作者认为最核心的类——CCNode。 之前说过&#xff0c;cocos2d的所有类都以CC开头&#xff0c…

大一计算机导论期中考试,大一计算机导论试题

大一计算机导论试题1. 用一个字节表示无符号整数&#xff0c;其最大值是十进制数( )。A. 256 B. 255 C. 127 D. 1282. 一个完整的计算机系统应包括( )。A. 运算器、控制器和存储器 B. 主机和应用程序C. 硬件系统和软件系统 D. 主机和外部设备3. 微机中的CPU是指( )。A. 内存和运…

eplan怎样创建和修改图框_EPLAN标题页及图框的设计

标题页理解为特殊的表格&#xff0c;选择“工具”--“主数据”--“表格”---“打开”&#xff0c;弹出“打开表格”对话框&#xff0c;文件类型“标题页/封页.f26”,选择需要打开的表格&#xff0c;点击打开按钮&#xff0c;表格中的元素&#xff1a;1.文本&#xff1a;表示普通…

计算机第二课堂教学计划,小学的第二课堂教学计划

小学的第二课堂教学计划开展内容丰富&#xff0c;形式多样的第二课堂活动&#xff0c;通过活动&#xff0c;使学生受到爱国主义及道德情感教育&#xff0c;掌握技能&#xff0c;全面提高他们的素质&#xff0c;使其成为全面发展的一代新人。下面是小编分享给大家的小学的第二课…

webstorm两个文件比对_webstorm怎么更改文件名称?或者是重命名

在开发的过程中&#xff0c;我们一个项目中会有很多的文件&#xff0c;每个文件中也会有很多的层级关系&#xff0c;有时候新建一个文件的时候&#xff0c;一不下心就会出错&#xff0c;位置出错我们可以移动更换位置&#xff0c;名称命名错误&#xff0c;我们可以重命名&#…

using

using关键字有两个主要用途&#xff1a; 作为指令&#xff0c;为命名空间创建别名或导入其他命名空间中的类型。作为语句&#xff0c;定义一个范围&#xff0c;在此范围的末尾将释放对象。using指令 using指令有两个用途&#xff1a; 导入其他命名空间中的类型&#xff1a;usin…

秒懂物理计算机出题规划,57张动图, 让你秒懂高中物理原理! 考试次次拿第一

原标题&#xff1a;57张动图, 让你秒懂高中物理原理! 考试次次拿第一物理不像语文或者英语&#xff0c;文科的东西记的东西偏多&#xff0c;理解的成分偏少&#xff0c;但物理理解的成分很重&#xff0c;要死记硬背的东西反而很少。要想把物理学好&#xff0c;先要把简单的概念…

matlab机器人自动分拣_极智嘉分拣系统落地 助力打造智慧物流引擎

全球AMR引领者极智嘉(Geek)近日宣布已为知名跨境电商企业棒谷科技(Banggood)部署全柔性智能AMR分拣系统,以支持棒谷科技日益增长的海外跨境电商业务需求。棒谷科技业务体系遍及全球200多个国家。随着电商业务的加速转变,棒谷科技的发展面临线上销售增长快、业务需求难以预测、劳…

$arr['id'],$arr[id]的区别

说白了区别就是当不加的时候我们首先会考虑的是这个id是不是一个常量 例如&#xff1a; define("abc",ABC); 那么实际上$arr[id] $arr[ABC]; 所以在这个过程中就会多加了一步操作。那么引申一个问题就是 在$arr取值时尽量使用单引号就会比直接写或者加双引号就会更快…