Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

antlr 4 - warning: rule contains an optional block with at least one alternative that can match an empty string

Tags:

antlr

antlr4

I work with antlr v4 to write a t-sql parser. Is this warning a problem?

"rule 'sqlCommit' contains an optional block with at least one alternative that can match an empty string"

My Code:

sqlCommit: COMMIT (TRAN | TRANSACTION | WORK)? id?;

id:
ID  | CREATE | PROC | AS | EXEC | OUTPUT| INTTYPE |VARCHARTYPE |NUMERICTYPE |CHARTYPE |DECIMALTYPE | DOUBLETYPE | REALTYPE
|FLOATTYPE|TINYINTTYPE|SMALLINTTYPE|DATETYPE|DATETIMETYPE|TIMETYPE|TIMESTAMPTYPE|BIGINTTYPE|UNSIGNEDBIGINTTYPE..........
;

ID: (LETTER | UNDERSCORE | RAUTE) (LETTER | [0-9]| DOT | UNDERSCORE)*

In a version before I used directly the lexer rule ID instead of the parser rule id in sqlCommit. But after change ID to id the warning appears.

(Hint if you are confused of ID and id: I want to use the parser rule id instead of ID because an identifier can be a literal which maybe already matched by an other lexer rule)

Regards

EDIT With the help of "280Z28" I solved the problem. In the parser rule "id" was one slash more than needed: BITTYPE|CREATE|PROC| |AS|EXEC|OUTPUT|

So the | | includes that the parser rule can match an empty string.

like image 387
phil Avatar asked Sep 25 '14 14:09

phil


1 Answers

From a Google search:

ErrorType.EPSILON_OPTIONAL

Compiler Warning 154.

rule rule contains an optional block with at least one alternative that can match an empty string

A rule contains an optional block ((...)?) around an empty alternative.

The following rule produces this warning.

x  : ;
y  : x?;                                // warning 154
z1 : ('foo' | 'bar'? 'bar2'?)?;         // warning 154
z2 : ('foo' | 'bar' 'bar2'? | 'bar2')?; // ok

Since:
4.1

The problem described by this warning is primarily a performance problem. By wrapping a zero-length string in an optional block, you added a completely unnecessary decision to the grammar (whether to enter the optional block or not) which has a high likelihood of forcing the prediction algorithm through its slowest path. It's similar to wrapping Java code in the following:

if (slowMethodThatAlwaysReturnsTrue()) {
  ...
}
like image 89
Sam Harwell Avatar answered Oct 22 '22 04:10

Sam Harwell