summaryrefslogtreecommitdiffstats
path: root/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/documentation/paren_stack.txt
diff options
context:
space:
mode:
Diffstat (limited to 'debian/uncrustify-trinity/uncrustify-trinity-0.74.0/documentation/paren_stack.txt')
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/documentation/paren_stack.txt221
1 files changed, 221 insertions, 0 deletions
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/documentation/paren_stack.txt b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/documentation/paren_stack.txt
new file mode 100644
index 00000000..109709dc
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/documentation/paren_stack.txt
@@ -0,0 +1,221 @@
+
+=-----------------------------------------------------------------------------=
+* *
+* Paren Stack *
+* *
+=-----------------------------------------------------------------------------=
+
+At the heart of this algorithm are two stacks.
+There is the Paren Stack (PS) and the Frame stack.
+
+The PS (pse in the code) keeps track of braces, parens,
+if/else/switch/do/while/etc items -- anything that is nestable.
+
+Complex statements go through some of these BS_ stages:
+ BS_PAREN1 - paren on if/for/switch/while, etc
+ BS_PAREN2 - paren on do{}while()
+ BS_BRACE_DO - brace set on do{}
+ BS_BRACE2 - brace on if/else/for/switch/while
+ BS_ELSE - expecting 'else' after 'if'
+ BS_ELSEIF - expecting 'if' after 'else'
+ BS_WHILE - expecting 'while' after 'do'
+
+The file is processed one token at a time to support #if/#else/#endif
+preprocessors at any point.
+
+Take this simple if statement as an example:
+
+ if ( x )
+ {
+ x--;
+ }
+
+The stack would look like so:
+The format is first the token processed and then the PSE stack as it appears
+AFTER the token is processed.
+
+'if' [IF - PAREN1]
+'(' [IF - PAREN1] [SPAREN OPEN]
+'x' [IF - PAREN1] [SPAREN OPEN]
+')' [IF - BRACE2] <- note that the stage was changed on SPAREN_CLOSE
+'{' [IF - BRACE2] [BRACE OPEN]
+'x' [IF - BRACE2] [BRACE OPEN]
+'--' [IF - BRACE2] [BRACE OPEN]
+';' [IF - BRACE2] [BRACE OPEN]
+'}' [IF - ELSE]
+ <- lack of else kills the ELSE, closes statement
+
+Virtual brace example:
+ if ( x )
+ x--;
+ else if (y)
+ y--;
+ else
+ z++;
+
+'if' [IF - PAREN1]
+'(' [IF - PAREN1] [SPAREN OPEN]
+'x' [IF - PAREN1] [SPAREN OPEN]
+')' [IF - BRACE2]
+'x' [IF - BRACE2] [VBRACE OPEN] <- VBrace open inserted before because
+ the token was not '{'
+'--' [IF - BRACE2] [VBRACE OPEN]
+';' [IF - ELSE] <- Semicolon causes a VBrace close to be
+ inserted after the semicolon
+'else' [ELSE - ELSEIF] <- IF changed into ELSE, expect IF or BRACE
+'x' [ELSE - BRACE2] [VBRACE OPEN] <- lack of '{' -> VBrace
+'++' [ELSE - BRACE2] [VBRACE OPEN]
+';' <- VBrace close inserted after semicolon
+ ELSE removed after statement close
+
+Nested virtual brace example: (EOF represents the end of the file)
+ if ( x )
+ if (y)
+ y--;
+ else
+ z++;
+ EOF
+
+'if' [IF - PAREN1]
+'(' [IF - PAREN1] [PAREN OPEN]
+'x' [IF - PAREN1] [PAREN OPEN]
+')' [IF - BRACE2]
+'if' [IF - BRACE2] [VBRACE OPEN] [IF - PAREN1] <- VBrace on BRACE2, IF opened
+'(' [IF - BRACE2] [VBRACE OPEN] [IF - PAREN1] [SPAREN OPEN]
+'y' [IF - BRACE2] [VBRACE OPEN] [IF - PAREN1] [SPAREN OPEN]
+')' [IF - BRACE2] [VBRACE OPEN] [IF - BRACE2]
+'y' [IF - BRACE2] [VBRACE OPEN] [IF - BRACE2] [VBRACE OPEN]
+'--' [IF - BRACE2] [VBRACE OPEN] [IF - BRACE2] [VBRACE OPEN]
+';' [IF - BRACE2] [VBRACE OPEN] [IF - ELSE]
+'else' [IF - BRACE2] [VBRACE OPEN] [ELSE - ELSEIF]
+'z' [IF - BRACE2] [VBRACE OPEN] [ELSE - BRACE2] [VBRACE OPEN]
+'++' [IF - BRACE2] [VBRACE OPEN] [ELSE - BRACE2] [VBRACE OPEN]
+';' [IF - BRACE2] [VBRACE OPEN] [ELSE - BRACE2] - step1
+ [IF - BRACE2] [VBRACE OPEN] - step2
+ [IF - ELSE] - step3
+EOF
+
+-- this last semi is more complicated - first it terminates the VBRACE and then
+ the else, which then, since it is the end of a statement, terminates the
+ VBRACE. That bumps the IF stage to ELSE.
+ The EOF kills that off (since it is not an else)
+
+Order of operation:
+1) if TOS=VBRACE && PC=SEMI, insert VBRACE close, PC=>VBRACE close
+2) if PC=VBRACE close or PC=BRACE close, and TOS is complex (if/else/etc)
+ then advance complex stage. If statement ends, pop and advance
+
+
+Stages for each complex statement:
+if
+IF-PAREN1, IF-BRACE2, IF-ELSE
+
+if/else
+IF-PAREN1, IF-BRACE2, IF-ELSE, ELSE-ELSEIF, ELSE-BRACE2
+
+if/else if/else
+IF-PAREN1, IF-BRACE2, IF-ELSE, ELSE-ELSEIF, IF-PAREN1, IF-BRACE2, IF-ELSE, ELSE-ELSEIF, ELSE-BRACE2
+
+for
+FOR-PAREN1, FOR-BRACE2
+
+while
+WHILE-PAREN1, WHILE-BRACE2
+
+switch
+SWITCH-PAREN1, SWITCH-BRACE2
+
+synchronized
+SYNCHRONIZED-PAREN1
+
+do/while
+DO-BRACE_DO, DO-WHILE, WHILE-PAREN2
+
+
+Another less-interesting example:
+
+{
+ if (x)
+ volatile
+ {
+ y++;
+ }
+ return y;
+}
+
+'{' [BRACE OPEN]
+'if' [BRACE OPEN] [IF - PAREN1]
+'(' [BRACE OPEN] [IF - PAREN1] [PAREN OPEN]
+'x' [BRACE OPEN] [IF - PAREN1] [PAREN OPEN]
+')' [BRACE OPEN] [IF - BRACE2]
+'volatile' [BRACE OPEN] [IF - BRACE2] [VBRACE OPEN] [VOLATILE - BRACE2]
+'{' [BRACE OPEN] [IF - BRACE2] [VBRACE OPEN] [VOLATILE - BRACE2] [BRACE OPEN]
+'y' [BRACE OPEN] [IF - BRACE2] [VBRACE OPEN] [VOLATILE - BRACE2] [BRACE OPEN]
+'++' [BRACE OPEN] [IF - BRACE2] [VBRACE OPEN] [VOLATILE - BRACE2] [BRACE OPEN]
+';' [BRACE OPEN] [IF - BRACE2] [VBRACE OPEN] [VOLATILE - BRACE2] [BRACE OPEN]
+'}' [BRACE OPEN] [IF - ELSE] <- the brace close ends brace-open,
+ volatile-brace2 and vbrace-open
+'return' [BRACE OPEN] <- not else
+'y' [BRACE OPEN]
+';' [BRACE OPEN]
+'}' <- empties the stack
+
+
+=-----------------------------------------------------------------------------=
+* *
+* Parse Frames *
+* *
+=-----------------------------------------------------------------------------=
+
+The pse stack is kept on a frame stack.
+The frame stack is need for languages that support preprocessors (C, C++, C#)
+that can arbitrarily change code flow. It also isolates #define macros so
+that they are indented independently and do not affect the rest of the program.
+
+When an #if is hit, a copy of the current frame is push on the frame stack.
+When an #else/#elif is hit, a copy of the current stack is pushed under the
+#if frame and the original (pre-#if) frame is copied to the current frame.
+When #endif is hit, the top frame is popped.
+This has the following effects:
+ - a simple #if / #endif does not affect program flow
+ - #if / #else /#endif - continues from the #if clause
+
+When a #define is entered, the current frame is pushed and cleared.
+When a #define is exited, the frame is popped.
+
+
+Take this example, which isn't very exciting, as both the #if and #else parts
+end up with the same paren stack. This is the usual case.
+
+{
+ foo(param1,
+#ifdef DEBUG
+ "debug");
+#else
+ "release");
+#endif
+}
+
+Right before the #ifdef, we have this for the paren stack:
+ Top> [BRACE OPEN] [PAREN OPEN]
+
+The #ifdef pushes a copy of the current stack, so we have this:
+ Top> [BRACE OPEN] [PAREN OPEN]
+ [BRACE OPEN] [PAREN OPEN]
+
+The close paren after "debug" closes out the PAREN-OPEN on the top of the stack.
+ Top> [BRACE OPEN]
+ [BRACE OPEN] [PAREN OPEN]
+
+The #else swaps the top two frames.
+ Top> [BRACE OPEN] [PAREN OPEN]
+ [BRACE OPEN]
+
+Right after the #else, we hit another close paren after the "release".
+ Top> [BRACE OPEN]
+ [BRACE OPEN]
+
+At the #endif, the top of stack is thrown out, which restores us to the #if path.
+ Top> [BRACE OPEN]
+
+