View Javadoc
1   package io.github.magwas.inez.parse;
2   
3   import java.util.ArrayList;
4   import java.util.HashMap;
5   import java.util.List;
6   import java.util.Map;
7   import java.util.function.Function;
8   import java.util.stream.Stream;
9   
10  import org.antlr.v4.runtime.tree.ParseTree;
11  import org.antlr.v4.runtime.tree.TerminalNode;
12  import org.springframework.beans.factory.annotation.Autowired;
13  import org.springframework.stereotype.Service;
14  
15  import io.github.magwas.inez.parser.BridiParser;
16  import io.github.magwas.inez.parser.BridiParser.BridiContext;
17  import io.github.magwas.inez.parser.BridiParser.LiteralContext;
18  import io.github.magwas.inez.parser.BridiParser.ParagraphContext;
19  import io.github.magwas.inez.parser.BridiParser.TextReferenceContext;
20  import io.github.magwas.runtime.LogUtil;
21  
22  @Service
23  public class ParseTextService implements Function<String, Stream<ParserOutput>> {
24  	@Autowired
25  	CreateParserFromTokensService createParserFromTokens;
26  
27  	@Override
28  	public Stream<ParserOutput> apply(final String input) {
29  		LogUtil.debug("input:" + input);
30  		BridiParser parser = createParserFromTokens.apply(input);
31  		ParagraphContext text = parser.paragraph();
32  		return text.children.stream()
33  				.filter(BridiContext.class::isInstance)
34  				.map(x -> compileBridiFromTree((BridiContext) x));
35  	}
36  
37  	private ParserOutput compileBridiFromTree(final BridiContext bridi) {
38  		StringBuilder representation = new StringBuilder();
39  		StringBuilder topBuilder = new StringBuilder();
40  		Map<String, List<String>> references = new HashMap<>();
41  		List<String> kidrefs = new ArrayList<>();
42  		int childIndex = 0;
43  		for (ParseTree kid : bridi.children) {
44  			String text = kid.getText();
45  			if (kid instanceof TerminalNode) {
46  				LogUtil.debug("r:" + text);
47  				if ("{[".equals(text)) representation.append("{");
48  				else if ("]}".equals(text)) representation.append("}");
49  				else representation.append(text);
50  				topBuilder.append(text);
51  			} else if (kid instanceof BridiContext) {
52  				LogUtil.debug("bridi", text, kid.getChildCount());
53  				ParserOutput parsedKid = compileBridiFromTree((BridiContext) kid);
54  				references.putAll(parsedKid.referenceMap());
55  				String kidTop = parsedKid.top();
56  				kidrefs.add(kidTop);
57  				representation.append(childIndex++);
58  				topBuilder.append(kidTop);
59  			} else if (kid instanceof TextReferenceContext) {
60  				LogUtil.debug("ref", text);
61  				representation.append(childIndex++);
62  				topBuilder.append(text);
63  				kidrefs.add(text);
64  			} else if (kid instanceof LiteralContext) {
65  				LogUtil.debug("literal", text, kid.getChildCount());
66  				representation.append(childIndex++);
67  				topBuilder.append(text);
68  				kidrefs.add(text);
69  			} else throw new InternalError("unrecognized tree element:" + kid.getClass());
70  		}
71  		String repr = representation.toString();
72  		String top = topBuilder.toString();
73  		LogUtil.debug("repr:" + representation);
74  		if (!kidrefs.isEmpty()) {
75  			kidrefs.add(0, repr);
76  			references.put(top, kidrefs);
77  		}
78  		ParserOutput ret = new ParserOutput(top, references);
79  		LogUtil.debug("compileBridiFromTree", top, ret);
80  		return ret;
81  	}
82  }