/// <summary> /// .lcppからレイヤ構造ファイルにコンパイル。 /// </summary> /// <param name="fileName">ファイル名。</param> /// <returns>コンパイル結果。</returns> private LayerStructureFile CompileLCppToObjectFile(string fileName) { // ファイルチェック string fileName2 = fileName; if (!File.Exists(fileName2)) { fileName2 = SourceRootPath + fileName; if (!File.Exists(fileName2)) { throw new FileNotFoundException(fileName + " が見つかりません", fileName); } } // ファイルオープン RTCOPSourceFile src = null; using (StreamReader sr = new StreamReader(fileName2, Encoding)) { string text = sr.ReadToEnd(); src = new RTCOPSourceFile(fileName2, text); } // プリプロセス var src2 = _RTCOPPreprocessor.Run(src); // コンパイル var result = _RTCOPCompiler.Compile(src2); return(result); }
/// <summary> /// プリプロセス実行 /// </summary> /// <param name="inputFile">入力ファイル</param> /// <returns>実行後のファイル</returns> public RTCOPSourceFile Run(RTCOPSourceFile inputFile) { var macros = new List <PreprocessDirective>(DefinedMacros); _ImportedFileNames.Clear(); return(Run_Private(inputFile, macros)); }
public static void Test() { string src = @" baselayer { // ベースクラス base class Sample { public: Sample(); virtual ~Sample(); }; } "; var text = RTCOPParser.BaseLayerDefinition.TokenWithSkipComment().Many().Parse(src); //var text = PreprocessParser.DirectiveOrLine.TokenWithSkipCommentForPreprocessParser().Many().Parse(src2); //var text = RTCOPParser.BaseLayerDefinition.TokenWithSkipComment().Many().Parse(src); //var text = TokenParser.Token.TokenWithSkipComment().Many().Parse(src); //var text = PreprocessParser.Directive.TokenWithSkipCommentForPreprocessParser().Many().Parse(src); //foreach (var t in text) Console.WriteLine(t); //Console.WriteLine(text); RTCOPSourceFile f = new RTCOPSourceFile("a.lcpp", src); RTCOPPreprocessor p = new RTCOPPreprocessor(new string[0], new List <string>(), Encoding.UTF8); var f2 = p.Run(f); Console.WriteLine(f2.Text); RTCOPCompiler c = new RTCOPCompiler(null); var of = c.Compile(f2); LayerStructureFile.SaveFile(@"C:\Users\Ikuta\Desktop\aaa.lobj", of); var of2 = LayerStructureFile.LoadFile(@"C:\Users\Ikuta\Desktop\aaa.lobj"); }
/// <summary> /// プリプロセス実行 /// </summary> /// <param name="inputFile">入力ファイル</param> /// <param name="macros">ファイル内で定義されたマクロ</param> /// <returns>実行後のファイル</returns> private RTCOPSourceFile Run_Private(RTCOPSourceFile inputFile, List <PreprocessDirective> macros) { // ファイルから全てのディレクティブ、行を取得 var allObjs = PreprocessParser.IfSection.Or(PreprocessParser.DirectiveOrLineForIfSection).TokenWithSkipCommentForPreprocessParser().Many().Parse(inputFile.Text); var importingFiles = new List <RTCOPSourceFile>(); // 実際のプリプロセス処理を行う Func <IEnumerable <object>, IEnumerable <object> > runPreprocess = null; runPreprocess = (objs) => { var newObjs = new List <object>(); foreach (object obj in objs) { // ifセクション if (obj is IfSection) { var ifSection = (IfSection)obj; foreach (var group in ifSection.Groups) { // 条件が合えば追加 bool isMatch = EvaluateIfDirectiveExpression(group.First() as PreprocessDirective, macros); if (isMatch) { var additionalGroup = runPreprocess(group.Skip(1)); newObjs.AddRange(additionalGroup); break; } } } // ディレクティブ else if (obj is PreprocessDirective) { var directive = (PreprocessDirective)obj; switch (directive.Kind) { case DirectiveKind.Define: macros.Add(directive); //newObjs.Add(directive); break; case DirectiveKind.Undef: var removingMacro = macros.Find((macro) => macro.Param1 == directive.Param1); if (removingMacro != null) { macros.Remove(removingMacro); } //newObjs.Add(directive); break; case DirectiveKind.ImportLayerHeader: case DirectiveKind.ImportBaseClassHeader: RTCOPSourceFile importingFile = null; foreach (var incpath in IncludePaths) { string path = incpath + directive.Param1; string fullpath = Path.GetFullPath(path); if (File.Exists(fullpath)) { if (_ImportedFileNames.Contains(fullpath)) { // 同じパスのファイルは二度読み込まないようにする goto EndImport; } else { _ImportedFileNames.Add(fullpath); } // ファイルオープン RTCOPSourceFile src = null; using (StreamReader sr = new StreamReader(fullpath, Encoding)) { string text = sr.ReadToEnd(); src = new RTCOPSourceFile(fullpath, text); } importingFile = Run_Private(src, macros); break; } } if (importingFile == null) { throw new Exception("ファイル: " + directive.Param1 + "が見つかりません"); } importingFiles.Add(importingFile); if (directive.Kind == DirectiveKind.ImportBaseClassHeader) { // includeに変換して追加 PreprocessDirective incdirective = new PreprocessDirective(DirectiveKind.Include, directive.Param1); newObjs.Add(incdirective); } else { newObjs.Add(directive); } EndImport: break; default: newObjs.Add(directive); break; } } // 通常の行 else { // マクロ展開して追加 var line = (NonDirectiveLine)obj; var newLine = ExpandMacro(line.Contents, macros, false); newObjs.Add(newLine); } } return(newObjs); }; // 実行開始 var result = runPreprocess(allObjs); // 結果を返す StringBuilder sb = new StringBuilder(); foreach (object obj in result) { sb.Append(obj.ToString()); sb.Append("\r\n"); } RTCOPSourceFile outputFile = new RTCOPSourceFile(inputFile.FilePath, sb.ToString(), importingFiles); return(outputFile); }
/// <summary> /// コンパイル /// </summary> /// <param name="sourceFile">ソースファイル</param> /// <returns>レイヤ構造ファイル</returns> public LayerStructureFile Compile(RTCOPSourceFile sourceFile) { // 結果を格納するためのレイヤ構造ファイル LayerStructureFile result = new LayerStructureFile(); // パーサに通す string sourceCode = sourceFile.Text; var items = RTCOPParser.RTCOPSourceFile.Parse(sourceCode); // 各レイヤ共通のアイテム List <object> commonItemsS = new List <object>(); List <object> commonItemsH = new List <object>(); // 要素の解釈 foreach (object item in items) { // レイヤ定義の場合 if (item is LayerDefinition) { var layerDefinition = (LayerDefinition)item; if (layerDefinition.Name == "baselayer") { if (result.BaseLayerStructure == null) { result.BaseLayerStructure = new LayerStructure("baselayer"); } result.BaseLayerStructure.SourceFileItems.Add(layerDefinition); } else { var layerStructure = result.LayerStructures.Find((obj) => obj.LayerName == layerDefinition.Name); if (layerStructure == null) { layerStructure = new LayerStructure(layerDefinition.Name); result.LayerStructures.Add(layerStructure); } layerStructure.SourceFileItems.Add(layerDefinition); } } // それ以外 else { commonItemsS.Add(item); } } // 各レイヤ共通のアイテムの反映 if (result.BaseLayerStructure != null) { result.BaseLayerStructure.SourceFileItems.InsertRange(0, commonItemsS); } foreach (var layerStructure in result.LayerStructures) { layerStructure.SourceFileItems.InsertRange(0, commonItemsS); } // ヘッダファイルの解釈 Action <RTCOPSourceFile> InterpretImportedFiles = null; InterpretImportedFiles = (src) => { foreach (RTCOPSourceFile impFile in src.ImportedFiles) { // .lh内でさらに読み込まれているファイルをチェック InterpretImportedFiles(impFile); // パーサに通す string impFileCode = impFile.Text; var impFileItems = RTCOPParser.RTCOPSourceFile.Parse(impFileCode); // ファイルの種類によって処理方法を変える if (Path.GetExtension(impFile.FilePath) == ".lh") { List <string> layerNames = new List <string>(); // 要素の解釈 foreach (object item in impFileItems) { // レイヤ定義の場合 if (item is LayerDefinition) { var layerDefinition = (LayerDefinition)item; layerNames.Add(layerDefinition.Name); // ヘッダ要素の追加 if (layerDefinition.Name == "baselayer") { // ベースレイヤ if (result.BaseLayerStructure == null) { result.BaseLayerStructure = new LayerStructure("baselayer"); } ImportedFileInfomation ifi = result.BaseLayerStructure.ImportedLhInfomation.Find((obj) => obj.FilePath == impFile.FilePath); if (ifi == null) { ifi = new ImportedFileInfomation(impFile.FilePath); ifi.StartIndex = result.BaseLayerStructure.HeaderFileItems.Count; ifi.NumOfItems = 0; result.BaseLayerStructure.ImportedLhInfomation.Add(ifi); } ++ifi.NumOfItems; result.BaseLayerStructure.HeaderFileItems.Add(layerDefinition); } else { // ベースレイヤ以外 var layerStructure = result.LayerStructures.Find((obj) => obj.LayerName == layerDefinition.Name); if (layerStructure == null) { layerStructure = new LayerStructure(layerDefinition.Name); result.LayerStructures.Add(layerStructure); } ImportedFileInfomation ifi = layerStructure.ImportedLhInfomation.Find((obj) => obj.FilePath == impFile.FilePath); if (ifi == null) { ifi = new ImportedFileInfomation(impFile.FilePath); ifi.StartIndex = layerStructure.HeaderFileItems.Count; ifi.NumOfItems = 0; layerStructure.ImportedLhInfomation.Add(ifi); } ++ifi.NumOfItems; layerStructure.HeaderFileItems.Add(layerDefinition); } } // それ以外 else { commonItemsH.Add(item); } } // 各レイヤ共通のアイテムの反映 if (layerNames.Contains("baselayer")) { ImportedFileInfomation ifi = result.BaseLayerStructure.ImportedLhInfomation.Find((obj) => obj.FilePath == impFile.FilePath); ifi.NumOfItems += commonItemsH.Count; result.BaseLayerStructure.HeaderFileItems.InsertRange(ifi.StartIndex, commonItemsH); } foreach (var layerStructure in result.LayerStructures) { if (layerNames.Contains(layerStructure.LayerName)) { ImportedFileInfomation ifi = layerStructure.ImportedLhInfomation.Find((obj) => obj.FilePath == impFile.FilePath); ifi.NumOfItems += commonItemsH.Count; layerStructure.HeaderFileItems.InsertRange(ifi.StartIndex, commonItemsH); } } } // .lhファイル以外 else { ImportedFileInfomation ifi = new ImportedFileInfomation(impFile.FilePath); ifi.StartIndex = result.BaseClassHeaderItems.Count; ifi.NumOfItems = impFileItems.Count(); result.ImportedBaseClassHeaderInfomation.Add(ifi); result.BaseClassHeaderItems.AddRange(impFileItems); } } }; InterpretImportedFiles(sourceFile); // 結果を返す return(result); }