antlr / intellij-plugin-v4

An IntelliJ plugin for ANTLR v4
https://plugins.jetbrains.com/plugin/7358-antlr-v4
BSD 3-Clause "New" or "Revised" License
467 stars 104 forks source link

errors in grammar can cause ANTLR error. #169

Closed parrt closed 9 years ago

parrt commented 9 years ago
2015-02-08 13:17:46: antlr4 -listener -lib /tmp/fun/play -o /tmp/fun/gen -visitor /tmp/fun/play/T.g4
error(20): T.g4:12:41: internal error: Rule fieldname undefined 
2015-02-08 13:17:46: antlr4 java.lang.NullPointerException
    at org.antlr.v4.automata.ParserATNFactory.elemList(ParserATNFactory.java:492)
    at org.antlr.v4.automata.ParserATNFactory.alt(ParserATNFactory.java:473)
    at org.antlr.v4.parse.ATNBuilder.alternative(ATNBuilder.java:557)
    at org.antlr.v4.parse.ATNBuilder.ruleBlock(ATNBuilder.java:291)
    at org.antlr.v4.automata.ParserATNFactory._createATN(ParserATNFactory.java:184)
    at org.antlr.v4.automata.ParserATNFactory.createATN(ParserATNFactory.java:134)
    at org.antlr.v4.Tool.processNonCombinedGrammar(Tool.java:414)
    at org.antlr.v4.Tool.process(Tool.java:387)
    at org.antlr.v4.Tool.processGrammarsOnCommandLine(Tool.java:346)
    at org.antlr.intellij.plugin.parsing.RunANTLROnGrammarFile.antlr(RunANTLROnGrammarFile.java:121)
    at org.antlr.intellij.plugin.parsing.RunANTLROnGrammarFile.run(RunANTLROnGrammarFile.java:63)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl$TaskRunnable.run(ProgressManagerImpl.java:621)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl$7.run(ProgressManagerImpl.java:422)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl$3.run(ProgressManagerImpl.java:194)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl.a(ProgressManagerImpl.java:281)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:233)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl.runProcess(ProgressManagerImpl.java:181)
    at com.intellij.openapi.application.impl.ApplicationImpl$10$1.run(ApplicationImpl.java:640)
    at com.intellij.openapi.application.impl.ApplicationImpl$8.run(ApplicationImpl.java:405)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
    at java.lang.Thread.run(Thread.java:695)
    at org.jetbrains.ide.PooledThreadExecutor$1$1.run(PooledThreadExecutor.java:56)

and again:

