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

Update DRL6Expressions.g4 to ANTLR 4 #47

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions drools-parser/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-drl-ast</artifactId>
<version>${version.drools-drl-ast}</version>
<version>${version.org.drools}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-util</artifactId>
<version>${version.drools-drl-ast}</version>
<version>${version.org.drools}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-drl-parser</artifactId>
<version>${version.org.drools}</version>
</dependency>

<!-- External dependencies -->
Expand Down
366 changes: 189 additions & 177 deletions drools-parser/src/main/antlr4/org/drools/parser/DRL6Expressions.g4

Large diffs are not rendered by default.

21 changes: 14 additions & 7 deletions drools-parser/src/main/java/org/drools/parser/DRLExpressions.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@
import java.util.LinkedList;
import java.util.List;

import org.antlr.runtime.Parser;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.RecognizerSharedState;
import org.antlr.runtime.TokenStream;
import org.antlr.v4.runtime.Parser;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.TokenStream;
import org.drools.drl.ast.descr.BaseDescr;
import org.drools.drl.parser.DroolsParserException;
import org.drools.drl.parser.lang.DroolsSentence;

public abstract class DRLExpressions extends Parser {
public DRLExpressions(TokenStream input, RecognizerSharedState state) {
super(input, state);
public DRLExpressions(TokenStream input) {
super(input);
}

public abstract void setBuildDescr( boolean build );
Expand All @@ -42,7 +42,14 @@ public DRLExpressions(TokenStream input, RecognizerSharedState state) {
public abstract void setHasBindings( boolean value );
public abstract boolean hasBindings();

public abstract BaseDescr conditionalOrExpression() throws RecognitionException;
/*
* This is the original method signature in drools/drools-drl/drools-drl-parser:
* public abstract BaseDescr conditionalOrExpression() throws RecognitionException;
* I changed it here because the conditionalOrExpression() method generated by ANTLR 4 from the conditionalOrExpression rule
* returns ConditionalOrExpressionContext, so it has a return type that's different from what was originally expected here.
* The Descr object is of course inside that context (go to this method's impl to see).
*/
public abstract BaseDescr conditionalOrExpressionDescr() throws RecognitionException;

public abstract ParserHelper getHelper();
public abstract boolean hasErrors();
Expand Down
34 changes: 16 additions & 18 deletions drools-parser/src/main/java/org/drools/parser/DrlExprParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,12 @@
import java.util.Collections;
import java.util.List;

import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.RecognizerSharedState;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.drools.drl.ast.descr.BaseDescr;
import org.drools.drl.ast.descr.ConstraintConnectiveDescr;
import org.drools.drl.parser.lang.ParserHelper;
import org.drools.drl.parser.DroolsParserException;
import org.kie.internal.builder.conf.LanguageLevelOption;

/**
Expand All @@ -45,23 +44,22 @@ public DrlExprParser(LanguageLevelOption languageLevel) {
}

/** Parse an expression from text */
public ConstraintConnectiveDescr parse( final String text ) {
public ConstraintConnectiveDescr parse(final String text) {
ConstraintConnectiveDescr constraint = null;
try {
DRLLexer lexer = DRLFactory.getDRLLexer(new ANTLRStringStream(text), languageLevel);
CommonTokenStream input = new CommonTokenStream( lexer );
RecognizerSharedState state = new RecognizerSharedState();
helper = new ParserHelper( input, state, languageLevel );
DRLExpressions parser = DRLFactory.getDRLExpressions(input, state, helper, languageLevel);
parser.setBuildDescr( true );
parser.setLeftMostExpr( null ); // setting initial value just in case
BaseDescr expr = parser.conditionalOrExpression();
if ( expr != null && !parser.hasErrors() ) {
DRLLexer lexer = new DRLLexer(CharStreams.fromString(text));
CommonTokenStream input = new CommonTokenStream(lexer);
helper = new ParserHelper(input, null, languageLevel);
DRLExpressions parser = new DRL6Expressions(input, helper);
parser.setBuildDescr(true);
parser.setLeftMostExpr(null); // setting initial value just in case
BaseDescr expr = parser.conditionalOrExpressionDescr();
if (expr != null && !parser.hasErrors()) {
constraint = ConstraintConnectiveDescr.newAnd();
constraint.addOrMerge( expr );
constraint.addOrMerge(expr);
}
} catch ( RecognitionException e ) {
helper.reportError( e );
} catch (RecognitionException e) {
helper.reportError(e);
}
return constraint;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,18 @@
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.antlr.runtime.BitSet;
import org.antlr.runtime.EarlyExitException;
import org.antlr.runtime.FailedPredicateException;
import org.antlr.runtime.MismatchedNotSetException;
import org.antlr.runtime.MismatchedSetException;
import org.antlr.runtime.MismatchedTokenException;
import org.antlr.runtime.MismatchedTreeNodeException;
import org.antlr.runtime.NoViableAltException;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.Token;
import org.antlr.v4.runtime.FailedPredicateException;
import org.antlr.v4.runtime.NoViableAltException;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Token;
import org.drools.drl.parser.DRLFactory;
import org.drools.drl.parser.DroolsParserException;
import org.drools.drl.parser.lang.DroolsParaphraseTypes;
import org.kie.internal.builder.conf.LanguageLevelOption;

/**
Expand All @@ -48,14 +42,7 @@
* @see DroolsParserException
*/
public class DroolsParserExceptionFactory {
public final static String MISMATCHED_TOKEN_MESSAGE_COMPLETE = "Line %1$d:%2$d mismatched input '%3$s' expecting '%4$s'%5$s";
public final static String MISMATCHED_TOKEN_MESSAGE_PART = "Line %1$d:%2$d mismatched input '%3$s'%4$s";
public final static String MISMATCHED_TREE_NODE_MESSAGE_COMPLETE = "Line %1$d:%2$d mismatched tree node '%3$s' expecting '%4$s'%5$s";
public final static String MISMATCHED_TREE_NODE_MESSAGE_PART = "Line %1$d:%2$d mismatched tree node '%3$s'%4$s";
public final static String NO_VIABLE_ALT_MESSAGE = "Line %1$d:%2$d no viable alternative at input '%3$s'%4$s";
public final static String EARLY_EXIT_MESSAGE = "Line %1$d:%2$d required (...)+ loop did not match anything at input '%3$s'%4$s";
public final static String MISMATCHED_SET_MESSAGE = "Line %1$d:%2$d mismatched input '%3$s' expecting one of the following tokens: '%4$s'%5$s.";
public final static String MISMATCHED_NOT_SET_MESSAGE = "Line %1$d:%2$d mismatched input '%3$s' not expecting any of the following tokens: '%4$s'%5$s";
public final static String FAILED_PREDICATE_MESSAGE = "Line %1$d:%2$d rule '%3$s' failed predicate: {%4$s}?%5$s";
public final static String TRAILING_SEMI_COLON_NOT_ALLOWED_MESSAGE = "Line %1$d:%2$d trailing semi-colon not allowed%3$s";
public final static String PARSER_LOCATION_MESSAGE_COMPLETE = " in %1$s %2$s";
Expand Down Expand Up @@ -125,9 +112,10 @@ public DroolsParserException createDroolsException( RecognitionException e ) {
return new DroolsParserException( codeAndMessage.get( 1 ),
codeAndMessage
.get( 0 ),
e.line,
e.charPositionInLine,
e.index,
// TODO verify this is correct
e.getOffendingToken().getLine(),
e.getOffendingToken().getCharPositionInLine(),
e.getOffendingToken().getStartIndex(),
e );
}

Expand All @@ -138,119 +126,27 @@ public DroolsParserException createDroolsException( RecognitionException e ) {
private List<String> createErrorMessage( RecognitionException e ) {
List<String> codeAndMessage = new ArrayList<>( 2 );
String message;
if ( e instanceof MismatchedTokenException ) {
MismatchedTokenException mte = (MismatchedTokenException) e;
String expecting = mte instanceof DroolsMismatchedTokenException ? ((DroolsMismatchedTokenException)mte).getTokenText() : getBetterToken( mte.expecting );
if ( tokenNames != null && mte.expecting >= 0 && mte.expecting < tokenNames.length ) {
message = String
.format(
MISMATCHED_TOKEN_MESSAGE_COMPLETE,
e.line,
e.charPositionInLine,
getBetterToken( e.token ),
expecting,
formatParserLocation() );
codeAndMessage.add( message );
codeAndMessage.add( "ERR 102" );
} else {
message = String
.format(
MISMATCHED_TOKEN_MESSAGE_PART,
e.line,
e.charPositionInLine,
getBetterToken( e.token ),
formatParserLocation() );
codeAndMessage.add( message );
codeAndMessage.add( "ERR 102" );
}
} else if ( e instanceof MismatchedTreeNodeException ) {
MismatchedTreeNodeException mtne = (MismatchedTreeNodeException) e;
if ( mtne.expecting >= 0 && mtne.expecting < tokenNames.length ) {
message = String
.format(
MISMATCHED_TREE_NODE_MESSAGE_COMPLETE,
e.line,
e.charPositionInLine,
getBetterToken( e.token ),
getBetterToken( mtne.expecting ),
formatParserLocation() );
codeAndMessage.add( message );
codeAndMessage.add( "ERR 106" );
} else {
message = String
.format(
MISMATCHED_TREE_NODE_MESSAGE_PART,
e.line,
e.charPositionInLine,
getBetterToken( e.token ),
formatParserLocation() );
codeAndMessage.add( message );
codeAndMessage.add( "ERR 106" );
}
} else if ( e instanceof NoViableAltException ) {
if ( e instanceof NoViableAltException ) {
// NoViableAltException nvae = (NoViableAltException) e;
message = String.format(
NO_VIABLE_ALT_MESSAGE,
e.line,
e.charPositionInLine,
getBetterToken( e.token ),
// TODO verify this is correct
e.getOffendingToken().getLine(),
e.getOffendingToken().getCharPositionInLine(),
getBetterToken( e.getOffendingToken() ),
formatParserLocation() );
codeAndMessage.add( message );
codeAndMessage.add( "ERR 101" );
} else if ( e instanceof EarlyExitException ) {
// EarlyExitException eee = (EarlyExitException) e;
message = String.format(
EARLY_EXIT_MESSAGE,
e.line,
e.charPositionInLine,
getBetterToken( e.token ),
formatParserLocation() );
codeAndMessage.add( message );
codeAndMessage.add( "ERR 105" );
} else if ( e instanceof MismatchedSetException ) {
MismatchedSetException mse = (MismatchedSetException) e;
String expected = expectedTokensAsString( mse.expecting );
message = String.format(
MISMATCHED_SET_MESSAGE,
e.line,
e.charPositionInLine,
getBetterToken( e.token ),
expected,
formatParserLocation() );
codeAndMessage.add( message );
codeAndMessage.add( "ERR 107" );
} else if ( e instanceof DroolsMismatchedSetException ) {
DroolsMismatchedSetException mse = (DroolsMismatchedSetException) e;
String expected = Arrays.asList( mse.getTokenText() ).toString();
message = String.format(
MISMATCHED_SET_MESSAGE,
e.line,
e.charPositionInLine,
getBetterToken( e.token ),
expected,
formatParserLocation() );
codeAndMessage.add( message );
codeAndMessage.add( "ERR 107" );
} else if ( e instanceof MismatchedNotSetException ) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of these deleted mismatch branches should perhaps be replaced with the InputMismatchException. There is also the LexerNoViableAltException in ANTLR 4. It would be nice to add those together with some negative tests so that we have a better understanding under which conditions these exceptions occur.

See https://github.com/antlr/antlr4/blob/master/doc/parser-rules.md#catching-exceptions.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yurloc Thanks. Please file a JIRA to add tests to cover the use cases. There are drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/compiler/lang/ErrorsParserTest.java, but probably it's not enough.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MismatchedNotSetException mse = (MismatchedNotSetException) e;
String expected = expectedTokensAsString( mse.expecting );
message = String.format(
MISMATCHED_NOT_SET_MESSAGE,
e.line,
e.charPositionInLine,
getBetterToken( e.token ),
expected,
formatParserLocation() );
codeAndMessage.add( message );
codeAndMessage.add( "ERR 108" );
} else if ( e instanceof FailedPredicateException ) {
FailedPredicateException fpe = (FailedPredicateException) e;
String ruleName = fpe.getRecognizer().getRuleNames()[fpe.getRuleIndex()];
message = String.format(
FAILED_PREDICATE_MESSAGE,
e.line,
e.charPositionInLine,
fpe.ruleName,
fpe.predicateText,
// TODO verify this is correct
e.getOffendingToken().getLine(),
e.getOffendingToken().getCharPositionInLine(),
ruleName,
fpe.getPredicate(),
formatParserLocation() );
codeAndMessage.add( message );
codeAndMessage.add( "ERR 103" );
Expand All @@ -276,19 +172,6 @@ public DroolsParserException createDroolsException( Exception e,

}

private String expectedTokensAsString( BitSet set ) {
StringBuilder buf = new StringBuilder();
buf.append( "{ " );
int i = 0;
for ( int token : set.toArray() ) {
if ( i > 0 ) buf.append( ", " );
buf.append( getBetterToken( token ) );
i++;
}
buf.append( " }" );
return buf.toString();
}

/**
* This will take Paraphrases stack, and create a sensible location
*/
Expand Down Expand Up @@ -364,17 +247,4 @@ private String getBetterToken( Token token ) {
}
return DRLFactory.getBetterToken(token.getType(), token.getText(), languageLevel);
}

/**
* Helper method that creates a user friendly token definition
*
* @param tokenType
* token type
* @return user friendly token definition
*/
private String getBetterToken( int tokenType ) {
return DRLFactory.getBetterToken( tokenType, null, languageLevel );
}


}
14 changes: 10 additions & 4 deletions drools-parser/src/main/java/org/drools/parser/ParserHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@
import java.util.List;
import java.util.Map;

import org.antlr.runtime.CommonToken;
import org.antlr.runtime.RecognitionException;
import org.antlr.v4.runtime.CommonToken;
import org.antlr.runtime.RecognizerSharedState;
import org.antlr.runtime.Token;
import org.antlr.runtime.TokenStream;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.TokenStream;
import org.drools.drl.ast.descr.AttributeDescr;
import org.drools.drl.ast.descr.BaseDescr;
import org.drools.drl.ast.dsl.AbstractClassTypeDeclarationBuilder;
Expand Down Expand Up @@ -78,6 +78,12 @@
import org.drools.drl.ast.dsl.UnitDescrBuilder;
import org.drools.drl.ast.dsl.WindowDeclarationDescrBuilder;
import org.drools.drl.parser.DroolsParserException;
import org.drools.drl.parser.lang.DroolsEditorType;
import org.drools.drl.parser.lang.DroolsParaphraseTypes;
import org.drools.drl.parser.lang.DroolsSentence;
import org.drools.drl.parser.lang.DroolsSentenceType;
import org.drools.drl.parser.lang.DroolsSoftKeywords;
import org.drools.drl.parser.lang.DroolsToken;
import org.kie.internal.builder.conf.LanguageLevelOption;

/**
Expand Down
Loading
Loading