/******************************************************************************* | |
* Copyright (c) 2016 KPIT Technologies. | |
* | |
* All rights reserved. This program and the accompanying materials | |
* are made available under the terms of the Eclipse Public License v2.0 | |
* which accompanies this distribution, and is available at | |
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html | |
* | |
* SPDX-License-Identifier: EPL-2.0 | |
* | |
* Contributors: | |
* Jan Mauersberger- initial API and implementation | |
* Sascha Baumgart- initial API and implementation | |
*******************************************************************************/ | |
package org.eclipse.opencert.userguidance.labelparser; | |
import java.util.ArrayList; | |
import java.util.List; | |
import org.antlr.v4.runtime.ANTLRInputStream; | |
import org.antlr.v4.runtime.CommonTokenStream; | |
import org.antlr.v4.runtime.RecognitionException; | |
import org.antlr.v4.runtime.tree.ParseTree; | |
import org.antlr.v4.runtime.tree.TerminalNode; | |
import org.eclipse.opencert.userguidance.labelparser.generated.LabelLexer; | |
import org.eclipse.opencert.userguidance.labelparser.generated.LabelParser; | |
import org.eclipse.opencert.userguidance.labelparser.generated.LabelParser.ItemContext; | |
import org.eclipse.opencert.userguidance.labelparser.generated.LabelParser.ItembodyContext; | |
import org.eclipse.opencert.userguidance.labelparser.generated.LabelParser.TextContext; | |
import org.eclipse.opencert.userguidance.labelparser.tokens.HighlightItem; | |
import org.eclipse.opencert.userguidance.labelparser.tokens.HighlightItem.ItemBodyType; | |
import org.eclipse.opencert.userguidance.labelparser.tokens.HighlightItem.ItemHeaderType; | |
import org.eclipse.opencert.userguidance.labelparser.tokens.TextToken; | |
import org.eclipse.opencert.userguidance.labelparser.tokens.Token; | |
public class LabelParserUtil { | |
public static List<Token> parse(String input) { | |
List<Token> result = new ArrayList<Token>(); | |
if (input.length() == 0) { | |
return result; | |
} | |
ANTLRInputStream stream = new ANTLRInputStream(input); | |
LabelLexer lexer = new LabelLexer(stream); | |
CommonTokenStream tokens = new CommonTokenStream(lexer); | |
LabelParser parser = new LabelParser(tokens); | |
TextContext tree = null; | |
try { | |
tree = parser.text(); | |
} catch (RecognitionException e) { | |
return result; | |
} | |
result = process(tree); | |
return result; | |
} | |
private static List<Token> process(TextContext tree) { | |
List<Token> result = new ArrayList<Token>(); | |
// The total length of all previously processed tokens | |
int position = 0; | |
for (int i = 0; i < tree.getChildCount(); i++) { | |
ParseTree child = tree.getChild(i); | |
if (child instanceof ItemContext) { | |
ItemContext itemContext = (ItemContext) child; | |
if (itemContext.getChildCount() != 3) { | |
throw new IllegalArgumentException( | |
"Parser error: The token '" + itemContext.getText() | |
+ "' should have 3 child tokens."); | |
} | |
// Need to populate the following variables | |
String rawItemString = null; | |
String body = null; | |
String representation = null; | |
ItemHeaderType headerType = null; | |
ItemBodyType bodyType = null; | |
int startIndex = -1; | |
// Get rawItemString and startIndex | |
rawItemString = itemContext.getText(); | |
startIndex = itemContext.getStart().getStartIndex(); | |
// Get headerType | |
TerminalNode headerTerminalNode = (TerminalNode) itemContext | |
.getChild(0); | |
String headerString = headerTerminalNode.getText(); | |
headerType = ItemHeaderType.parse(headerString); | |
// Get bodyType | |
ItembodyContext bodyNode = (ItembodyContext) itemContext | |
.getChild(2); | |
int bodyChildCount = bodyNode.getChildCount(); | |
if (bodyChildCount == 0) { | |
continue; | |
} | |
if (bodyNode.getChild(0).getText().equals("\"") | |
&& bodyNode.getChild(bodyChildCount - 1).getText() | |
.equals("\"")) { | |
bodyType = ItemBodyType.doublequoted; | |
} else if (bodyNode.getChild(0).getText().equals("'") | |
&& bodyNode.getChild(bodyChildCount - 1).getText() | |
.equals("'")) { | |
bodyType = ItemBodyType.singlequoted; | |
} else { | |
bodyType = ItemBodyType.unquoted; | |
} | |
// Get body and representation | |
StringBuilder bodyBuilder = new StringBuilder(); | |
int firstString = bodyType == ItemBodyType.unquoted ? 0 : 1; | |
int lastString = bodyType == ItemBodyType.unquoted ? bodyNode | |
.getChildCount() : bodyNode.getChildCount() - 1; | |
for (int j = firstString; j < lastString; j++) { | |
// Avoid appending parsing error messages | |
if (!bodyNode.getChild(j).getText().startsWith("<missing ")) { | |
bodyBuilder.append(bodyNode.getChild(j).getText()); | |
} | |
} | |
String bodyRawText = bodyBuilder.toString(); | |
if (bodyRawText.contains("|")) { | |
int pipeIndex = bodyRawText.indexOf('|'); | |
body = bodyRawText.substring(0, pipeIndex); | |
representation = bodyRawText.substring(pipeIndex + 1); | |
} else { | |
body = bodyRawText; | |
representation = bodyRawText; | |
} | |
HighlightItem item = new HighlightItem(rawItemString, body, | |
representation, headerType, bodyType, startIndex); | |
result.add(item); | |
position += item.getStartIndex() + item.getRawString().length(); | |
} | |
if (child instanceof TerminalNode) { | |
TerminalNode terminalNode = (TerminalNode) child; | |
String text = terminalNode.getText(); | |
TextToken textToken = new TextToken(text, position); | |
result.add(textToken); | |
position += textToken.getRepresentation().length(); | |
} | |
} | |
return result; | |
} | |
} |