一个加减乘除的词法分析器

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;

namespace SalaryCalculationProject
{
    /// <summary>
    /// 薪酬集合
    /// </summary>
    public class SalaryItems
    {
        private List<string> strOperators; //算术运算符
        private List<string> strBaseItem; //存放操作数
        private List<string> strItems;


        private string salaryItemsTitle; //薪酬项集合的标题
        private DateTime SalaryItemsTime; //计算的时间


        private string strFormula;
        private static readonly char[] spliter = new char[] { ' ' };
        private static readonly char[] operatorMatrix = new char[] { '+', '-', '*', '/', '(', ')' };
        private static readonly int[] operatorValues = new int[] { 0, 0, 1, 1, -1, -2 };
        private string[] spliterMatrix;
        private StringBuilder strFormulaSb;
        private StringBuilder strSb;
        private int i;
        private int j;
        private int currentOperatorValue;
        private string strTmp;

        /// <summary>
        /// 薪酬项的集合
        /// </summary>
        public SalaryItems()
        {
            strOperators = new List<string>();
            strItems = new List<string>();
            strBaseItem = new List<string>();
            strFormulaSb = new StringBuilder();
            strSb = new StringBuilder();


            //添加基础表和二级表的表项
        }


        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="salaryItemsTitle">标题</param>
        public SalaryItems(string salaryItemsTitle)
            : this()
        {
            this.salaryItemsTitle = salaryItemsTitle;
        }


        /// <summary>
        /// 接受公式
        /// </summary>
        /// <param name="strExpression">公式表达式</param>
        /// <returns>是否符合表达式</returns>
        public bool AcceptExpression(string strExpression)
        {
            int Rst = 0;
            int ILen = 0;
            int OLen = 0;
            strFormulaSb.Remove(0, strFormulaSb.Length);
            strFormula = strExpression;
            spliterMatrix = strFormula.Split(spliter);
            if (spliterMatrix == null || spliterMatrix.Length == 0)
            {
                return false;
            }


            strItems.Clear();
            strBaseItem.Clear();


            for (i = 0; i < spliterMatrix.Length; ++i)
            {
                strItems.Add(spliterMatrix[i]);
            }


            strItems.Insert(0, "(");
            strItems.Add(")");


            for (i = 0; i < strItems.Count; ++i)
            {
                if (IsStrOperator(strItems[i], out Rst)) //如果是操作符
                {
                    if (strItems[i] == "(")
                    {
                        strOperators.Add(strItems[i]);
                        currentOperatorValue = Rst;
                        continue;
                    }
                    else if (strItems[i] == ")")
                    {
                        while ((OLen = strOperators.Count) > 0 && (currentOperatorValue = GetOperatorValue(strOperators[OLen - 1])) != -1)
                        {
                            if (currentOperatorValue > Rst)
                            {
                                if ((ILen = strBaseItem.Count) >= 2 && (OLen = strOperators.Count) >= 2)
                                {
                                    strSb.Remove(0, strSb.Length);
                                    strSb.Append(strBaseItem[ILen - 2]);
                                    strSb.Append(" ");
                                    strSb.Append(strBaseItem[ILen - 1]);
                                    strSb.Append(" ");
                                    strSb.Append(strOperators[OLen - 1]); //后缀表达式                               


                                    strBaseItem.RemoveAt(ILen - 1); //将操作数和运算符弹出
                                    strBaseItem.RemoveAt(ILen - 2);
                                    strOperators.RemoveAt(OLen - 1);
                                    strBaseItem.Add(strSb.ToString());
                                }
                                else
                                {
                                    return false; // 公式有误
                                }
                            }
                            else
                            {
                                return false;
                            }
                        }


                        if (strOperators.Count > 0)
                        {
                            strOperators.RemoveAt(strOperators.Count - 1);
                        }


                        currentOperatorValue = Rst;
                        continue;
                    }


                    if (currentOperatorValue != -1 && Rst > currentOperatorValue)
                    {
                        if (currentOperatorValue == -2) //如果为')'
                        {
                            if (strOperators.Count > 0)
                            {
                                if (GetOperatorValue(strOperators[(OLen = strOperators.Count) - 1]) >= Rst)
                                {
                                    if ((ILen = strBaseItem.Count) >= 2)
                                    {
                                        strSb.Remove(0, strSb.Length);
                                        strSb.Append(strBaseItem[ILen - 2]);
                                        strSb.Append(" ");
                                        strSb.Append(strBaseItem[ILen - 1]);
                                        strSb.Append(" ");
                                        strSb.Append(strOperators[OLen - 1]);


                                        strBaseItem.RemoveAt(ILen - 1);
                                        strBaseItem.RemoveAt(ILen - 2);
                                        strOperators.RemoveAt(OLen - 1);
                                        strBaseItem.Add(strSb.ToString());
                                    }
                                    else
                                    {
                                        return false;
                                    }
                                }
                            }
                        }


                        strOperators.Add(strItems[i]);
                        if (i + 1 < strItems.Count)
                        {
                            if (!IsStrOperator(strItems[i + 1], out Rst))
                            {
                                strBaseItem.Add(strItems[i + 1]);
                                if ((ILen = strBaseItem.Count) > 1 && (OLen = strOperators.Count) > 1)
                                {
                                    strSb.Remove(0, strSb.Length);
                                    strSb.Append(strBaseItem[ILen - 2]);
                                    strSb.Append(" ");
                                    strSb.Append(strBaseItem[ILen - 1]);
                                    strSb.Append(" ");
                                    strSb.Append(strOperators[OLen - 1]);


                                    strBaseItem.RemoveAt(ILen - 1);
                                    strBaseItem.RemoveAt(ILen - 2);
                                    strOperators.RemoveAt(OLen - 1);
                                    strBaseItem.Add(strSb.ToString());


                                    ++i;
                                }
                                else
                                {
                                    return false;
                                }
                            }
                            else if (Rst == -1) //为左括号
                            {
                                currentOperatorValue = Rst;
                                strOperators.Add(strItems[i + 1]);
                                ++i;
                            }
                            else
                            {
                                return false;
                            }
                        }
                    }
                    else if (currentOperatorValue != -1 && Rst == currentOperatorValue)
                    {
                        if ((ILen = strBaseItem.Count) >= 2 && (OLen = strOperators.Count) >= 2)
                        {
                            strSb.Remove(0, strSb.Length);
                            strSb.Append(strBaseItem[ILen - 2]);
                            strSb.Append(" ");
                            strSb.Append(strBaseItem[ILen - 1]);
                            strSb.Append(" ");
                            strSb.Append(strOperators[OLen - 1]);


                            strBaseItem.RemoveAt(ILen - 1);
                            strBaseItem.RemoveAt(ILen - 2);
                            strOperators.RemoveAt(OLen - 1);
                            strBaseItem.Add(strSb.ToString());
                        }
                        else
                        {
                            return false; // 公式有误
                        }


                        strOperators.Add(strItems[i]);
                        currentOperatorValue = Rst;
                    }
                    else if (currentOperatorValue == -1)
                    {
                        strOperators.Add(strItems[i]);
                        currentOperatorValue = Rst;
                    }
                }
                else
                {
                    strBaseItem.Add(strItems[i]);
                }
            }


            if (strBaseItem.Count != 1)
            {
                return false;
            }


            return true;
        }


