c# – 编写一个非常简单的解析器

前端之家收集整理的这篇文章主要介绍了c# – 编写一个非常简单的解析器前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在编写一个非常基本的Web服务器,它必须支持极其有限的特殊服务器端脚本语言.基本上我需要支持的是“回声”,只有2个操作数的加法/减法/乘法(没有除法),一个简单的“date()”函数输出日期并使用“&”运算符以连接字符串.

一个例子可能是:

echo "Here is the date: " & date();
echo "9 x 15 = : & 9*15;

我已经完成并创建了生成令牌所需的代码,但我不确定我是否使用了正确的令牌.

我为以下内容创建了令牌:

ECHO - The echo command
WHITESPACE - Any whitespace
STRING - A string inside quotations
DATE - The date() function
CONCAT - the & operator for concatenation
MATH - Any instance of binary operation (5+4,9*2,8-2,etc)
TERM - The terminal character (;)

MATH我特别不确定.通常我看到人们专门为整数创建一个令牌,然后为每个运算符创建一个令牌,但由于我只想允许二进制操作,我认为将它组合成一个令牌是有意义的.如果我要分开做所有事情,我将不得不做一些额外的工作,以确保我从未接受过“5 4 1”.

问题1是我在正确的轨道上使用哪些令牌?

我的下一个问题是如何使用这些令牌来确保正确的语法?我想到的方法基本上是说:“好吧,我知道我有这个令牌,这里是一个令牌列表,根据当前令牌允许接下来.列表中的下一个令牌是什么?”

基于此,我列出了所有令牌以及令牌后有效的令牌(为简单起见,不包括空格).

ECHO        ->      STRING|MATH|DATE
STRING      ->      TERM|CONCAT
MATH        ->      TERM|CONCAT
DATE        ->      TERM|CONCAT
CONCAT      ->      STRING|MATH|DATE

问题是我根本不确定如何最好地实现这一点.我真的需要跟踪空白,以确保令牌之间有空格.但这意味着我必须一次向前看两个令牌,这更令人生畏.我也不确定如何管理“有效的下一个令牌”的东西,而不仅仅是一些令人厌恶的if块.我是否应该在尝试实际执行脚本之前检查有效语法,还是应该立即执行所有操作并在遇到意外令牌时抛出错误?在这个简单的例子中,一切都将从左到右完美地解析,没有真正的优先规则(除了MATH之外,但这也是为什么我将它组合成一个令牌的一部分,即使它感觉不对.)即使这样,我也不会不介意设计更具可扩展性和优雅的解决方案.

在我关于编写解析器的研究中,我看到很多关于创建“accept()”和“expect()”函数的引用,但是我找不到任何关于它们应该做什么或它们应该如何工作的清晰描述.

我想我只是不确定如何实现它,然后如何在一天结束时实际产生一个结果字符串.

我是否朝着正确的方向前进,是否有人知道可以帮助我了解如何最好地实现这样简单的事情的资源?我需要手动完成,不能使用像ANTLR这样的工具.

在此先感谢您的帮助.

解决方法

您需要做的第一件事就是丢弃所有的空格(除了字符串中的空格).这样,当您将令牌添加到令牌列表时,您确定该列表仅包含有效令牌.例如,请考虑以下声明:
echo "Here is the date: " & date();

我将开始标记并首先根据空白区域分离回声(是的,此处需要使用空格来分隔它,但在此之后无效).然后令牌器遇到双引号并继续读取所有内容,直到找到结束双引号.同样,我为&,date和()创建了单独的标记.

我的令牌列表现在包含以下令牌:

echo@H_301_45@
“Here is the date: “@H_301_45@
&@H_301_45@
date@H_301_45@
()@H_301_45@

现在,在解析阶段,我们读取这些令牌.解析器循环遍历令牌列表中的每个令牌.它读取echo并检查它是否有效(基于您对该语言的规则/功能).它前进到下一个标记,并查看它是日期,字符串还是数学.同样,它会检查其余的令牌.如果在任何时候,不应该存在令牌,则可以抛出指示语法错误或其他内容错误.

对于数学语句标记化,仅分别包含括号中的表达式和其余的操作数和运算符.例如:9/3(7-3 1)将具有令牌9,/,3和(7-3 1).由于每个令牌都有自己的优先级(您在令牌结构中定义),因此您可以从最高优先级令牌开始评估到最低令牌优先级.这样您就可以使用优先级表达式.如果您仍然有困惑,请告诉我.我会给你写一些示例代码.

原文链接:https://www.f2er.com/csharp/100258.html

猜你在找的C#相关文章