设计一门脚本语言——(二)预处理

本文介绍如何设计脚本语言的预处理部分,使用C#作为实现语言。通过建立虚拟机、预处理类Lexel,将代码分解成Token。预处理涉及识别和处理分割Token的符号,如'_'、'@'、';'、'='等,并考虑空格等无意义的分隔符。预处理代码分析了如何构建并使用StringBuilder和List来存储和处理Token,最后展示了测试结果。
摘要由CSDN通过智能技术生成

二、预处理

开始写代码吧,用什么语言好呢?CC++JavaC#

随便,什么顺手就用什么,语言只是工具而已。

这学期开了一门新课,.Net程序设计,接触了C#,那就那它吧,也好熟悉这么语言

新建一个工程Snail(慢慢来的意思~哈哈),添加一个文件main.cs

代码如下:

namespace Snail

{

public static void Main()

{

Console.Read();
}

}

这就是入口函数了,相当于Cmain函数

既然我们要做预处理,那单独建一个类吧,但我们不急着编写代码,而是想想它是怎么工作的。

既然我们是解释型脚本,做词法分析的时候,肯定不能一次性的就分析完了吧,肯定是边运行,边分析。为了加快速度和简化词法分析,所以需要预处理,把一长串的代码,分成一个个单独的字符串

好,我大概想到了

首先,我们需要一个虚拟机(别被名字忽悠了,没那么高深)

新建一个Snail.cs写一点基本的代码

public class Snail

{

public Snail()

{
}

public void Execute(string code)

{
}

}

然后在Main函数里写入

Snali s = new Snail();

string code = File.ReadAllText(“test.txt”); // 把文件test.txt的内容全读取到code

s.Execute(code);

编译是可以的,不过估计运行错误,因为没有test.txt。当然,你可以在程序目录创建一个test.txt,这样运行是没有错了,但什么也不会显示,因为代码什么都没做。别急,下一步,我们开始预处理

新建一个Lexel.cs文件

public class Lexel

{

public Lexel()

{

}

public void Start(string code)

{
}
}

Start(本来想改Pretreatment的,但这单词太难打了)函数负责处理传入的参数code,那么这个函数需要完成什么样的功能呢?

我想把脚本的代码分解为一个个小的字符串,每个字符串为一个基本单位,称为Token

那依据什么来分割字符串呢?

对于如下代码

def_main

  @x = 10;

end

可以用符号_ @ ; =和空格等来分割

其中,这些符号是需要的,就是说,它不只起到分割Token的作用,它本事也是一个Token

还有一些,比如空格,仅仅起到一个分割Token的作用

好,有了这么一个基本的概念。可以动手写代码了

首先,申明两个数组

private char[] invalidSigns = new char[]{ ‘\r’, ‘\n’, ‘ ’, ‘\t’ };

这些字符是不需要的,仅仅起到分割作用

private char[] splitSigns = new char[]

{

 ‘_’, ‘@’, ‘=’, ‘;’
};

然后在申请一个

private List<string> Tokens = new List<string>(); // 不了解C#的朋友,可以当它是一个队列,或者说是C的链表吧~差不多的

好了,有了这两个数组和一个List,我们可以开始编写Start函数了

下面有些东西,比如StringBuilderforeach,不了解的,可以百度下C#的知识,以后就不单独解释这些东西了

public void Start(string code)

{

try

{

StringBuilder line = new StringBuilder();

// 分析每一个字符

foreach char in code )

{

// 如果这个字符在invalidSigns数组中

// 那么说明这个字符是一个分割字符,而且本身不被程序需要

if ( invalidSigns.Contains<char>(c))

{

// 添加字符串到Token

if ( line.Length != 0 ) 

{

Tokens.Add(line.ToString());

Tokens.Clear();

}

continue;
}

// 如果这个字符在splitSigns数组中

// 那么说明这个字符是一个分割字符,本身被程序所需要

if ( splitSigns.Contanis<char>(c) )

{

// 添加字符串到Tokens

if ( line.Length != 0 )

{

Tokens.Add(line.ToString();

Tokens.Clear();
}

// 添加这个分隔符本身到Tokens

Tokens.Add(c.ToString());

}

}

}

catch(Exception ex) // 异常处理(关于这个,可百度之~

{

throw ex;
}

}

代码很简短,因该能表达的清楚吧。

意思很简单,把一长串的代码,分成我想要的Tokens

测试下:

test.txt中输入

def_main

@x=10;

end

SnailExecute中(不会忘记了吧,这可是我们的虚拟机,在main函数中被调用)输入

Lexel lexel = new Lexel();

lexel.Start(code);

foreach (string token in lexel.Tokens) // 为了测试,把Tokensprivate改为public

{

Console.WriteLine(token);
}

运行结果

def

_

main

@

x

=

10

;

end

成功。下一步开始词法分析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值