[antlr-interest] [antlr-dev] Generated code checks for backtracking even though backtracking is off

Sam Harwell sharwell at pixelminegames.com
Mon Feb 28 14:37:09 PST 2011


Hi Susanna,

 

Actions are not executed as part of a syntactic predicate. As a simplified
example, take the following:

 

rule : (x {Foo();}) => x;

 

Foo() will not be called here, instead, you should write:

 

rule : (x) => x {Foo();};

 

Sam

 

From: antlr-dev-bounces at antlr.org [mailto:antlr-dev-bounces at antlr.org] On
Behalf Of Susanna Siebert
Sent: Monday, February 28, 2011 2:19 PM
To: antlr-dev at antlr.org
Subject: [antlr-dev] Generated code checks for backtracking even though
backtracking is off

 

Hi everybody,

we are trying to add custom bracematching to our language, Hop. For example,
our functions are designed in the form action myAction .. end, where we are
trying to match the "action" with the "end". To do that we added some
semantic actions to the appropriate rules in the *.g file, that add some
information about the position of the tokens to a hash table in a matcher
module. This works fine except for the if-else-statements. These look like
so:

if_statement    
    :
    firstif = IF root_expression THEN { symbol.add(new BlockDescriptor()); }
block { symbol.popScope(); } firstend = END 
    {
        MatchKeyword keyword1 = new MatchKeyword();
        keyword1.setMatchID(((CommonToken)$firstif).getStartIndex());
        keyword1.setStartOffset(((CommonToken)$firstif).getStartIndex() -
$firstif.getLine() + 1);
        keyword1.setEndOffset(((CommonToken)$firstif).getStopIndex() -
$firstif.getLine() + 2);
        keyword1.setIsPrefix(true); 
        MatchKeyword keyword2 = new MatchKeyword();
        keyword2.setMatchID(((CommonToken)$firstif).getStartIndex());
        keyword2.setStartOffset(((CommonToken)$firstend).getStartIndex() -
$firstend.getLine() + 1);
        keyword2.setEndOffset(((CommonToken)$firstend).getStopIndex() -
$firstend.getLine() + 2);
        keyword2.setIsPrefix(false); 
        matcher.addMatch(keyword1, keyword2);
    }
    ((firstelse = ELSE IF root_expression THEN { symbol.add(new
BlockDescriptor()); } block { symbol.popScope(); } secondend = END 
    {
        MatchKeyword keyword1 = new MatchKeyword();
        keyword1.setMatchID(((CommonToken)$firstelse).getStartIndex());
        keyword1.setStartOffset(((CommonToken)$firstelse).getStartIndex() -
$firstelse.getLine() + 1);
        keyword1.setEndOffset(((CommonToken)$firstelse).getStopIndex() -
$firstelse.getLine() + 2);
        keyword1.setIsPrefix(true); 
        MatchKeyword keyword2 = new MatchKeyword();
        keyword2.setMatchID(((CommonToken)$firstelse).getStartIndex());
        keyword2.setStartOffset(((CommonToken)$secondend).getStartIndex() -
$secondend.getLine() + 1);
        keyword2.setEndOffset(((CommonToken)$secondend).getStopIndex() -
$secondend.getLine() + 2);
        keyword2.setIsPrefix(false); 
        matcher.addMatch(keyword1, keyword2);
    }
    ) => (ELSE IF root_expression THEN block END))*  //else if blocks
    ((secondelse = ELSE THEN { symbol.add(new BlockDescriptor()); } block {
symbol.popScope(); } thirdend = END
    {
        MatchKeyword keyword1 = new MatchKeyword();
        keyword1.setMatchID(((CommonToken)$secondelse).getStartIndex());
        keyword1.setStartOffset(((CommonToken)$secondelse).getStartIndex() -
$secondelse.getLine() + 1);
        keyword1.setEndOffset(((CommonToken)$secondelse).getStopIndex() -
$secondelse.getLine() + 2);
        keyword1.setIsPrefix(true); 
        MatchKeyword keyword2 = new MatchKeyword();
        keyword2.setMatchID(((CommonToken)$secondelse).getStartIndex());
        keyword2.setStartOffset(((CommonToken)$thirdend).getStartIndex() -
$thirdend.getLine() + 1);
        keyword2.setEndOffset(((CommonToken)$thirdend).getStopIndex() -
$thirdend.getLine() + 2);
        keyword2.setIsPrefix(false); 
        matcher.addMatch(keyword1, keyword2);
    }
    ) => (ELSE THEN block END) )? 
    ;

The problem is that when the code is generated, the semantic actions are
being surrounded by an if-statement that checks state.backtracking (if
(state.backtracking == 0) {}). For the if-then part of the rule, this check
evaluates to true but for the else-if-then and else-then it evaluates to
false because state.backtracking is 1. However, backtracking is turned off. 

My questions now are: 
Why is a check for state.backtracking added when code is generated even if
backtracking is turned off? 
How can I make sure that the semantic actions of the else-if-then and
else-then are being executed? 

I appreciate your help.

Best regards,

Susanna Siebert



More information about the antlr-interest mailing list