c# - Antlr parser StackOverflowException -
i have following in antlr parser grammar xamarin.ios c# project:
mathtoken : digit #digit | null #null | lessthan #lessthan | greaterthan #greaterthan | anylessthanorequal #lessthanorequal // 30 more options here mathtokenlist : mathtoken mathtokenlist #compoundmathtokens | mathtoken #singlemathtoken ;
this works great list of 10 tokens, 100, or 1000. once list gets long enough, leads stackoverflowexception, generated mathtokenlist recursively calls itself, listener code @ top:
mynamespace.handletoken(mytokenclass parsertoken, list<myothertokenclass> buildinglist) in mynamespace.manualfileparser.cs:58 mynamespace.customstringreaderparselistener.visitdefault(antlr4.runtime.tree.terminalnodeimpl node) in mynamespace.customstringreaderparselistener.cs:228 mynamespace.customstringreaderparselistener.visitterminal(antlr4.runtime.tree.terminalnodeimpl node) in mynamespace.customstringreaderparselistener.cs:94 antlr4.runtime.parser.consume() antlr4.runtime.parser.match(int ttype) antlr.stringreaderparser.mathtoken() antlr.stringreaderparser.mathtokenlist() // lots of calls here . . . seems antlr.stringreaderparser.mathtokenlist() // 1 each token. antlr.stringreaderparser.mathtokenlist() // ( in antlr generated code)
is possible restructure parser grammar avoid kind of problem? or need more involved parser never sees long list of mathtokens?
i put band-aid on problem combining lists of digits before parser sees them. recur other token type.
you cannot entirely avoid problem. each rule invocation function call in generated parser (recursive descent parser principle). if input complex enough hit available stack limit. in (all?) compilers can increase stackspace app, helps extent.
however, @bartkiers suggested can lower invocation count using loops instead of recursions (a principle used in programming). mathtokenlist
rule looks how define list in yacc/bison. in antlr can use loop operators instead, make better read , less resource intensive:
mathtokenlist: mathtoken+;
is way go here. end in loop being executed in mathtokenlist
method (look @ generated parser code, quite enlightening).
Comments
Post a Comment