C language interpreter-19 syntax analysis (4)

Source: Internet
Author: User

Take the + operator as an example to describe the process of operator analysis:

private bool ParseExpression_Plus(Context ctx, SourceCode src, ref Expression.ExpressionNode expTree)        {            if (src.TestNextChar('=')) // +=            {                src.NextChar();                src.NextChar(); // skip '+='                return AddOperatorNode(ref expTree, new Expression.Operator.Binary.AddAssign());            }            else            {                if (src.TestNextChar('+')) // self ++                {                    src.NextChar();                    src.NextChar(); // skip '++'                    if (expTree == null)                    {                        return AddOperatorNode(ref expTree, new Expression.Operator.Unary.PrefixIncrease());                    }                    else                    {                        if (m_lastExpNode == null || (m_lastExpNode != null && m_lastExpNode.Token is Expression.Operator.Operator)) //                         {                            return AddOperatorNode(ref expTree, new Expression.Operator.Unary.PrefixIncrease());                        }                        else                            return AddOperatorNode(ref expTree, new Expression.Operator.Unary.PostfixIncrease());                    }                }                else                {                    src.NextChar(); // skip '+'                    if (m_lastExpNode == null || (m_lastExpNode != null && m_lastExpNode.Token is Expression.Operator.Operator))                        return AddOperatorNode(ref expTree, new Expression.Operator.Unary.Plus());                    else                        return AddOperatorNode(ref expTree, new Expression.Operator.Binary.Add());                }            }        }

Finally, the method to obtain the value type is as follows:

private Expression.Operand.Value GetNumberValue(Context ctx, SourceCode src)        {            // Test '0x'            if (src.CurrentChar == '0' && src.TestNextChar(SourceCode.HexMark))            {                return GetHexValue(ctx, src);            }            else            {                return GetIntOrFloatValue(ctx, src);            }        }        private Expression.Operand.Value GetHexValue(Context ctx, SourceCode src)        {            int start = src.Column;            src.NextChar(); // skip '0'            src.NextChar(); // skip 'x'            do            {                if (SourceCode.IsDigit(src.CurrentChar) ||                    (src.CurrentChar >= 'a' && src.CurrentChar <= 'f') ||                    (src.CurrentChar >= 'A' && src.CurrentChar <= 'F'))                {                    src.NextChar();                }                else                {                    break;                }            } while (true);            if (src.Column - start < 3)                if (!NotifyError(ctx, src.Location, ParsingErrorType.FormatError, "Invalid hex format."))                    return null;            if (src.Column - start > 10)                if (!NotifyError(ctx, src.Location, ParsingErrorType.FormatError, "Invalid hex format."))                    return null;            string hexStr = src.Text.Substring(start + 2, src.Column - start - 2);            UInt32 val = UInt32.Parse(hexStr, System.Globalization.NumberStyles.HexNumber);            if (hexStr.Length < 3) // 0xFF                return new Expression.Operand.Value()                {                    DataType = PrimitiveDataType.CharType | PrimitiveDataType.UnsignedType,                    DataField = (byte)val                };            else                if (hexStr.Length < 5) // 0xFFFF                    return new Expression.Operand.Value()                        {                            DataType = PrimitiveDataType.ShortType | PrimitiveDataType.UnsignedType,                            DataField = (ushort)val                        };                else // 0xFFFFFFFF                    return new Expression.Operand.Value()                    {                        DataType = PrimitiveDataType.IntType,                        DataField = (ushort)val                    };        }        private Expression.Operand.Value GetIntOrFloatValue(Context ctx, SourceCode src)        {            bool isUnsigned = false;            int pointNum = 0;            int expNum = 0;            int floatMark = 0;            int start = src.Column;            src.NextChar(); // skip first digit            while (!src.Eof)            {                bool stop = false;                switch (src.CurrentChar)                {                    case '.':                        {                            pointNum++;                            if (pointNum > 1)                                if (!NotifyError(ctx, src.Location, ParsingErrorType.FormatError, "Invalid float format."))                                    return null;                            if (src.TestNextChar(SourceCode.ExponentialMark))                                if (!NotifyError(ctx, src.Location, ParsingErrorType.FormatError, "Invalid float format."))                                    return null;                            src.NextChar();                        }                        break;                    case 'e':                    case 'E':                        {                            expNum++;                            if (expNum > 1)                                if (!NotifyError(ctx, src.Location, ParsingErrorType.FormatError, "Invalid float format."))                                    return null;                            if (src.TestNextChar(SourceCode.PlusMinusMark))                                if (!NotifyError(ctx, src.Location, ParsingErrorType.FormatError, "Invalid float format."))                                    return null;                            src.NextChar(); // skip 'e/E'                            src.NextChar(); // skip '+/-'                        }                        break;                    case 'f':                    case 'F':                        {                            floatMark++;                            if (floatMark > 1)                                if (!NotifyError(ctx, src.Location, ParsingErrorType.FormatError, "Invalid float format."))                                    return null;                            if (src.Eof)                                if (!NotifyError(ctx, src.Location, ParsingErrorType.FormatError, "Invalid float format."))                                    return null;                            src.NextChar(); // skip 'f/F'                            stop = true;                        }                        break;                    default:                        {                            if (!SourceCode.IsDigit(src.CurrentChar))                            {                                stop = true;                                if (src.CurrentChar == 'u' || src.CurrentChar == 'U')                                {                                    if (pointNum > 0 || expNum > 0 || floatMark > 0)                                    {                                        if (!NotifyError(ctx, src.Location, ParsingErrorType.FormatError, "Invalid float format"))                                            return null;                                    }                                    src.NextChar(); // skip 'U'                                    isUnsigned = true;                                }                            }                            else                                src.NextChar();                        }                        break;                } // switch                if (src.Eof || stop)                    break;            } // while            string valStr = src.Text.Substring(start, src.Column - start);            if (pointNum > 0 || expNum > 0 || floatMark > 0)            {                float val = float.Parse(valStr);                return new Expression.Operand.Value()                {                    DataType = PrimitiveDataType.FloatType,                    DataField = val                };            }            else            {                int val = int.Parse(valStr);                if (val < 65535)                {                    return new Expression.Operand.Value()                    {                        DataType = PrimitiveDataType.ShortType | (isUnsigned ? PrimitiveDataType.UnsignedType : PrimitiveDataType.SignedType),                        DataField = (short)val                    };                }                else                    return new Expression.Operand.Value()                    {                        DataType = PrimitiveDataType.IntType | (isUnsigned ? PrimitiveDataType.UnsignedType : PrimitiveDataType.SignedType),                        DataField = val                    };            }        }        private Expression.Operand.Value GetCharValue(Context ctx, SourceCode src)        {            src.NextChar(); // skip '\''            char val = src.CurrentChar;            if (src.CurrentChar == '\\') // escape            {                src.NextChar(); // skip escape                if (m_escapeCharDict.Count == 0)                {                    m_escapeCharDict.Add('a', '\a');    // Bell (alert)                    m_escapeCharDict.Add('b', '\b');    // Backspace                    m_escapeCharDict.Add('f', '\f');    // Formfeed                    m_escapeCharDict.Add('n', '\n');    // New line                    m_escapeCharDict.Add('r', '\r');    // Carriage return                    m_escapeCharDict.Add('t', '\t');    // Horizontal tab                    m_escapeCharDict.Add('v', '\v');    // Vertical tab                    m_escapeCharDict.Add('\'', '\'');    // Single quotation mark                    // m_escapeCharDict.Add('\"  Double quotation mark                    m_escapeCharDict.Add('\\', '\\');   // Backslash                    m_escapeCharDict.Add('?', (char)63);   // Literal question mark                }                if (SourceCode.IsDigit(src.CurrentChar)) // Digit                {                    bool octal = src.CurrentChar == '0';                    int start = src.Column;                    while (!src.Eof && SourceCode.IsDigit(src.CurrentChar))                        src.NextChar(false);                    if (!src.Eof)                    {                        if (src.CurrentChar == '\'')                        {                            string str = src.Text.Substring(start, src.Column - start);                            val  = (char)int.Parse(str, System.Globalization.NumberStyles.Integer);                        }                        else                            if (!NotifyError(ctx, src.Location, ParsingErrorType.SyntaxError, "Invalid char value."))                                return null;                    }                }                else                {                    // Hex                    if (src.CurrentChar == 'x' || src.CurrentChar == 'X')                    {                        src.NextChar(); // skip x                        int start = src.Column;                        while (!src.Eof && (SourceCode.IsDigit(src.CurrentChar) || (src.CurrentChar >= 'a' && src.CurrentChar <= 'f') || (src.CurrentChar >= 'A' && src.CurrentChar <= 'F')))                            src.NextChar(false);                        if (!src.Eof)                        {                            if (src.CurrentChar == '\'')                            {                                string str = src.Text.Substring(start, src.Column - start);                                val = (char)int.Parse(str, System.Globalization.NumberStyles.HexNumber);                            }                            else                                if (!NotifyError(ctx, src.Location, ParsingErrorType.SyntaxError, "Invalid hexadecimal number."))                                    return null;                        }                                            }                    else                    {                        if (!m_escapeCharDict.ContainsKey(src.CurrentChar))                            if (!NotifyError(ctx, src.Location, ParsingErrorType.SyntaxError, "Unrecognized character escape sequence."))                                return null;                        val = m_escapeCharDict[src.CurrentChar];                    }                }            }            src.NextChar(); // skip value field            if (src.CurrentChar != '\'')                if (!NotifyError(ctx, src.Location, ParsingErrorType.SyntaxError, "Missing close quote."))                    return null;            // skip '\''            src.NextChar();            return new Expression.Operand.Value()            {                DataType = PrimitiveDataType.CharType,                DataField = (byte)val            };        }        private Expression.Operand.Operand GetStringValue(Context ctx, SourceCode src)        {            src.NextChar(); // skip '"'            int startPos = src.Column;            int startPosOfLine = src.ColumnOfCurrentLine;            int startLineNo = src.Line;            StringBuilder strBuilder = new StringBuilder();            while (!src.Eof)            {                if (src.CurrentChar == '\\')                {                    src.NextChar();                    src.NextChar(); // skip Escape and char                }                else                    if (src.CurrentChar == '"')                    {                        strBuilder.Append(src.Text.Substring(startPos, src.Column - startPos));                        src.NextChar(); // skip '"'                        src.SkipSpace();                        if (!src.Eof && src.CurrentChar == '"')                        {                            src.NextChar();                            // String followed by string                            startPos = src.Column;                        }                        else                            break;                    }                    else                        src.NextChar();            }            // The const variable            Variable stxConstVar = new Variable()            {                TypeInfo = new DataTypeInfo()                {                    Type = PrimitiveDataType.CharType | PrimitiveDataType.PointerType,                    PointerCount = 1                },                ReferenceCount = 1            };            stxConstVar.Name = Context.GetAnonymousName(stxConstVar.TypeInfo);            int byteArrayLen = Encoding.ASCII.GetByteCount(strBuilder.ToString()) + 1;            ConstantInitialize stxConstInit = new ConstantInitialize()            {                Name = Context.GetAnonymousName("const_init"),                VariableName = stxConstVar.Name,                InitialValue = new byte[byteArrayLen]            };                        char[] charArray = strBuilder.ToString().ToCharArray();            Encoding.ASCII.GetBytes(charArray, 0, charArray.Length, stxConstInit.InitialValue, 0);            stxConstInit.InitialValue[byteArrayLen - 1] = 0;                        ctx.GlobalContex.AddChildAtFirst(stxConstInit);            ctx.GlobalContex.AddChildAtFirst(stxConstVar);            return new Expression.Operand.ValueOfVariableReference()            {                Name = stxConstInit.VariableName            };        }

At this point, the basic framework of syntax analysis has become.

 

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.