{"action":"created","issue":{"url":"https://api.github.com/repos/antlr/antlr4/issues/1545","repository_url":"https://api.github.com/repos/antlr/antlr4","labels_url":"https://api.github.com/repos/antlr/antlr4/issues/1545/labels{/name}","comments_url":"https://api.github.com/repos/antlr/antlr4/issues/1545/comments","events_url":"https://api.github.com/repos/antlr/antlr4/issues/1545/events","html_url":"https://github.com/antlr/antlr4/issues/1545","id":197381970,"number":1545,"title":"Parentheses without quantifier in parser rule lead to syntax error on non-root rule parsing","user":{"login":"rslemos","id":954487,"avatar_url":"https://avatars.githubusercontent.com/u/954487?v=3","gravatar_id":"","url":"https://api.github.com/users/rslemos","html_url":"https://github.com/rslemos","followers_url":"https://api.github.com/users/rslemos/followers","following_url":"https://api.github.com/users/rslemos/following{/other_user}","gists_url":"https://api.github.com/users/rslemos/gists{/gist_id}","starred_url":"https://api.github.com/users/rslemos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rslemos/subscriptions","organizations_url":"https://api.github.com/users/rslemos/orgs","repos_url":"https://api.github.com/users/rslemos/repos","events_url":"https://api.github.com/users/rslemos/events{/privacy}","received_events_url":"https://api.github.com/users/rslemos/received_events","type":"User","site_admin":false},"labels":[{"id":227775,"url":"https://api.github.com/repos/antlr/antlr4/labels/grammars","name":"grammars","color":"ededed","default":false},{"id":227766,"url":"https://api.github.com/repos/antlr/antlr4/labels/parsers","name":"parsers","color":"ededed","default":false},{"id":237266,"url":"https://api.github.com/repos/antlr/antlr4/labels/type:bug","name":"type:bug","color":"e0b5b3","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":4,"created_at":"2016-12-23T14:54:56Z","updated_at":"2016-12-23T20:46:31Z","closed_at":null,"body":"Consider the following grammar:\r\n\r\n```ANTLR\r\ngrammar OpenDeviceStatement;\r\n\r\nprogram : statement+ '.' ;\r\n\r\nstatement : 'OPEN' ( 'DEVICE' (  OPT1  |  OPT2  |  OPT3  )? )+ ;\r\n\r\n//statement : 'OPEN' ( 'DEVICE' ( (OPT1) |  OPT2  |  OPT3  )? )+ ;\r\n//statement : 'OPEN' ( 'DEVICE' (  OPT1  | (OPT2) |  OPT3  )? )+ ;\r\n//statement : 'OPEN' ( 'DEVICE' (  OPT1  |  OPT2  | (OPT3) )? )+ ;\r\n//statement : 'OPEN' ( 'DEVICE' ( (OPT1) | (OPT2) |  OPT3  )? )+ ;\r\n//statement : 'OPEN' ( 'DEVICE' ( (OPT1) |  OPT2  | (OPT3) )? )+ ;\r\n//statement : 'OPEN' ( 'DEVICE' (  OPT1  | (OPT2) | (OPT3) )? )+ ;\r\n//statement : 'OPEN' ( 'DEVICE' ( (OPT1) | (OPT2) | (OPT3) )? )+ ;\r\n\r\nOPT1 : 'OPT-1';\r\nOPT2 : 'OPT-2';\r\nOPT3 : 'OPT-3';\r\n\r\nWS : (' '|'\\n')+ -> channel(HIDDEN);\r\n\r\n```\r\n\r\nWhen parsing the text ```OPEN DEVICE DEVICE``` (directly through ```statement()```, and **not** through ```program()```) everything works fine.\r\n\r\nTrace output:\r\n```\r\nenter   statement, LT(1)=OPEN\r\nconsume [@0,0:3='OPEN',<2>,1:0] rule statement\r\nconsume [@2,5:10='DEVICE',<3>,1:5] rule statement\r\nconsume [@4,12:17='DEVICE',<3>,1:12] rule statement\r\nexit    statement, LT(1)=<EOF>\r\n```\r\n\r\nTree output:\r\n```\r\n(statement OPEN DEVICE DEVICE)\r\n```\r\n\r\n### Exercise 1\r\n\r\nNow consider substituting any of the alternative ```statement``` definitions (where one or more ```OPTx``` tokens are parenthized).\r\n\r\nTree output is still the same. But now some ```syntaxError()``` get reported on the ```ANTLRErrorListener```. Here the trace along with ```ConsoleErrorListener``` output:\r\n\r\n```\r\nenter   statement, LT(1)=OPEN\r\nconsume [@0,0:3='OPEN',<2>,1:0] rule statement\r\nconsume [@2,5:10='DEVICE',<3>,1:5] rule statement\r\nconsume [@4,12:17='DEVICE',<3>,1:12] rule statement\r\nline 1:18 no viable alternative at input '<EOF>'\r\nexit    statement, LT(1)=<EOF>\r\n```\r\n\r\nMaybe ANTLR4 is expecting either: any ```OPTx``` (an optional argument to the previous ```DEVICE```), another ```DEVICE```, ```OPEN``` (for a new ```statement```) or ```.``` (period, to close the ```program```). I understand that ```<EOF>``` is not to be expected if we were to parse the text from the root rule ```program``` (here I just assume that ANTLR4 breaks its promise to be able to parse from any rule, giving no rule the special quality of being *the root rule* or *the main rule*).\r\n\r\n### Exercise 2 (on top of exercise 1)\r\n\r\nGoing one step further, lets then parse the text ```OPEN DEVICE DEVICE.``` (notice the period). Again our parsing starts at ```statement``` rule.\r\n\r\nWhat trace do we get?\r\n\r\n```\r\nenter   statement, LT(1)=OPEN\r\nconsume [@0,0:3='OPEN',<2>,1:0] rule statement\r\nconsume [@2,5:10='DEVICE',<3>,1:5] rule statement\r\nconsume [@4,12:17='DEVICE',<3>,1:12] rule statement\r\nline 1:18 extraneous input '.' expecting {<EOF>, 'DEVICE', 'OPT-1', 'OPT-2', 'OPT-3'}\r\nline 1:19 no viable alternative at input '<EOF>'\r\nexit    statement, LT(1)=<EOF>\r\n```\r\n\r\nWeirdly it **is** expecting ```<EOF>``` (and not ```OPEN``` nor ```.``` because they are outside ```statement``` rule).\r\n\r\nThe output tree wrongly incorporates the ```.```: \r\n```\r\n(statement OPEN DEVICE DEVICE .)\r\n```\r\n(well, at least I expected it to stop at the second ```DEVICE```, leaving the ```.``` unparsed)\r\n\r\n--------------------------------------------------------------------------------\r\nI think there are 3 bugs here:\r\n1. the superfluous parentheses around ```OPTx``` should have no effect in the generated parser;\r\n2. the parsing through the non-root rule ```statement``` should not see the ```<EOF>``` as unexpected (after ```DEVICE``` or any ```OPTx``` token);\r\n3. the parsing through the non-root rule ```statement``` should not consume the ```.``` token (not sure about this one; this may only apply to lexers, not to parsers).\r\n\r\nWhat do you think?"},"comment":{"url":"https://api.github.com/repos/antlr/antlr4/issues/comments/269043835","html_url":"https://github.com/antlr/antlr4/issues/1545#issuecomment-269043835","issue_url":"https://api.github.com/repos/antlr/antlr4/issues/1545","id":269043835,"user":{"login":"sharwell","id":1408396,"avatar_url":"https://avatars.githubusercontent.com/u/1408396?v=3","gravatar_id":"","url":"https://api.github.com/users/sharwell","html_url":"https://github.com/sharwell","followers_url":"https://api.github.com/users/sharwell/followers","following_url":"https://api.github.com/users/sharwell/following{/other_user}","gists_url":"https://api.github.com/users/sharwell/gists{/gist_id}","starred_url":"https://api.github.com/users/sharwell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sharwell/subscriptions","organizations_url":"https://api.github.com/users/sharwell/orgs","repos_url":"https://api.github.com/users/sharwell/repos","events_url":"https://api.github.com/users/sharwell/events{/privacy}","received_events_url":"https://api.github.com/users/sharwell/received_events","type":"User","site_admin":false},"created_at":"2016-12-23T20:46:31Z","updated_at":"2016-12-23T20:46:31Z","body":"😮 ?"}}
{"actor":{"display_login":"sharwell"}}