package org.develnext.jphp.core.syntax.generators.manually; import org.develnext.jphp.core.tokenizer.token.ColonToken; import org.develnext.jphp.core.tokenizer.token.SemicolonToken; import org.develnext.jphp.core.tokenizer.token.Token; import org.develnext.jphp.core.tokenizer.TokenMeta; import org.develnext.jphp.core.tokenizer.token.expr.BraceExprToken; import org.develnext.jphp.core.tokenizer.token.expr.value.YieldExprToken; import org.develnext.jphp.core.tokenizer.token.stmt.BodyStmtToken; import org.develnext.jphp.core.tokenizer.token.stmt.ExprStmtToken; import org.develnext.jphp.core.syntax.SyntaxAnalyzer; import org.develnext.jphp.core.syntax.generators.ExprGenerator; import org.develnext.jphp.core.syntax.generators.Generator; import java.util.ArrayList; import java.util.List; import java.util.ListIterator; public class BodyGenerator extends Generator<BodyStmtToken> { public BodyGenerator(SyntaxAnalyzer analyzer) { super(analyzer); } public BodyStmtToken getToken(Token current, ListIterator<Token> iterator, Class<? extends Token>... endTokens) { return getToken(current, iterator, false, endTokens); } @SuppressWarnings("unchecked") public BodyStmtToken getToken(Token current, ListIterator<Token> iterator, boolean absolute, Class<? extends Token>... endTokens) { return getToken(current, iterator, absolute, true, endTokens); } @SuppressWarnings("unchecked") public BodyStmtToken getToken(Token current, ListIterator<Token> iterator, boolean absolute, boolean returnNull, Class<? extends Token>... endTokens) { boolean alternativeSyntax = false; List<ExprStmtToken> instructions = new ArrayList<ExprStmtToken>(); if (isOpenedBrace(current, BraceExprToken.Kind.BLOCK) /*|| current instanceof SemicolonToken*/){ //if (!returnNull) returnNull = false; while ((current = nextToken(iterator)) != null){ ExprStmtToken expr = analyzer.generator(ExprGenerator.class).getToken( current, iterator, BraceExprToken.class ); if (expr == null){ break; } instructions.add(expr); } } else if (current instanceof ColonToken || (absolute && endTokens != null)){ if (endTokens == null) unexpectedToken(current); if (!(current instanceof ColonToken)) iterator.previous(); else alternativeSyntax = true; while (iterator.hasNext()){ current = nextToken(iterator); ExprStmtToken expr = analyzer.generator(ExprGenerator.class) .getToken(current, iterator, endTokens); if (expr == null) { iterator.previous(); break; } else if (expr.getTokens().size() == 1 && expr.getTokens().get(0) instanceof SemicolonToken){ // nop break; } else { instructions.add(expr); } } } else { ExprStmtToken expr = analyzer.generator(ExprGenerator.class).getToken(current, iterator); if (expr != null) { if (expr.getTokens().size() == 1 && expr.getTokens().get(0) instanceof SemicolonToken) { // nop } else { instructions.add(expr); } } } if (instructions.isEmpty() && returnNull) return null; BodyStmtToken result = new BodyStmtToken(TokenMeta.of(instructions)); result.setInstructions(instructions); result.setAlternativeSyntax(alternativeSyntax); return result; } @Override @SuppressWarnings("unchecked") public BodyStmtToken getToken(Token current, ListIterator<Token> iterator) { return getToken(current, iterator, (Class<? extends Token>[])null); } @Override public boolean isAutomatic() { return false; } }