null
java.lang.NullPointerException
    at org.antlr.v4.automata.ParserATNFactory.elemList(ParserATNFactory.java:492)
    at org.antlr.v4.automata.ParserATNFactory.alt(ParserATNFactory.java:473)
    at org.antlr.v4.parse.ATNBuilder.alternative(ATNBuilder.java:557)
    at org.antlr.v4.parse.ATNBuilder.ruleBlock(ATNBuilder.java:291)
    at org.antlr.v4.automata.ParserATNFactory._createATN(ParserATNFactory.java:184)
    at org.antlr.v4.automata.ParserATNFactory.createATN(ParserATNFactory.java:134)
    at org.antlr.v4.Tool.processNonCombinedGrammar(Tool.java:414)
    at org.antlr.v4.Tool.process(Tool.java:387)
    at org.antlr.intellij.plugin.parsing.ParsingUtils.loadGrammars(ParsingUtils.java:299)
    at org.antlr.intellij.plugin.ANTLRv4PluginController.updateGrammarObjectsFromFile_(ANTLRv4PluginController.java:366)
    at org.antlr.intellij.plugin.ANTLRv4PluginController.updateGrammarObjectsFromFile(ANTLRv4PluginController.java:350)
    at org.antlr.intellij.plugin.ANTLRv4PluginController.grammarFileSavedEvent(ANTLRv4PluginController.java:260)
    at org.antlr.intellij.plugin.ANTLRv4PluginController$MyVirtualFileAdapter.contentsChanged(ANTLRv4PluginController.java:526)
    at sun.reflect.GeneratedMethodAccessor79.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.util.EventDispatcher.dispatch(EventDispatcher.java:88)
    at com.intellij.util.EventDispatcher.access$100(EventDispatcher.java:34)
    at com.intellij.util.EventDispatcher$1.invoke(EventDispatcher.java:68)
    at com.sun.proxy.$Proxy17.contentsChanged(Unknown Source)
    at com.intellij.openapi.vfs.impl.BulkVirtualFileListenerAdapter.fireAfter(BulkVirtualFileListenerAdapter.java:65)
    at com.intellij.openapi.vfs.impl.BulkVirtualFileListenerAdapter.after(BulkVirtualFileListenerAdapter.java:56)
    at sun.reflect.GeneratedMethodAccessor77.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.util.messages.impl.MessageBusConnectionImpl.deliverMessage(MessageBusConnectionImpl.java:114)
    at com.intellij.util.messages.impl.MessageBusImpl.doPumpMessages(MessageBusImpl.java:315)
    at com.intellij.util.messages.impl.MessageBusImpl.pumpMessages(MessageBusImpl.java:302)
    at com.intellij.util.messages.impl.MessageBusImpl.sendMessage(MessageBusImpl.java:287)
    at com.intellij.util.messages.impl.MessageBusImpl.access$200(MessageBusImpl.java:41)
    at com.intellij.util.messages.impl.MessageBusImpl$2.invoke(MessageBusImpl.java:177)
    at com.sun.proxy.$Proxy18.after(Unknown Source)
    at com.intellij.openapi.vfs.newvfs.persistent.PersistentFSImpl$5.close(PersistentFSImpl.java:649)
    at com.intellij.openapi.fileEditor.impl.LoadTextUtil.write(LoadTextUtil.java:259)
    at com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl$4.run(FileDocumentManagerImpl.java:421)
    at com.intellij.pom.core.impl.PomModelImpl.guardPsiModificationsIn(PomModelImpl.java:354)
    at com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl.a(FileDocumentManagerImpl.java:408)
    at com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl.a(FileDocumentManagerImpl.java:382)
    at com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl.saveAllDocuments(FileDocumentManagerImpl.java:303)
    at com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl.saveAllDocuments(FileDocumentManagerImpl.java:282)
    at com.intellij.openapi.application.impl.ApplicationImpl.saveAll(ApplicationImpl.java:1449)
    at com.intellij.ide.actions.SaveAllAction.actionPerformed(SaveAllAction.java:26)
    at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher$3.performAction(IdeKeyEventDispatcher.java:614)
    at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher.processAction(IdeKeyEventDispatcher.java:663)
    at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher.d(IdeKeyEventDispatcher.java:513)
    at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher.dispatchKeyEvent(IdeKeyEventDispatcher.java:211)
    at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:546)
    at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:384)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

FROM:

grammar T;

/*
1997-2007.is. -> is1997-2007)
1997-2007.yr. -> yr:[ 1997 TO 2007 ]
*/

term : field
     | date_field
     ;

field     : {!isDateField()}? string '.' fieldname ;

date_field: {isDateField()}? year ('-' year)? '.' fieldname ;

string : (d | letter|'_'|'-')+ ; // 1997-2007

fieldname : letter letter ;

year : d d d d ;

d   :   '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
    ;

letter
    :   'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j'
    |   'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't'
    |   'u' | 'v' | 'w' | 'x' | 'y' | 'z'
    |   'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J'
    |   'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T'
    |   'U' | 'V' | 'W' | 'X' | 'Y' | 'Z'
   ;

/*
word
title:word
word or word2
word or word2 and not word3

liver cancer and harvard
a and not b
a or not b

(not liver) or harvard
not (liver or harvard)
1 + (2 * 3)
(1 + 2) * 3

script : query ('\n' query)* '\n'? EOF ;

//query : 'not'? phrase (('and'|'or') 'not'? phrase)* ;

query : phrase                      # basic
      | 'not' query                 # negate
      | FIELD ':' query             # qualifier
      | query 'and' query           # AndOp
      | query 'or' query            # OrOp
      | '(' query ')'               # Group
      ;

// 3+4   1*2 + 3*4   expr '+' expr | INT |
phrase : WORD+ ;

FIELD : [a-z][a-z] ;
WORD : [a-zA-Z_0-9_]+ ;
WS : [ \t]+ -> skip ;*/
------------
parrt commented 9 years ago

I can't seem to reproduce this error with that grammar. The issue is that a reference to an undefined rule leaves an empty ATNFactory.Handle for rule element in alternative of ATNBuilder.g:

alternative returns [ATNFactory.Handle p] :
   ...
   ^(ALT elementOptions? (e=element {els.add($e.p);})+) {$p = factory.alt(els);}

The call to alt eventually reaches the following line in elemList:

