C language interpreter-16 syntax analysis (1)

Source: Internet
Author: User

The Parser class is used to analyze the syntax of C code and construct a syntax tree.

/// <Summary> // Parser class parses the simple C source code to build // the syntax serial. /// </summary> public class Parser {public enum ParsingErrorType {Warning, UnknownError, UndefinedVariable, UnexpectedKeyword, TokenExpected, SyntaxError, TypeError, FormatError, FunctionBodyUndefined }; public class ParsingEventArg {public Context;} public class ParsingWarningEventArg {public Context; public Context. locationInfo Location; public string Description;} public class ParsingErrorEventArg {public Context; public Context. locationInfo Location; public callback Error; public string Description; public bool Continue;} public event EventHandler <ParsingEventArg> OnParsing; public event EventHandler 

The main syntax analysis method is defined as follows:

Private bool Parse (Context ctx, SourceCode src) {bool res = true; ctx. location. firstLine = src. absoluteLine; ctx. location. firstPos = src. absolutePos; foreach (SourceCode stmt in src. splitStatement () // process by statement {try {// detect do... while part if (ctx. children. count> 0 & ctx. children. last () is ControlFlow. doWhileLoop) {if (ctx. children. last () as ControlFlow. doWhileLoop ). condition = null) {Wor D wordOfWhile = GetWord (stmt); if (wordOfWhile. Text! = "While") {if (! Policyerror (ctx, wordOfWhile. location, ParsingErrorType. syntaxError, "\" while \ "is expected. ") return false;} else {res = ParseControl_While (ctx, stmt, new Context. locationInfo () {FirstLine = wordOfWhile. absoluteLine, FirstPos = wordOfWhile. absoluteStartPos}); if (! Res) return false; else continue ;}} if (stmt. text. endsWith (";") // statement {res = ParseStatement (ctx, stmt);} else {if (stmt. text. endsWith ("}") // function body or block {if (stmt. text. startsWith ("{") // block {SourceCode blockSrc = new SourceCode () {LineOffset = stmt. absoluteLine, PosOffset = stmt. absolutePos, Text = stmt. text. substring (1, stmt. text. length-2)}; Block block = new Block () {Name = Context. get AnonymousName ("block"), Location = new Context. locationInfo () {FirstLine = stmt. absoluteLine, FirstPos = stmt. absolutePos }}; ctx. addChild (block); res = Parse (block, blockSrc); block. location. lastLine = stmt. absoluteLine; block. location. lastPos = stmt. absolutePos;} else {// function // filter control structure Word wordOfControlFlow = GetWord (stmt); if (Context. isControlFlow (wordOfControlFlow. text) {res = ParseCont RolFlow (ctx, stmt, wordOfControlFlow);} else {stmt. resetPos (); res = ParseFunction (ctx, stmt, wordOfControlFlow. location) ;}}}} catch (ParseException pe) {if (! Policyerror (ctx, ctx. Location, ParsingErrorType. SyntaxError, pe. Message) return false;} if (! Res) return false;} // for ctx. Location. LastLine = src. AbsoluteLine; ctx. Location. LastPos = src. AbsolutePos; return true ;}

Statement processing: Statement statement, control structure, and expression.

Private bool ParseStatement (Context ctx, SourceCode src) {Word firstWord = GetWord (src); if (Context. isDataType (firstWord. text) // type the header {// variable or function declaration return ParseDeclare (ctx, src, firstWord);} else if (Context. isControlFlow (firstWord. text) // Control Structure {// Control return ParseControlFlow (ctx, src, firstWord);} else {// expression src. resetPos (); return ParseExpression (ctx, src, firstWord. location );}}

Function Parsing is implemented as follows:

Private bool parsefunction (context CTX, sourcecode SRC, context. locationinfo LOC) {// locate the function body while (! SRC. EOF & SRC. currentchar! = '{') SRC. nextchar (); // the header position information context. locationinfo headerloc = LOC; headerloc. lastpos = SRC. absolutepos-1; // function header sourcecode funcheader = new sourcecode () {posoffset = loc. firstpos, lineoffset = loc. firstline, text = SRC. text. substring (0, SRC. column)}; // The parsing header // if it is successful, a functiondefine will be added to the end of the current context if (! Parsestatement (CTX, funcheader) return false; SRC. nextchar (); // skip' {'// function body sourcecode bodystmt = new sourcecode () {posoffset = SRC. absolutepos, lineoffset = SRC. absoluteline, text = SRC. text. substring (SRC. column, SRC. text. length-Src. column-1)}; // function object function. functiondefine funcdef = CTX. children. last () as function. functiondefine; funcdef. addchild (new block () {name = context. getanonymousname ("Block")}); // recursive parsing function body if (PARSE (funcdef. body, bodystmt) {funcdef. location = headerloc; return true;} return false ;}

The control structure is parsed as follows:

private bool ParseControlFlow(Context ctx, SourceCode src, Word wordOfControlFlow)        {            bool res = false;            switch (wordOfControlFlow.Text)            {                case "if": res = ParseControl_If(ctx, src, wordOfControlFlow.Location); break;                case "else": res = ParseControl_Else(ctx, src, wordOfControlFlow.Location); break;                case "for": res = ParseControl_For(ctx, src, wordOfControlFlow.Location); break;                case "do": res = ParseControl_DoWhile(ctx, src, wordOfControlFlow.Location); break;                case "while": res = ParseControl_While(ctx, src, wordOfControlFlow.Location); break;                case "switch": res = ParseControl_Switch(ctx, src, wordOfControlFlow.Location); break;                case "continue": res = ParseControl_Continue(ctx, src, wordOfControlFlow.Location); break;                case "break": res = ParseControl_Break(ctx, src, wordOfControlFlow.Location); break;                case "return": res = ParseControl_Return(ctx, src, wordOfControlFlow.Location); break;                default:                    {                        // Unsupported control flow.                        if (!NotifyError(ctx, wordOfControlFlow.Location, ParsingErrorType.SyntaxError, "Unsupported keyword."))                            return false;                    }                    break;            } // switch            if (res)                NotifyParsing(ctx.Children.Last());            return res;        }

 

Take if/else as an example to describe the parsing process of the control structure.

First look at the if section:

Private bool parsecontrol_if (context CTX, sourcecode SRC, context. locationinfo LOC) {SRC. skipspace (); // get '('If (SRC. currentchar! = '(') If (! Policyerror (CTX, getlocation (loc. firstline, loc. firstpos, SRC. absoluteline, SRC. absolutepos), parsingerrortype. syntaxerror, "'(' is expected. ") return false; // obtain the judgment Expression sourcecode condition = getparenthesiscode (SRC); controlflow. ifthen stxif = new controlflow. ifthen () {location = new context. locationinfo () {firstline = loc. firstline, firstpos = loc. firstpos }}; CTX. addchild (stxif); // parse and determine the expression if (! Parseexpression (stxif, condition, ref stxif. condition) return false; // try to parse the then part of the code SRC. skipspace (); bool res = false; block thenblock = new block (); stxif. addchild (thenblock); If (SRC. currentchar = '{') // block? {Sourcecode code = getblockcode (SRC); Res = parse (thenblock, Code); stxif. location. lastline = SRC. absoluteline; stxif. location. lastpos = SRC. absolutepos;} else {// a single statement? Sourcecode stmt = new sourcecode () {posoffset = SRC. absolutepos, lineoffset = SRC. absoluteline, text = SRC. text. substring (SRC. column)}; Res = parse (thenblock, stmt); stxif. location. lastline = stmt. absoluteline; stxif. location. lastpos = stmt. absolutepos;} // another else case handling return res ;}

 

Let's look at the else section:

Private bool ParseControl_Else (Context ctx, SourceCode src, Context. LocationInfo loc) {// else cannot appear separately, and there must be an if before. This method also solves the nearby matching problem between else and if. If (! (Ctx. Children. Last () is ControlFlow. IfThen) if (! Policyerror (ctx, loc, ParsingErrorType. syntaxError, "\" else \ "shocould not appear here. ") return false; // The previous syntax may be multiple if/then Context lastx = ctx. children. last (); while (lastStx. children. count> 2) // if the number of Children is greater than 2, indicating that the else part exists, the last if/then {lastStx = lastStx is obtained. children. last ();} // re-detect if/then if (! (LastStx is ControlFlow. IfThen) if (! Policyerror (ctx, loc, ParsingErrorType. syntaxError, "Can't find matched \" if \". ") return false; ControlFlow. ifThen stxIf = lastStx as ControlFlow. ifThen; src. skipSpace (); bool res = false; Block elseBlock = new Block (); stxIf. addChild (elseBlock); // Block if (src. currentChar = '{') {SourceCode code = GetBlockCode (src); res = Parse (elseBlock, code); lastStx. location. lastLine = src. absoluteLine; lastStx. location. lastPos = src. absolutePos;} else {// Statement SourceCode stmt = new SourceCode () {PosOffset = src. absolutePos, LineOffset = src. absoluteLine, Text = src. text. substring (src. column)}; res = Parse (elseBlock, stmt); lastStx. location. lastLine = stmt. absoluteLine; lastStx. location. lastPos = stmt. absolutePos;} return res ;}

 

 

 

 

 

 

 

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.