public static ICommandsEvaluator ParseCommandBlockDeclaration(CalculatorEnvironment localContext, ref String commandLine, ref String resultLine) { // COMMANDBLOCK = "{" COMMANDS "}" . // COMMANDBLOCK = #4 "{" COMMANDS "}" . Boolean OK = true; if (!String.IsNullOrEmpty(commandLine)) { if (localContext.ParseState == CommandParserState.ReadCommandBlock) { if (commandLine.StartsWith("//")) { // #4 commandLine = null; return(null); } OK = TokenString.ParseToken("{", ref commandLine, ref resultLine); if (OK) { localContext.ParseState = CommandParserState.ReadCommands; localContext.CommandBlockToParseInfo.InnerBlockCount = 0; } } if (localContext.ParseState == CommandParserState.ReadCommands) { if (!String.IsNullOrEmpty(commandLine)) { String tempCommandLine = commandLine; int indexStartComment = commandLine.IndexOf("//"); if (indexStartComment >= 0) { // Command line are terminated by "//" tempCommandLine = commandLine.Substring(0, indexStartComment); } int indexCommandEnd = commandLine.Length; { int indexStartInnerBlock = tempCommandLine.IndexOf("{"); int tempIndexCommandEnd = tempCommandLine.IndexOf('}'); while (tempIndexCommandEnd > 0) { // some command block is terminated by '}' (before comment) // Look for inner command blocks //indexStartInnerBlock = tempCommandLine.IndexOf("{", indexStartInnerBlock+1); while ((indexStartInnerBlock >= 0) && (tempIndexCommandEnd > indexStartInnerBlock)) { // Commands has inner block start localContext.CommandBlockToParseInfo.InnerBlockCount++; indexStartInnerBlock = tempCommandLine.IndexOf('{', indexStartInnerBlock + 1); } // InnerBlockCount now holds the no of inner block starts if (localContext.CommandBlockToParseInfo.InnerBlockCount > 0) { // The found '}' terminates the most inner of the inner blocks localContext.CommandBlockToParseInfo.InnerBlockCount--; // Look for next '}' tempIndexCommandEnd = tempCommandLine.IndexOf('}', tempIndexCommandEnd + 1); } else { // The found '}' terminates this (most outer) block indexCommandEnd = tempIndexCommandEnd; tempIndexCommandEnd = -2; } } if (localContext.CommandBlockToParseInfo.InnerBlockCount > 0) { // this (most outer) block are not terminated in this line // Line are not terminated by '}' // Whole commandLine is part of Command Block // indexCommandEnd = commandLine.Length; Debug.Assert(tempIndexCommandEnd == -1); Debug.Assert(indexCommandEnd == commandLine.Length); } else { Debug.Assert(tempIndexCommandEnd == -2); } } if (indexCommandEnd > 0) { if (localContext.CommandBlockToParseInfo.CommandBlock.Commands == null) { // localContext.CommandBlockToParseInfo.CommandBlock.Commands = new List<String>(); } Debug.Assert(localContext.CommandBlockToParseInfo.CommandBlock.Commands != null); localContext.CommandBlockToParseInfo.CommandBlock.Commands.Add(commandLine.Substring(0, indexCommandEnd)); commandLine = commandLine.Substring(indexCommandEnd); } if (!String.IsNullOrEmpty(commandLine)) { OK = TokenString.ParseToken("}", ref commandLine, ref resultLine); if (OK) { if (localContext.CommandBlockToParseInfo.InnerBlockCount > 0) { localContext.CommandBlockToParseInfo.InnerBlockCount--; } else { // Completed function declaration parsing localContext.ParseState = CommandParserState.ExecuteCommandLine; return(localContext.CommandBlockToParseInfo.CommandBlock); } } } } } } return(null); }
public static IFunctionEvaluator ParseFunctionDeclaration(CalculatorEnvironment localContext, ref String commandLine, ref String resultLine) { // FUNC = FUNCNAME "(" PARAMLIST ")" "{" FUNCBODY "}" . // FUNC = FUNCNAME #1 "(" #2 PARAMLIST #3 ")" #4 "{" FUNCBODY "}" . Boolean OK = true; if (localContext.ParseState == CommandParserState.ReadFunctionParameterList) { if (commandLine.StartsWith("//")) { // #1 commandLine = null; return(null); } OK = TokenString.ParseToken("(", ref commandLine, ref resultLine); localContext.ParseState = CommandParserState.ReadFunctionParameters; } if (String.IsNullOrEmpty(commandLine)) { return(null); } if (((localContext.ParseState == CommandParserState.ReadFunctionParameters || localContext.ParseState == CommandParserState.ReadFunctionParametersOptional) && !commandLine.StartsWith(")")) || (localContext.ParseState == CommandParserState.ReadFunctionParameter)) { Boolean MoreParamsToParse; do { if (commandLine.StartsWith("//")) { // #2 commandLine = null; return(null); } if ((localContext.ParseState == CommandParserState.ReadFunctionParameters) || (localContext.ParseState == CommandParserState.ReadFunctionParameter)) { PhysicalQuantityFunctionParam param = ParseFunctionParam(ref commandLine, ref resultLine); OK &= param != null; localContext.FunctionToParseInfo.Function.ParamListAdd(param); localContext.ParseState = CommandParserState.ReadFunctionParametersOptional; if (commandLine.StartsWith("//")) { // #3 commandLine = null; return(null); } } MoreParamsToParse = TokenString.TryParseToken(",", ref commandLine); if (MoreParamsToParse) { localContext.ParseState = CommandParserState.ReadFunctionParameter; } } while (OK && !String.IsNullOrEmpty(commandLine) && MoreParamsToParse); } if (OK && !String.IsNullOrEmpty(commandLine)) { if ((localContext.ParseState == CommandParserState.ReadFunctionParameters) || (localContext.ParseState == CommandParserState.ReadFunctionParametersOptional)) { OK = TokenString.ParseToken(")", ref commandLine, ref resultLine); if (OK) { localContext.ParseState = CommandParserState.ReadFunctionBlock; } } if (OK) { if (!String.IsNullOrEmpty(commandLine)) { if (localContext.ParseState == CommandParserState.ReadFunctionBlock) { if (commandLine.StartsWith("//")) { // #4 commandLine = null; return(null); } OK = TokenString.ParseToken("{", ref commandLine, ref resultLine); if (OK) { localContext.ParseState = CommandParserState.ReadFunctionBody; localContext.CommandBlockLevel = 1; } } if (localContext.ParseState == CommandParserState.ReadFunctionBody) { if (!String.IsNullOrEmpty(commandLine)) { String TempcommandLine = commandLine; int indexStartComment = commandLine.IndexOf("//"); if (indexStartComment >= 0) { // Command are terminated by "//" TempcommandLine = TempcommandLine.Substring(0, indexStartComment); } string NoCommentCommandLine = TempcommandLine; int indexCommandBlockBegin = TempcommandLine.IndexOf('{'); int indexCommandBlockEnd = TempcommandLine.IndexOf('}'); while (localContext.CommandBlockLevel > 0 && (indexCommandBlockBegin >= 0 || indexCommandBlockEnd >= 0)) { Boolean beginIsBeforeEnd = (indexCommandBlockBegin >= 0 && (indexCommandBlockEnd <0 || indexCommandBlockEnd> indexCommandBlockBegin)); if (beginIsBeforeEnd) { localContext.CommandBlockLevel++; int skipLen = indexCommandBlockBegin + 1; TempcommandLine = TempcommandLine.Length > skipLen?TempcommandLine.Substring(skipLen) : ""; indexCommandBlockBegin = TempcommandLine.IndexOf('{'); indexCommandBlockEnd -= skipLen; } else { localContext.CommandBlockLevel--; int skipLen = indexCommandBlockEnd; if (localContext.CommandBlockLevel > 0) { // Include '}' if it is not the end of this function block skipLen++; } TempcommandLine = TempcommandLine.Length > skipLen?TempcommandLine.Substring(skipLen) : ""; indexCommandBlockBegin -= skipLen; indexCommandBlockEnd = TempcommandLine.IndexOf('}'); } } ; int indexCommandEnd = -1; if (localContext.CommandBlockLevel > 0) { // function block are not terminated by '}' // Whole commandLine is part of Command Block indexCommandEnd = commandLine.Length; } else { indexCommandEnd = NoCommentCommandLine.Length - TempcommandLine.Length; } if (indexCommandEnd > 0) { if (localContext.FunctionToParseInfo.Function.Commands == null) { // localContext.FunctionToParseInfo.Function.Commands = new List<String>(); } Debug.Assert(localContext.FunctionToParseInfo.Function.Commands != null); localContext.FunctionToParseInfo.Function.Commands.Add(commandLine.Substring(0, indexCommandEnd)); commandLine = commandLine.Substring(indexCommandEnd); } if (localContext.CommandBlockLevel == 0) { OK = TokenString.ParseToken("}", ref commandLine, ref resultLine); if (OK) { // Completed function declaration parsing localContext.ParseState = CommandParserState.ExecuteCommandLine; return(localContext.FunctionToParseInfo.Function); } } } } } } } return(null); }
// static public Boolean ParseToken(String Token, ref String CommandLine, ref string ResultLine) => TokenString.ParseToken(Token, ref CommandLine, ref ResultLine);