+bool
+TPushParser::correctBrace()
+{
+ // this method MUST be invoked when the cursor is child of a
+ // phantom group, which in turn is the last rightOpen MACRO's child.
+ // The only way to exit from a rightOpen MACRO is opening a group before
+ // inserting the MACRO and, once the MACRO is completely inserted, closing
+ // the group.
+ // This method return true if the condition above is true. False, otherwise.
+ assert(cursor.parent() && cursor.parent().isG() && !cursor.parent().hasId());
+ TNode parent = cursor.parent();
+ assert(parent.parent() && parent.parent().isC());
+ assert(!frames.empty());
+ Frame& frame = frames.top();
+ assert(frame.entry.rightOpen);
+ assert(parent.parent().last() == parent);
+
+ TNode c = parent.parent();
+ bool stop = false;
+ bool ok = false;
+ TNode node = c.parent();
+ do
+ {
+ if (node.isG() && node.hasId())
+ {
+ // in this case, the rightOpen MACRO is a child of a group with id.
+ // So, the '}' is correct
+ ok = true;
+ stop = true;
+ }
+ else if (node.isG())
+ {
+ // the MACRO is a phantom group's child. We have to control why we
+ // have this phantom group
+ TNode nodeParent = node.parent();
+ if (nodeParent && nodeParent.isC())
+ {
+ // we have to control the nature of this MACRO
+ const TDictionary::Entry& entry = dictionary.find(nodeParent.nameC());
+ if (entry.rightOpen && node == nodeParent.last())
+ {
+ // in this case we have to re-iterate the process
+ node = nodeParent.parent();
+ }
+ else stop = true;
+ }
+ else stop = true;
+ }
+ else
+ {
+ // at the moment we assume that a MACRO cannot be child of an element other than a group
+ stop = true;
+ }
+ }
+ while (!stop);
+
+ return ok;
+}
+
+bool