        public string GetSuffixFormula()
        {
            return strBaseItem[0];
        }


        /// <summary>
        /// 判断是不是操作符
        /// </summary>
        /// <param name="strItem">公式项</param>
        /// <param name="nResult">优先级</param>
        /// <returns>是否是操作符</returns>
        public bool IsStrOperator(string strItem, out int nResult)
        {
            if (strItem != null && strItem.Length == 1)
            {
                for (j = 0; j < operatorMatrix.Length; ++j)
                {
                    if (strItem[0] == operatorMatrix[j])
                    {
                        nResult = operatorValues[j];
                        return true;
                    }
                }
            }


            nResult = -3;
            return false;
        }


        /// <summary>
        /// 返回运算符的优先级
        /// </summary>
        /// <param name="strOper">运算符</param>
        /// <returns>优先级</returns>
        private int GetOperatorValue(string strOper)
        {
            for (j = 0; j < operatorMatrix.Length; ++j)
            {
                if (strOper.CompareTo(operatorMatrix[j].ToString()) == 0)
                {
                    return operatorValues[j];
                }
            }


            return -3;
        }

        /// <summary>
        /// 判断是不是+-*/
        /// </summary>
        /// <param name="op">字符串</param>
        /// <returns></returns>
        public bool IsOperator(string op)
        {
            bool oop = false;


            string[] operator1 = new string[] { "+", "-", "*", "/" };


            for (int i = 0; i < operator1.Length; i++)
            {
                if (operator1[i] == op)
                { oop = true; break; }
            }
            return oop;
        }
    }
}

测试程序

    class Program
    {
        static string strFormula = "( A + 3 ) / 4 + ( F + G ) * ( K - A ) / 3 - ( ( J - F ) * H )";
        static void Main(string[] args)
        {
            SalaryItems salaryItems = new SalaryItems("Test");

            if (salaryItems.AcceptExpression(strFormula))
            {
                Console.WriteLine("{0}\n", strFormula);
                Console.WriteLine(salaryItems.GetSuffixFormula());
            }
            else
            {
                Console.WriteLine("Bad");
            }

            Console.Read();
        }
    }


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值