Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 368966 - [serializer] infinite loop when syntactic transition involves loop
Summary: [serializer] infinite loop when syntactic transition involves loop
Status: CLOSED FIXED
Alias: None
Product: TMF
Classification: Modeling
Component: Xtext (show other bugs)
Version: 2.3.0   Edit
Hardware: PC Mac OS X - Carbon (unsup.)
: P3 normal (vote)
Target Milestone: M7   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-01-18 09:11 EST by Moritz Eysholdt CLA
Modified: 2017-10-31 11:30 EDT (History)
2 users (show)

See Also:
moritz.eysholdt: kepler+


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Moritz Eysholdt CLA 2012-01-18 09:11:22 EST
I assume this can be reproduced with grammars such as

Rule:
	name=ID ('foo'* bar=ID)*;

The infinite loop results in an OutOfMemoryError in 

Thread [main] (Suspended)	
	PdaUtil.traceToWithPruningStack(Pda<S,P>, Iterable<S>, Iterator<P>, Predicate<S>, Predicate<S>) line: 536	
	PdaUtil.shortestStackpruningPathTo(Pda<S,P>, S, Iterator<P>, Predicate<S>, Predicate<S>) line: 457	
	PdaUtil.shortestStackpruningPathTo(Pda<S,P>, Iterator<P>, Predicate<S>) line: 447	
	SyntacticSequencerPDAProvider$SynTransition(SyntacticSequencerPDAProvider$SynNavigable).shortestStackpruningPathTo(Iterator<RuleCall>, Predicate<ISynState>, boolean) line: 338	
	SyntacticSequencerPDAProvider$SynTransition(SyntacticSequencerPDAProvider$SynNavigable).getShortestStackpruningPathToAbsorber(RuleCallStack) line: 225	
	ClassmodelSyntacticSequencer(AbstractSyntacticSequencer).navigateToAbsorber(ISyntacticSequencerPDAProvider$ISynFollowerOwner, INode, INode, RuleCallStack) line: 411	
	ClassmodelSyntacticSequencer(AbstractSyntacticSequencer).navigateToAbsorber(AbstractElement, INode) line: 399	
	ClassmodelSyntacticSequencer(AbstractSyntacticSequencer).finish() line: 341	
	SequenceFeeder.finish() line: 369	
	BacktrackingSemanticSequencer.createSequence(EObject, EObject) line: 426
Comment 1 Moritz Eysholdt CLA 2012-01-19 05:45:01 EST
It turns out this is no real infinite loop, but a exponential high runtime complexity for scenarios like:

Greeting:
  'Hello' foo=ID 
    ("kw1" val1+=ID? | 
     "kw2" val2+=ID? | 
     "kw3" val3+=ID? | 
     "kw4" val4+=ID? | 
     "kw5" val5+=ID? | 
     "kw6" val6+=ID? | 
     "kw7" val7+=ID? | 
     "kw8" val8+=ID?)* 
  '!';

The state machine describing the syntactic transition from "start" to "stop" involves all keywords from this rule, since all assignments are optional. Furthermore, since the parser rule allows the keywords to be in any order, any keyword can be followed by any other keyword.

In this state-machine, PdaUtil.shortestStackpruningPathTo() does a breadth-first search, i.e. the algorithm tries all possibles paths at the same time, by extending each path by one step in every iteration, until one valid path has been found. In this state machine, the amount of paths multiplies by the amount of states in each step.

Proposed fix:
Don't execute the algorithm on the "full" state machine. Instead, create a derived state machine that does not include the edges which by definition can not be part of the shortest path. That are the edges that lead to optional elements or loops.
Comment 2 Sebastian Zarnekow CLA 2012-01-19 05:51:13 EST
Sounds like a good use case for Dijkstra's algorithm for graphs where the cost function could be the minimum number of remaining steps, e.g. 

Greeting:
  'Hello' foo=ID 
    ("kw1" val1+=ID? | 
     "kw2" val2+=ID? | 
    )* 
  '!';

ignoring the val1+=ID after consuming the kw1 would be more expensive than consuming it. Should be straight forward to apply for the given search problem.
Comment 3 Moritz Eysholdt CLA 2013-04-19 09:07:31 EDT
It looks like this has been fixed in the meantime. I've added a test case in 
http://git.eclipse.org/c/tmf/org.eclipse.xtext.git/commit/?id=4df39d675f106570cb668d0c1f865526b40afce7
Comment 4 Eclipse Webmaster CLA 2017-10-31 11:30:36 EDT
Requested via bug 522520.

-M.