#if UNITY_EDITOR using System; using System.Collections.Generic; using UnityEngine; namespace SLZ.Bonelab { public class SIParser { public string fileDir; public SIParser(string fileDir) { this.fileDir = fileDir; } enum ErrorCode : int { none, missingOrder, orderNotInt, missingTag, unexpectedParam, unexpectedCmd, expectedOtherCmd, unexpectedEnd, } public int validateBase(List commands) { //bool needsEnd = false; SILexicon.CmdType expectedCmd = SILexicon.CmdType.Invalid; SILexer.CommandInfo prevCmd = null; //int prevCmdLine = 0; for (int i = 0; i < commands.Count; i++) { switch (commands[i].cmdType) { case SILexicon.CmdType.Invalid: Debug.LogError("Invalid ShaderInjector Command at line " + commands[i].line); return -1; case SILexicon.CmdType.InjectPoint: ErrorCode cmdError0 = validateInjectPoint(commands[i], expectedCmd); if (cmdError0 != ErrorCode.none) { PrintErrorMessage(cmdError0, commands[i], expectedCmd); return -1; } expectedCmd = SILexicon.CmdType.Invalid; break; case SILexicon.CmdType.InjectDefault: ErrorCode cmdError1 = validateInjectDefault(commands[i], prevCmd, expectedCmd); if (cmdError1 != ErrorCode.none) { PrintErrorMessage(cmdError1, commands[i], expectedCmd); return -1; } expectedCmd = SILexicon.CmdType.InjectEnd; break; case SILexicon.CmdType.InjectEnd: ErrorCode cmdError2 = validateInjectEnd(commands[i], expectedCmd); if (cmdError2 != ErrorCode.none) { PrintErrorMessage(cmdError2, commands[i], expectedCmd); return -1; } expectedCmd = SILexicon.CmdType.Invalid; break; case SILexicon.CmdType.TexcoordCounter: ErrorCode cmdError3 = validateTexcoord(commands[i]); if (cmdError3 != ErrorCode.none) { PrintErrorMessage(cmdError3, commands[i], expectedCmd); return -1; } break; default: PrintErrorMessage(ErrorCode.unexpectedCmd, commands[i], expectedCmd); return -1; } prevCmd = commands[i]; } if (expectedCmd != SILexicon.CmdType.Invalid) { PrintErrorMessage(ErrorCode.unexpectedEnd, commands[commands.Count - 1], expectedCmd); return -1; } return 0; } public int validateInjection(List commands) { //bool needsEnd = false; SILexicon.CmdType expectedCmd = SILexicon.CmdType.Invalid; SILexer.CommandInfo prevCmd = null; //int prevCmdLine = 0; for (int i = 0; i < commands.Count; i++) { switch (commands[i].cmdType) { case SILexicon.CmdType.Invalid: Debug.LogError("Invalid ShaderInjector Command at line " + commands[i].line); return -1; case SILexicon.CmdType.InjectBegin: ErrorCode cmdError0 = validateInjectBegin(commands[i], expectedCmd); if (cmdError0 != ErrorCode.none) { PrintErrorMessage(cmdError0, commands[i], expectedCmd); return -1; } expectedCmd = SILexicon.CmdType.InjectEnd; break; case SILexicon.CmdType.InjectEnd: ErrorCode cmdError1 = validateInjectEnd(commands[i], expectedCmd); if (cmdError1 != ErrorCode.none) { PrintErrorMessage(cmdError1, commands[i], expectedCmd); return -1; } expectedCmd = SILexicon.CmdType.Invalid; break; case SILexicon.CmdType.TexcoordCounter: ErrorCode cmdError2 = validateTexcoord(commands[i]); if (cmdError2 != ErrorCode.none) { PrintErrorMessage(cmdError2, commands[i], expectedCmd); return -1; } break; default: PrintErrorMessage(ErrorCode.unexpectedCmd, commands[i], expectedCmd); return -1; } prevCmd = commands[i]; } if (expectedCmd != SILexicon.CmdType.Invalid) { PrintErrorMessage(ErrorCode.unexpectedEnd, commands[commands.Count - 1], expectedCmd); return -1; } return 0; } ErrorCode validateInjectEnd(SILexer.CommandInfo cmd, SILexicon.CmdType expectedCmd) { if (expectedCmd != SILexicon.CmdType.InjectEnd) { return ErrorCode.unexpectedCmd; } if (cmd.parameters.Count > 0) { return ErrorCode.unexpectedParam; } return ErrorCode.none; } ErrorCode validateInjectBegin(SILexer.CommandInfo cmd, SILexicon.CmdType expectedCmd) { if (expectedCmd != SILexicon.CmdType.Invalid && cmd.cmdType != expectedCmd ) { return ErrorCode.expectedOtherCmd; } if (cmd.parameters.Count < 1) { return ErrorCode.missingTag; } if (cmd.parameters.Count == 1) { return ErrorCode.missingOrder; } int param2 = 0; if (!Int32.TryParse(cmd.parameters[1], out param2)) { return ErrorCode.orderNotInt; } return ErrorCode.none; } ErrorCode validateInjectPoint(SILexer.CommandInfo cmd, SILexicon.CmdType expectedCmd) { if (expectedCmd != SILexicon.CmdType.Invalid && cmd.cmdType != expectedCmd) { return ErrorCode.expectedOtherCmd; } if (cmd.parameters.Count == 0) { return ErrorCode.missingTag; } if (cmd.parameters.Count > 1) { return ErrorCode.unexpectedParam; } return ErrorCode.none; } ErrorCode validateInjectDefault(SILexer.CommandInfo cmd, SILexer.CommandInfo prevCmd, SILexicon.CmdType expectedCmd) { if (expectedCmd != SILexicon.CmdType.Invalid && cmd.cmdType != expectedCmd) { return ErrorCode.expectedOtherCmd; } if (prevCmd.cmdType != SILexicon.CmdType.InjectPoint) { return ErrorCode.unexpectedCmd; } if (cmd.parameters.Count > 0) { return ErrorCode.unexpectedParam; } return ErrorCode.none; } ErrorCode validateTexcoord(SILexer.CommandInfo cmd) { if (cmd.parameters.Count < 2) { return ErrorCode.missingTag; } if (cmd.parameters.Count == 2) { return ErrorCode.missingOrder; } if (cmd.parameters.Count > 3) { return ErrorCode.unexpectedParam; } int param2 = 0; if (!Int32.TryParse(cmd.parameters[2], out param2)) { return ErrorCode.orderNotInt; } return ErrorCode.none; } void PrintErrorMessage(ErrorCode error, SILexer.CommandInfo curr, SILexicon.CmdType expected) { string currCmdName = SILexicon.Lexicon2[curr.cmdType]; int currLine = curr.line; string expectedCmdName = expected != SILexicon.CmdType.Invalid ? SILexicon.Lexicon2[expected] : "INVALID_TYPE"; switch (error) { case ErrorCode.missingOrder: Debug.LogError(string.Format("ShaderInjector: {0} at line {1} is missing order parameter\n {2}", currCmdName, currLine, fileDir)); break; case ErrorCode.orderNotInt: Debug.LogError(string.Format("ShaderInjector: {0} at line {1} cannot convert parameter to int\n {2}", currCmdName, currLine, fileDir)); break; case ErrorCode.missingTag: Debug.LogError(string.Format("ShaderInjector: {0} at line {1} is missing tag name\n {2}", currCmdName, currLine, fileDir)); break; case ErrorCode.unexpectedParam: Debug.LogError(string.Format("ShaderInjector: {0} at line {1} has an unexpected parameter\n {2}", currCmdName, currLine, fileDir)); break; case ErrorCode.expectedOtherCmd: Debug.LogError(string.Format("ShaderInjector: expected {0}, found {1} at line {2}\n {3}", expectedCmdName, currCmdName, currLine, fileDir)); break; case ErrorCode.unexpectedCmd: Debug.LogError(string.Format("ShaderInjector: Unexpected command {0} at line {1}\n {2}", currCmdName, currLine, fileDir)); break; case ErrorCode.unexpectedEnd: Debug.LogError(string.Format("ShaderInjector: Reached end of file before finding {2} to match {0} at line {1} \n {3}", currCmdName, currLine, expectedCmdName, fileDir)); break; default: Debug.LogError(string.Format("ShaderInjector: unknown error in {0} at line {1} \n {2}", currCmdName, currLine, fileDir)); break; } } } } #endif