else tr.target = els.get(i+1).left;

The els.get(i+1) is likely returning null which causes the problem.

This is almost certainly a problem with ANTLR itself because both paths lead to the same point in Tool.processNonCombinedGrammar() that should be checking for syntactic and semantic errors before creating an ATN.

parrt commented 9 years ago

Was using latest HEAD not 1.6. That grammar with 1.6 gives an error. I changed fieldnme to fieldname or was it fielddfname and saved then "test rule term".

field     : {!isDateField()}? string '.' fieldname ;
null
java.lang.NullPointerException
    at org.antlr.intellij.plugin.preview.PreviewPanel.ensureStartRuleExists(PreviewPanel.java:145)
    at org.antlr.intellij.plugin.preview.PreviewPanel.grammarFileSaved(PreviewPanel.java:126)
    at org.antlr.intellij.plugin.ANTLRv4PluginController.grammarFileSavedEvent(ANTLRv4PluginController.java:262)
    at org.antlr.intellij.plugin.ANTLRv4PluginController$MyVirtualFileAdapter.contentsChanged(ANTLRv4PluginController.java:526)
    at sun.reflect.GeneratedMethodAccessor71.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.util.EventDispatcher.dispatch(EventDispatcher.java:88)
    at com.intellij.util.EventDispatcher.access$100(EventDispatcher.java:34)
    at com.intellij.util.EventDispatcher$1.invoke(EventDispatcher.java:68)
    at com.sun.proxy.$Proxy17.contentsChanged(Unknown Source)
    at com.intellij.openapi.vfs.impl.BulkVirtualFileListenerAdapter.fireAfter(BulkVirtualFileListenerAdapter.java:65)
    at com.intellij.openapi.vfs.impl.BulkVirtualFileListenerAdapter.after(BulkVirtualFileListenerAdapter.java:56)
    at sun.reflect.GeneratedMethodAccessor69.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.util.messages.impl.MessageBusConnectionImpl.deliverMessage(MessageBusConnectionImpl.java:114)
    at com.intellij.util.messages.impl.MessageBusImpl.doPumpMessages(MessageBusImpl.java:315)
    at com.intellij.util.messages.impl.MessageBusImpl.pumpMessages(MessageBusImpl.java:302)
    at com.intellij.util.messages.impl.MessageBusImpl.sendMessage(MessageBusImpl.java:287)
    at com.intellij.util.messages.impl.MessageBusImpl.access$200(MessageBusImpl.java:41)
    at com.intellij.util.messages.impl.MessageBusImpl$2.invoke(MessageBusImpl.java:177)
    at com.sun.proxy.$Proxy18.after(Unknown Source)
    at com.intellij.openapi.vfs.newvfs.persistent.PersistentFSImpl$5.close(PersistentFSImpl.java:649)
    at com.intellij.openapi.fileEditor.impl.LoadTextUtil.write(LoadTextUtil.java:259)
    at com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl$4.run(FileDocumentManagerImpl.java:421)
    at com.intellij.pom.core.impl.PomModelImpl.guardPsiModificationsIn(PomModelImpl.java:354)
    at com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl.a(FileDocumentManagerImpl.java:408)
    at com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl.a(FileDocumentManagerImpl.java:382)
    at com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl.saveAllDocuments(FileDocumentManagerImpl.java:303)
    at com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl.saveAllDocuments(FileDocumentManagerImpl.java:282)
    at com.intellij.openapi.application.impl.ApplicationImpl.saveAll(ApplicationImpl.java:1449)
    at com.intellij.ide.actions.SaveAllAction.actionPerformed(SaveAllAction.java:26)
    at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher$3.performAction(IdeKeyEventDispatcher.java:614)
    at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher.processAction(IdeKeyEventDispatcher.java:663)
    at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher.d(IdeKeyEventDispatcher.java:513)
    at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher.dispatchKeyEvent(IdeKeyEventDispatcher.java:211)
    at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:546)
    at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:384)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

which is

            Rule rule = previewState.g.getRule(previewState.startRuleName);
parrt commented 9 years ago

I think it has to do with the fact that the interp/preview seems to work even with bad rule ref:

field     : {!isDateField()}? string '.' fieldnme ;

Yep, won't preview if I load with fielnme misspelled but if i fix and test then misspell it still works. Could be source of issue. Stuff is out of sync with cached ATN.

parrt commented 9 years ago

1.7 seems to fix this (could be fix in antlr 4.5.1).