在C#中设计词法分析器和解析器

时间:2015-03-22 16:15:40

标签: c# lexical-analysis

我将在Gold Parse Builder(GPB)的帮助下设计一个编译器来设计词法分析器和解析器。我有投入 x1 = x3 /(x2 / x5);

需要输出如下:

[  1]   Variable         x1 at 1,1
[  2]     Equals          = at 1,4
[  3]   Variable         x3 at 1,6
[  4]     Divide          / at 1,8
[  5]  LeftParen          ( at 1,9
[  6]   Variable         x2 at 1,10
[  7]     Divide          / at 1,12
[  8]   Variable         x5 at 1,13
[  9] RightParen          ) at 1,15
[  10]       Semi          ; at 1,16

我可以打印此输出,因为我有这方面的语法。但我的问题是如何像第一个索引x1一样逐个获取令牌(如果我尝试通过char读取它然后输出x和1而不是x1,我尝试将其从白色空间拆分然后x3 /( X2 / X5))。

让我对此有所了解

提前致谢。

1 个答案:

答案 0 :(得分:0)

您可以使用正则表达式或通过循环字符串并读取相关信息来制作解析器,如下面的代码。

我只包含解析器本身,因为其余部分可以从它调用的方式或如何使用它来推断。你仍然需要检查令牌在哪个位置开始,但我想这应该很简单。

public class FormulaReader : IFormulaReader
{
    protected static readonly IToken EQUALIZE = new Token(TokenType.EQUALIZER, "=");
    protected static readonly IToken ADD = new Token(TokenType.MODIFIER, "+");
    protected static readonly IToken SUBTRACT = new Token(TokenType.MODIFIER, "-");
    protected static readonly IToken DIVIDE = new Token(TokenType.MODIFIER, "/");
    protected static readonly IToken MULTIPLY = new Token(TokenType.MODIFIER, "*");
    protected static readonly IToken GROUPSTART = new Token(TokenType.GROUPSTART, "(");
    protected static readonly IToken GROUPEND = new Token(TokenType.GROUPEND, ")");

    public IFormula Parse(string textRepresentation)
    {
        IList<IToken> tokenList = new List<IToken>()
        {
            EQUALIZE, ADD, SUBTRACT, DIVIDE, MULTIPLY, GROUPSTART, GROUPEND
        };
        IFormula formula = new Formula();
        IToken currentToken = new Token(TokenType.IDENTIFIER, "");
        bool equalizerFound = false;

        for (int i = 0, len = textRepresentation.Length; i < len; i++)
        {
            string item = textRepresentation[i].ToString();
            if (item == " ")
            {
                continue;
            }
            IToken selectedToken = (from t in tokenList where string.Equals(t.Text, item) select t).FirstOrDefault();
            if (selectedToken == null)
            {
                currentToken.Text += item;
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(currentToken.Text))
                {
                    // contains an identifier
                    formula.Add(currentToken, equalizerFound);
                }
                if (selectedToken.TokenType != TokenType.EQUALIZER)
                {
                    formula.Add(selectedToken, equalizerFound);
                }
                else
                {
                    equalizerFound = true;
                }
                currentToken = new Token(TokenType.IDENTIFIER, "");
            }
        }

        return formula;
    }
}