Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various Cpp/C target fixes #145

Open
wants to merge 54 commits into
base: master
Choose a base branch
from
Open

Various Cpp/C target fixes #145

wants to merge 54 commits into from

Conversation

ibre5041
Copy link
Contributor

@ibre5041 ibre5041 commented Feb 7, 2014

Fix compilation for C target when compiled using MSVC 2010
Memory leak fix for Cpp target
Various fixes for lexer label ref. for Cpp target

@ibre5041 ibre5041 changed the title MSVC 2010 compile fix Various Cpp/C target fixes May 13, 2014
ibre5041 and others added 27 commits July 27, 2014 13:38
…ng C, which means C89. All block-local variables need to be declared at the beginning of your functions.

Or at begginning of {} block.
Inspired by bennyk. Since this patch uses std::unique_ptr the build now requires
a compiler supporting at least some of C++11 features.
+ minor fix - remover StringTemplate warning in matchSet/terminalOptions
Python target used as an example
= The current code depends on the fact that EOF is #define EOF -1 is some standart C headers
= While generated enums use EOF_TOKEN
= Moreover EOF(-1) is signed value while LA an other methods return ANTLR_UINT32, this cause plenty of compiler warnings
= Moreover clang++11 refuses compile code like this:

    switch(this->LA(1)
    {
    case EOF: // -1
    ...

This patch sets EOF_TOKEN = std::numerical_limits<ANTLR_UINT32>::max()
All generated local varibles are of type ANTLR_UINT32 (instead of int)
Generated conditions use EOF_TOKEN instead if pure EOF
Allocate tree storage only withing context of the root grammar.
SEGFAULT fix - m_dirty flag (align with Java target)
Explanation:
For code(using labels e1, e2) like this:

sample_clause
    :    sample_key block_key?
        LEFT_PAREN e1=expression (COMMA e2=expression)? RIGHT_PAREN
        seed_part?
        -> ^(sample_key block_key? ^(EXPR $e1) ^(EXPR $e2)? seed_part?)
    ;

ANTLR generates code like this:
	e1=expression();
	...
	if ( this->get_backtracking()==0 ) stream_expression.add(e1.tree);
	...
	...
        // AST REWRITE
        // elements: e1, e2, block_key, sample_key, seed_part
        // token labels:
        // rule labels: retval, e1, e2
        // token list labels:
        // rule list labels:
        // wildcard labels:
        if ( this->get_backtracking()==0 ) {
            retval.tree = std::move(root_0);
            RewriteRuleSubtreeStream<ImplTraits> stream_retval(get_psrstate()->get_treeAdaptor(), "rule retval",retval.tree); // retval
            RewriteRuleSubtreeStream<ImplTraits> stream_e1(get_psrstate()->get_treeAdaptor(), "rule e1",e1.tree); // rewrite alias
            RewriteRuleSubtreeStream<ImplTraits> stream_e2(get_psrstate()->get_treeAdaptor(), "rule e2",e2.tree); // rewrite alias
	...

The variable e1 of type expression_return is assigned into two different SubTreeStreams.
Since destructive copying is used(unique_ptr) the second assignment inserts NULL ptr into stream_e1.

A new variable of type TreeType* (pure pointer) is added. A value of this pointer is used ONLY when
inserting a tree into alias'es RewriteRuleSubtreeStream. When there are no aliases declared in the rule the "last pointer" remains unused.
When inserting TreeTypePtr into a stream value is moved. When inserting a pure pointer into the aliases stream the whole tree is deeply dupped
(assuming that the original tree was already moved into some other RewriteRuleSubtreeStream).

New result:
        if ( this->get_backtracking()==0 ) {
            retval.tree = std::move(root_0);
            RewriteRuleSubtreeStream<ImplTraits> stream_retval(get_psrstate()->get_treeAdaptor(), "rule retval",retval.tree); // retval
            RewriteRuleSubtreeStream<ImplTraits> stream_e1(get_psrstate()->get_treeAdaptor(), "rule e1",e1_last); // rewrite alias
            RewriteRuleSubtreeStream<ImplTraits> stream_e2(get_psrstate()->get_treeAdaptor(), "rule e2",e2_last); // rewrite alias

Note: we have also deal with this situation.

unpivot_in_elements
    :   (    column_name
        |    LEFT_PAREN column_name (COMMA column_name)* RIGHT_PAREN
        )
        (     as_key
         (    constant
         |    (LEFT_PAREN)=> LEFT_PAREN constant (COMMA constant)* RIGHT_PAREN
         )
        )?
        -> column_name+ ^(PIVOT_ALIAS constant+)?
    ;

The AST tree contains multiple instances of "column_name".
RewriteRuleSubtreeStream can not contain reference(pointer) into matched tree as it would get overwritten
in every "loop". It really needs to be moved.
ibre5041 and others added 19 commits August 15, 2014 21:43
- unused #define macros removed
- unused class templates removed
- unused #include-s removed
= note: macros ANTLR_ENC_* are no more used
=       use enums antlr3::ENC_* instead
create( ANTLR_UINT32 tokenType, const CommonTokenType* fromToken, const char* text);
_LA renamed to LA

Conflicts:
	runtime/Cpp/include/antlr3intstream.inl
    _LT renamed to LT

Conflicts:
	runtime/Cpp/include/antlr3treeparser.inl
…every tree node.

Conflicts:
	tool/src/main/resources/org/antlr/codegen/templates/Cpp/Cpp.stg
_LA renamed to LA
_LT renamed to LT

    Function name aligned

    _LT renamed to LT

test synced _LT => LT
ibre5041 and others added 5 commits September 6, 2015 16:54
Also:
	CommonTree<ImplTraits>::toString() calls Token's method toString() insted of getText()
	Test a007 shows how to use Token's UserData to pass information from Tree node to Tree leaf
	Test a007 shows how to override Tokens toString() method
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants