001: /* Generated By:JJTree: Do not edit this line. JJTPnutsParserState.java */
002:
003: package pnuts.lang;
004:
005: import org.pnuts.util.Stack;
006:
007: class JJTPnutsParserState {
008: private Stack nodes;
009: private Stack marks;
010: private int sp; // number of nodes on stack
011: private int mk; // current mark
012: private boolean node_created;
013:
014: JJTPnutsParserState() {
015: nodes = new Stack();
016: marks = new Stack();
017: sp = 0;
018: mk = 0;
019: }
020:
021: /*
022: * Determines whether the current node was actually closed and pushed. This
023: * should only be called in the final user action of a node scope.
024: */
025: boolean nodeCreated() {
026: return node_created;
027: }
028:
029: /*
030: * Call this to reinitialize the node stack. It is called automatically by
031: * the parser's ReInit() method.
032: */
033: void reset() {
034: nodes.removeAllElements();
035: marks.removeAllElements();
036: sp = 0;
037: mk = 0;
038: }
039:
040: /*
041: * Returns the root node of the AST. It only makes sense to call this after
042: * a successful parse.
043: */
044: // SimpleNode rootNode() {
045: // return (SimpleNode)nodes.elementAt(0);
046: // }
047: /* Pushes a node on to the stack. */
048: void pushNode(SimpleNode n) {
049: nodes.push(n);
050: ++sp;
051: }
052:
053: /*
054: * Returns the node on the top of the stack, and remove it from the stack.
055: */
056: SimpleNode popNode() {
057: if (--sp < mk) {
058: mk = ((Integer) marks.pop()).intValue();
059: }
060: return (SimpleNode) nodes.pop();
061: }
062:
063: /* Returns the node currently on the top of the stack. */
064: SimpleNode peekNode() {
065: return (SimpleNode) nodes.peek();
066: }
067:
068: /*
069: * Returns the number of children on the stack in the current node scope.
070: */
071: int nodeArity() {
072: return sp - mk;
073: }
074:
075: void clearNodeScope(SimpleNode n) {
076: while (sp > mk) {
077: popNode();
078: }
079: mk = ((Integer) marks.pop()).intValue();
080: }
081:
082: void openNodeScope(SimpleNode n) {
083: marks.push(new Integer(mk));
084: mk = sp;
085: // n.jjtOpen();
086: }
087:
088: /*
089: * A definite node is constructed from a specified number of children. That
090: * number of nodes are popped from the stack and made the children of the
091: * definite node. Then the definite node is pushed on to the stack.
092: */
093: void closeNodeScope(SimpleNode n, int num) {
094: mk = ((Integer) marks.pop()).intValue();
095: while (num-- > 0) {
096: SimpleNode c = popNode();
097: c.jjtSetParent(n);
098: n.jjtAddChild(c, num);
099: }
100: // n.jjtClose();
101: pushNode(n);
102: node_created = true;
103: }
104:
105: /*
106: * A conditional node is constructed if its condition is true. All the nodes
107: * that have been pushed since the node was opened are made children of the
108: * the conditional node, which is then pushed on to the stack. If the
109: * condition is false the node is not constructed and they are left on the
110: * stack.
111: */
112: void closeNodeScope(SimpleNode n, boolean condition) {
113: if (condition) {
114: int a = nodeArity();
115: mk = ((Integer) marks.pop()).intValue();
116: while (a-- > 0) {
117: SimpleNode c = popNode();
118: c.jjtSetParent(n);
119: n.jjtAddChild(c, a);
120: }
121: // n.jjtClose();
122: pushNode(n);
123: node_created = true;
124: } else {
125: mk = ((Integer) marks.pop()).intValue();
126: node_created = false;
127: }
128: }
129: }
|