// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; using System.Collections.Generic; using System.Text; using PascalABCCompiler.SyntaxTree; namespace PascalABCCompiler.TreeConverter { public class CompilerDirectivesToSyntaxTreeNodesLinker { public static Dictionary BuildLinks(SyntaxTree.compilation_unit unit, List ErrorsList) { Dictionary links = new Dictionary(); SyntaxTreeNodeFinder finder = new SyntaxTreeNodeFinder(); if (unit.compiler_directives != null) foreach (compiler_directive cd in unit.compiler_directives) if (IsKnownDirectivee(cd)) { syntax_tree_node sn = finder.Find(unit, cd.source_context); if (sn != null) if (!links.ContainsKey(sn)) links.Add(sn, cd); else ErrorsList.Add(new PascalABCCompiler.Errors.CommonCompilerError("Повторное объявление директивы", unit.file_name, sn.source_context.begin_position.line_num, sn.source_context.begin_position.column_num)); } return links; } private static bool IsKnownDirectivee(compiler_directive cd) { return cd.Name.text.ToLower() == "omp"; } } class SyntaxTreeNodeFinder : WalkingVisitorNew { SourceContext _findContext = null; syntax_tree_node _findResult = null; public syntax_tree_node Find(SyntaxTree.compilation_unit unit, SourceContext findContext) { _findContext = findContext; _findResult = null; //unit.visit(this); ProcessNode(unit); return _findResult; } private bool FindContextIn(syntax_tree_node node) { return _findContext.In(node.source_context); } private bool FindContextBetween(syntax_tree_node node1, syntax_tree_node node2) { return _findContext.Between(node1.source_context, node2.source_context); } //второй узел начинается после конца первого private bool ContextInRightOrder(SourceContext sc1, SourceContext sc2) { return (sc1.end_position.line_num