如何在c#中排列匹配的输出?
我正在匹配单词以创建简单的词汇分析器。 下面是我的示例代码和输出 示例代码:如何在c#中排列匹配的输出?,c#,C#,我正在匹配单词以创建简单的词汇分析器。 下面是我的示例代码和输出 示例代码: public class { public static void main (String args[]) { System.out.println("Hello"); } } 输出: public = identifier void = identifier main = identifier class = identifier 正如你们所看到的,我的输出并没有随着输
public class
{
public static void main (String args[])
{
System.out.println("Hello");
}
}
输出:
public = identifier
void = identifier
main = identifier
class = identifier
正如你们所看到的,我的输出并没有随着输入的到来而排列void
和main
在类之后,但在输出中,类
位于末尾。我想在输入匹配时打印结果
c#代码:
CodeCaster是对的。你走的路不对。 我有一个词法分析器由我做了一段时间前作为一个项目 我知道我不应该把东西放在盘子里,但是分析器是C++的,所以你必须改变一些东西。
查看源代码,请尝试至少理解它是如何工作的:从严格意义上讲,所描述行为的原因是,在评估代码中,对
void
的搜索先于对类的搜索。然而,这种方法对于词法分析来说似乎过于简单,因为它只是检查子字符串。我完全赞同上述评论;根据您在大局中试图实现的目标,可能需要一种更复杂的方法。您的代码询问以下问题:
输入是否包含文本“public”
?如果是,请写下“public=identifier”
“void”
?如果是,写下“void=identifier”
“类”
?如果是这样,写下“class=identifier”
“main”
?如果是,写下“main=identifier”
public
、void
、class
和main
是关键字,而不是标识符
在空格上拆分?
因此,您的方法不会帮助您标记输入。更正确的方法是input.Split()
——它将在空白边界处截断输入,并为您提供一个字符串数组。尽管如此,里面还是有很多空白条目
input.Split(新字符[]{'、'\t'、'\r'、'\n'}、StringSplitOptions.RemoveEmptyEntries)
稍好一些,给了我们以下输出:public
、class
、public
、static
、void
、main
、、(字符串
、args[)
,{
,System.out.println(“你好”);
,}
和}
但您会注意到,其中一些字符串包含多个“标记”:(String
,args[])
和System.out.println(“Hello”);
。如果字符串中包含空格,它将被拆分为多个标记。显然,仅拆分空格是不够的
标记化
此时,您将开始编写一个循环,遍历输入中的每个字符,检查它是空白还是标点字符(例如(
,)
,{
,}
,[
,]
,
,
,等等)。这些字符应视为上一个标记的结尾,标点符号也应视为其自身的标记。可以跳过空白
您还必须考虑字符串文本和注释等内容:两个双引号之间的任何内容都不应标记化,而应视为单个“字符串”标记(包括空格)的一部分。此外,字符串还可以包含转义序列,例如生成单个字符的\“
(该双引号不应视为字符串的结尾,而应视为其内容的一部分)
在下一个换行符之前(换行符/序列因操作系统而异),应忽略两个正斜杠之后的任何内容(或将其解析为单个“注释”标记)。在遇到*/
序列之前,应忽略/*
之后的任何内容
数字可以选择以减号开头,可以包含点(或以点开头),也可以是负数的科学符号部分(e..
),还有类型后缀
换句话说,您正在编写一个状态机,根据您所处的状态,它的行为会有所不同:“string”、“comment”、“block comment”、“numeric literal”等等
词法分析
在标记化或作为单独步骤(词法分析)时,为每个标记分配一个类型很有用。public
是一个关键字,main
是一个标识符,1234
是一个整数文本,“Hello”
是一个字符串文本,等等。这将在下一步中有所帮助
解析
现在,您可以继续解析:将令牌列表转换为抽象语法树(AST)。此时,您可以检查令牌列表是否实际是有效代码。您基本上重复了上述步骤,但级别更高
例如,public
、protected
和private
都是关键字标记,它们都是访问修饰符。一旦遇到其中一个,您就知道必须遵循类、函数、字段或属性定义。如果下一个标记是while
关键字,则您会发出错误信号:public while
不是有效的C#构造。但是,如果下一个标记是类
关键字,则您知道它是类定义,并继续解析
所以你又一次得到了一个状态机,但这次你得到了像“类定义”、“函数定义”、“表达式”这样的状态
private void button1_Click(object sender, EventArgs e)
{
if (richTextBox1.Text.Contains("public"))
richTextBox2.AppendText("public = identifier\n");
if (richTextBox1.Text.Contains("void"))
richTextBox2.AppendText("void = identifier\n");
if (richTextBox1.Text.Contains("class"))
richTextBox2.AppendText("class = identifier\n");
if (richTextBox1.Text.Contains("main"))
richTextBox2.AppendText("main = identifier\n");
}