C language interpreter-17 syntax analysis (2)

Source: Internet
Author: User

For Loop parsing:

Private bool parsecontrol_for (context CTX, sourcecode SRC, context. locationinfo LOC) {SRC. skipspace (); If (SRC. currentchar! = '(') If (! Policyerror (CTX, getlocation (loc. firstline, loc. firstpos, SRC. absoluteline, SRC. absolutepos), parsingerrortype. syntaxerror, "'(' is expected. ") return false; // The Code sourcecode stmt = getparenthesiscode (SRC); List <sourcecode> stmtlist = stmt. splitstatement (); // required if (stmtlist. count! = 3) if (! Policyerror (CTX, getlocation (loc. firstline, loc. firstpos, SRC. absoluteline, SRC. absolutepos), parsingerrortype. syntaxerror, "syntax error. ") return false; controlflow. forloop stxfor = new controlflow. forloop () {location = new context. locationinfo () {firstline = loc. firstline, firstpos = loc. firstpos }}; CTX. addchild (stxfor); // initialize context stxinit = new context (); stxfor. addchild (stxinit); If (! Parsestatement (stxinit, stmtlist [0]) return false; // condition determines if (! Parseexpression (stxinit, stmtlist [1], ref stxfor. condition) return false; // iterator if (! Parseexpression (stxinit, stmtlist [2], ref stxfor. iterator) return false; SRC. skipspace (); // If (SRC. currentchar = '{') {stmt = getblockcode (SRC);} else {stmt = new sourcecode () {posoffset = SRC. absolutepos, lineoffset = SRC. absoluteline, text = SRC. text. substring (SRC. column) };} block = new block (); stxfor. addchild (Block); bool res = parse (Block, stmt); stxfor. location. lastline = stmt. absoluteline; stxfor. location. lastpos = stmt. absolutepos; return res ;}

 

The complexity is switch:

private bool ParseControl_Switch(Context ctx, SourceCode src, Context.LocationInfo loc)        {            // Check condition            src.SkipSpace();            if (src.CurrentChar != '(')                if (!NotifyError(ctx, GetLocation(loc.FirstLine, loc.FirstPos, src.AbsoluteLine, src.AbsolutePos), ParsingErrorType.SyntaxError, "Expecte a '('."))                    return false;            ControlFlow.Switch stxSwitch = new ControlFlow.Switch()            {                Location = new Context.LocationInfo()                {                    FirstLine = loc.FirstLine,                    FirstPos = loc.FirstPos                }            };                        ctx.AddChild(stxSwitch);            // Parse condition expression            if (!ParseExpression(stxSwitch, GetParenthesisCode(src), ref stxSwitch.Condition))            {                ctx.Children.RemoveAt(ctx.Children.Count - 1);                return false;            }            // Add body            stxSwitch.AddChild(new Block());            ControlFlow.Case stxDefault = new ControlFlow.Case(); // default part            stxSwitch.Body.AddChild(stxDefault);            // Check '{'            src.SkipSpace();            if (src.CurrentChar != '{')                if (!NotifyError(ctx, GetLocation(loc.FirstLine, loc.FirstPos, src.AbsoluteLine, src.AbsolutePos), ParsingErrorType.SyntaxError, "Expecte a '{'."))                    return false;            // Parse body            SourceCode switchBodyStmt = GetBlockCode(src);            Dictionary<object, bool> caseValDict = new Dictionary<object, bool>();             while (!switchBodyStmt.Eof)            {                switchBodyStmt.SkipSpace();                Word word = GetWord(switchBodyStmt);                switch(word.Text)                {                    case "case":                        {                            ControlFlow.Case stxCase = new ControlFlow.Case()                            {                                Location = new Context.LocationInfo()                                {                                    FirstLine = word.AbsoluteLine,                                    FirstPos = word.AbsoluteStartPos                                }                            };                            switchBodyStmt.SkipSpace();                            if (switchBodyStmt.CurrentChar == '\'') // char                            {                                Expression.Operand.Value charVal = GetCharValue(stxSwitch, switchBodyStmt);                                if (charVal == null)                                    if (!NotifyError(ctx, GetLocation(word.AbsoluteLine, word.AbsoluteStartPos, switchBodyStmt.AbsoluteLine, switchBodyStmt.AbsolutePos), ParsingErrorType.SyntaxError, "Expecte a expression."))                                        return false;                                stxCase.Value = charVal;                            }                            else                            {                                if (SourceCode.IsDigit(switchBodyStmt.CurrentChar)) // number                                {                                    stxCase.Value = GetNumberValue(ctx, switchBodyStmt);                                    if ((stxCase.Value.GetTypeInfo(ctx).Type & PrimitiveDataType.BaseTypeMask) == PrimitiveDataType.FloatType)                                        if (!NotifyError(ctx, GetLocation(word.AbsoluteLine, word.AbsoluteStartPos, switchBodyStmt.AbsoluteLine, switchBodyStmt.AbsolutePos), ParsingErrorType.SyntaxError, "Expression must be an integral constant value."))                                            return false;                                }                                else                                    if (!NotifyError(ctx, GetLocation(word.AbsoluteLine, word.AbsoluteStartPos, switchBodyStmt.AbsoluteLine, switchBodyStmt.AbsolutePos), ParsingErrorType.SyntaxError, "Expression must have a constant value."))                                        return false;                            }                            if (caseValDict.ContainsKey(stxCase.Value.AsInt))                            {                                if (!NotifyError(ctx, GetLocation(word.AbsoluteLine, word.AbsoluteStartPos, switchBodyStmt.AbsoluteLine, switchBodyStmt.AbsolutePos), ParsingErrorType.SyntaxError, "Case label value has appeared in this switch."))                                    return false;                            }                            else                                caseValDict.Add(stxCase.Value.AsInt, true);                            stxSwitch.Body.AddChild(stxCase);                            // Parse case body                            switchBodyStmt.SkipSpace();                            if (switchBodyStmt.CurrentChar != ':')                                if (!NotifyError(ctx, GetLocation(word.AbsoluteLine, word.AbsoluteStartPos, switchBodyStmt.AbsoluteLine, switchBodyStmt.AbsolutePos), ParsingErrorType.SyntaxError, "identifier is undefined."))                                    return false;                            switchBodyStmt.NextChar(); // skip ':'                            stxCase.Location.LastLine = switchBodyStmt.AbsoluteLine;                            stxCase.Location.LastPos = switchBodyStmt.AbsolutePos;                            NotifyParsing(stxCase);                            stxCase.AddChild(new Block());                            if (!Parse(stxCase.Body, GetCaseBodyCode(ctx, switchBodyStmt)))                                return false;                        }                        break;                    case "default":                        {                            if (stxDefault.Children.Count > 0)                                if (!NotifyError(ctx, GetLocation(word.AbsoluteLine, word.AbsoluteStartPos, switchBodyStmt.AbsoluteLine, switchBodyStmt.AbsolutePos), ParsingErrorType.SyntaxError, "default label has already appeared in this switch."))                                    return false;                            // Check ':'                            switchBodyStmt.SkipSpace();                            if (switchBodyStmt.CurrentChar != ':')                                if (!NotifyError(ctx, GetLocation(word.AbsoluteLine, word.AbsoluteStartPos, switchBodyStmt.AbsoluteLine, switchBodyStmt.AbsolutePos), ParsingErrorType.SyntaxError, "':' is expected."))                                    return false;                            switchBodyStmt.NextChar(); // skip ':'                            stxDefault.AddChild(new Block()                            {                                Location = new Context.LocationInfo()                                {                                    FirstLine = word.AbsoluteLine,                                    FirstPos = word.AbsoluteStartPos,                                    LastLine = src.AbsoluteLine,                                    LastPos = src.AbsolutePos                                }                            });                            if (!Parse(stxDefault.Body, GetCaseBodyCode(ctx, switchBodyStmt)))                                return false;                        }                        break;                    default:                        if (!NotifyError(ctx, GetLocation(word.AbsoluteLine, word.AbsoluteStartPos, switchBodyStmt.AbsoluteLine, switchBodyStmt.AbsolutePos), ParsingErrorType.SyntaxError, "\"case\" is expected but get \"" + word.Text + "\"."))                            return false;                        break;                }            } // while            stxSwitch.Body.RemoveChild(stxDefault);            stxSwitch.Body.AddChild(stxDefault);            stxSwitch.Location.LastLine = src.AbsoluteLine;            stxSwitch.Location.LastPos = src.AbsolutePos;            return true;        }

Expression Parsing is divided into two steps. The first step is to generate a Statement object and then parse it based on this object.

Step 1:

private bool ParseExpression(Context ctx, SourceCode src, Context.LocationInfo loc)        {            Statement stmtStx = new Statement()            {                Name = Context.GetAnonymousName("statement"),                Location = loc            };            if (!ParseExpression(ctx, src, ref stmtStx.TargetExpression))                return false;            ctx.AddChild(stmtStx);            stmtStx.Location.LastLine = src.AbsoluteLine;            stmtStx.Location.LastPos = src.AbsolutePos;            NotifyParsing(stmtStx);            return true;        }

Step 2:

private bool ParseExpression(Context ctx, SourceCode src, ref Expression.ExpressionNode expTree)        {            bool res = true;            while (!src.Eof && res)            {                src.SkipSpace();                switch (src.CurrentChar)                {                    case ',':                        {                            src.NextChar(); // skip ','                            Statement stxExp = new Statement();                            if (ctx.Parent != null)                                ctx.Parent.AddChild(stxExp);                            else                                ctx.AddChild(stxExp);                            res = ParseExpression(ctx, src, ref stxExp.TargetExpression);                        }                        break;                    case ';': src.NextChar(); break; // End of statement                    case '=': res = ParseExpression_Equal(ctx, src, ref expTree); break;                    case '+': res = ParseExpression_Plus(ctx, src, ref expTree); break;                    case '-': res = ParseExpression_Minus(ctx, src, ref expTree); break;                    case '*': res = ParseExpression_Mul(ctx, src, ref expTree); break;                    case '/': res = ParseExpression_Div(ctx, src, ref expTree); break;                    case '%': res = ParseExpression_Mod(ctx, src, ref expTree); break;                    case '&': res = ParseExpression_And(ctx, src, ref expTree); break;                    case '|': res = ParseExpression_Or(ctx, src, ref expTree); break;                    case '^': res = ParseExpression_Xor(ctx, src, ref expTree); break;                    case '!': res = ParseExpression_Not(ctx, src, ref expTree); break;                    case '~': res = ParseExpression_BitwiseNot(ctx, src, ref expTree); break;                    case '<': res = ParseExpression_Less(ctx, src, ref expTree); break;                    case '>': res = ParseExpression_Greater(ctx, src, ref expTree); break;                    case '(': res = ParseExpression_Parentheses(ctx, src, ref expTree); break;                    case '\'': res = ParseExpression_CharValue(ctx, src, ref expTree); break;                    case '"':                        {                            // const string                            res = ParseExpression_ConstStringValue(ctx, src, ref expTree);                            //if (!FireParsingFailedEvent(ctx, src, ParsingErrorType.SyntaxError, "String is not supported."))                            //    return false;                        }                        break;                    default:                        {                            Expression.ExpressionNode lastNode = m_lastExpNode;                            if (SourceCode.IsDigit(src.CurrentChar))                            {                                res = ParseExpression_NumberValue(ctx, src, ref expTree);                            }                            else                                if (SourceCode.IsLetter(src.CurrentChar))                                {                                    res = ParseExpression_Var(ctx, src, ref expTree);                                }                                else                                    if (!NotifyError(ctx, src.Location, ParsingErrorType.SyntaxError, "Syntax error."))                                         return false;                            if (!ValidateOperator(ctx, src, lastNode))                                return false;                        }                        break;                } // switch            } // while !Eof            return res;        } // func ParseExpression

 

 

 

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.