package org.xmlsh.sh.grammar; import java.util.ArrayDeque; import java.util.Deque; import org.xmlsh.sh.core.DelimWord; import org.xmlsh.sh.core.JoinedWordList; import org.xmlsh.sh.core.SourceLocation; import org.xmlsh.sh.core.StringWord; import org.xmlsh.sh.core.Word; import org.xmlsh.sh.grammar.ParserState.StateEnum; import org.xmlsh.sh.shell.Shell; class ParserContext { private Deque<ParserState> mStateStack = new ArrayDeque<ParserState>(); private String mSource ; private SourceLocation mParentLocation ; private ShellParser mParser; private Shell mShell; public Shell getShell() { return mShell; } ParserContext( Shell shell,ShellParser parser , String source ){ mParser = parser ; mShell = shell ; setSource(source) ; mStateStack.push( ParserState.instanceOf(StateEnum.START) ); } public SourceLocation getLocation(Token t) { SourceLocation loc = new SourceLocation(getSource(), t == null ? mParser.token : t); if( mParentLocation != null ) loc.refineLocation( mParentLocation ); return loc ; } public String getSource() { return mSource; } public void setSource(String source) { mSource = source; } public SourceLocation setParentLocation( SourceLocation loc ) { SourceLocation r = mParentLocation ; mParentLocation = loc ; return r ; } // Create a string word or string list public Word newJoinedWord( Token t , Word next ) { if( isDelim( t ) ) return newJoinedWord( new DelimWord( t) , next ); else return newJoinedWord( new StringWord( t) , next ); } // Create a string word or string list public Word newJoinedWord( Token t ) { return isDelim( t ) ? new DelimWord( t) : new StringWord( t); } public Word newJoinedWord( Word w , Word next ){ if( next == null ) return w ; JoinedWordList l = new JoinedWordList(w.getFirstToken()); // adds will flatten out any child joined word lists l.add(w ); l.add(next); return l; } public boolean isJoinable( Token t ) { return t.specialToken == null && ! isDelim( t ) ; } public boolean isJoinable( Word w ) { return w.isJoinable() ; } public boolean isDelim( Token t ) { assert( ! mStateStack.isEmpty() ); return mStateStack.peek().isDelim(t); } public void pushState( ParserState state ) { mStateStack.push(state); } public void popState ( ) { assert( ! mStateStack.isEmpty() ); mStateStack.pop(); assert( ! mStateStack.isEmpty() ); if( mStateStack.isEmpty() ) mStateStack.push( ParserState.instanceOf(StateEnum.START) ); } }