package nl.uva.sc.encoders.qls.parser; import java.util.ArrayList; import java.util.List; import nl.uva.sc.encoders.ql.ast.TextLocation; import nl.uva.sc.encoders.qls.EncodersQLSBaseVisitor; import nl.uva.sc.encoders.qls.EncodersQLSParser.CheckBoxContext; import nl.uva.sc.encoders.qls.EncodersQLSParser.ColorContext; import nl.uva.sc.encoders.qls.EncodersQLSParser.DefaultStyleContext; import nl.uva.sc.encoders.qls.EncodersQLSParser.FontContext; import nl.uva.sc.encoders.qls.EncodersQLSParser.FontSizeContext; import nl.uva.sc.encoders.qls.EncodersQLSParser.NumberFieldContext; import nl.uva.sc.encoders.qls.EncodersQLSParser.PageContext; import nl.uva.sc.encoders.qls.EncodersQLSParser.QuestionContext; import nl.uva.sc.encoders.qls.EncodersQLSParser.RadioContext; import nl.uva.sc.encoders.qls.EncodersQLSParser.SectionContext; import nl.uva.sc.encoders.qls.EncodersQLSParser.StylePropertyContext; import nl.uva.sc.encoders.qls.EncodersQLSParser.StylesheetContext; import nl.uva.sc.encoders.qls.EncodersQLSParser.TextFieldContext; import nl.uva.sc.encoders.qls.EncodersQLSParser.WidgetContext; import nl.uva.sc.encoders.qls.EncodersQLSParser.WidthContext; import nl.uva.sc.encoders.qls.ast.AstNode; import nl.uva.sc.encoders.qls.ast.DefaultStyle; import nl.uva.sc.encoders.qls.ast.Page; import nl.uva.sc.encoders.qls.ast.Question; import nl.uva.sc.encoders.qls.ast.Section; import nl.uva.sc.encoders.qls.ast.Stylesheet; import nl.uva.sc.encoders.qls.ast.property.Color; import nl.uva.sc.encoders.qls.ast.property.DefaultStyleProperty; import nl.uva.sc.encoders.qls.ast.property.Font; import nl.uva.sc.encoders.qls.ast.property.FontSize; import nl.uva.sc.encoders.qls.ast.property.Width; import nl.uva.sc.encoders.qls.ast.widget.CheckBox; import nl.uva.sc.encoders.qls.ast.widget.NumberField; import nl.uva.sc.encoders.qls.ast.widget.Radio; import nl.uva.sc.encoders.qls.ast.widget.TextField; import nl.uva.sc.encoders.qls.ast.widget.Widget; import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.tree.TerminalNode; public class ParseTreeToAbstractSyntaxTree extends EncodersQLSBaseVisitor<AstNode> { @Override public Stylesheet visitStylesheet(StylesheetContext ctx) { TextLocation textLocation = getTextLocation(ctx); String name = ctx.name.getText(); List<Page> pages = new ArrayList<>(); for (PageContext pageContext : ctx.page()) { Page page = (Page) pageContext.accept(this); pages.add(page); } return new Stylesheet(textLocation, name, pages); } @Override public Page visitPage(PageContext ctx) { TextLocation textLocation = getTextLocation(ctx); String name = ctx.name.getText(); List<Section> sections = new ArrayList<>(); List<DefaultStyle> pageDefaultStyles = new ArrayList<>(); for (SectionContext sectionContext : ctx.section()) { Section section = (Section) sectionContext.accept(this); sections.add(section); } for (DefaultStyleContext defaultStyleContext : ctx.defaultStyle()) { DefaultStyle defaultStyle = (DefaultStyle) defaultStyleContext.accept(this); pageDefaultStyles.add(defaultStyle); } return new Page(textLocation, name, sections, pageDefaultStyles); } @Override public Section visitSection(SectionContext ctx) { TextLocation textLocation = getTextLocation(ctx); String name = ctx.name.getText(); List<Question> questions = new ArrayList<>(); List<Section> subSections = new ArrayList<>(); List<DefaultStyle> sectionDefaultStyles = new ArrayList<>(); for (QuestionContext questionContext : ctx.question()) { Question question = (Question) questionContext.accept(this); questions.add(question); } for (SectionContext subSectionContext : ctx.section()) { Section subSection = visitSection(subSectionContext); subSections.add(subSection); } for (DefaultStyleContext defaultStyleContext : ctx.defaultStyle()) { DefaultStyle defaultStyle = (DefaultStyle) defaultStyleContext.accept(this); sectionDefaultStyles.add(defaultStyle); } return new Section(textLocation, name, questions, subSections, sectionDefaultStyles); } @Override public Question visitQuestion(QuestionContext ctx) { TextLocation textLocation = getTextLocation(ctx); String name = ctx.name.getText(); Widget widget = null; return new Question(textLocation, name, widget); } @Override public DefaultStyle visitDefaultStyle(DefaultStyleContext ctx) { TextLocation textLocation = getTextLocation(ctx); String dataType = ctx.DATATYPE().getText(); WidgetContext widgetContext = ctx.widget(); Widget defaultStyleWidget = (Widget) widgetContext.accept(this); DefaultStyle defaultStyle = new DefaultStyle(textLocation, dataType, defaultStyleWidget); for (StylePropertyContext stylePropertyContext : ctx.styleProperty()) { DefaultStyleProperty defaultStyleProperty = (DefaultStyleProperty) stylePropertyContext.accept(this); defaultStyle.addDefaultStyleProperty(defaultStyleProperty); } return defaultStyle; } @Override public Color visitColor(ColorContext ctx) { TextLocation textLocation = getTextLocation(ctx); String value = ctx.value.getText(); return new Color(textLocation, value); } @Override public Font visitFont(FontContext ctx) { TextLocation textLocation = getTextLocation(ctx); String value = ctx.value.getText(); return new Font(textLocation, value); } @Override public FontSize visitFontSize(FontSizeContext ctx) { TextLocation textLocation = getTextLocation(ctx); Integer value = Integer.valueOf(ctx.value.getText()); return new FontSize(textLocation, value); } @Override public Width visitWidth(WidthContext ctx) { TextLocation textLocation = getTextLocation(ctx); Integer value = Integer.valueOf(ctx.value.getText()); return new Width(textLocation, value); } @Override public CheckBox visitCheckBox(CheckBoxContext ctx) { TextLocation textLocation = getTextLocation(ctx); return new CheckBox(textLocation); } @Override public Radio visitRadio(RadioContext ctx) { TextLocation textLocation = getTextLocation(ctx); List<TerminalNode> stringliteral = ctx.STRINGLITERAL(); List<String> options = new ArrayList<>(); for (TerminalNode terminalNode : stringliteral) { options.add(terminalNode.getText()); } return new Radio(textLocation, options); } @Override public NumberField visitNumberField(NumberFieldContext ctx) { TextLocation textLocation = getTextLocation(ctx); return new NumberField(textLocation); } @Override public TextField visitTextField(TextFieldContext ctx) { TextLocation textLocation = getTextLocation(ctx); return new TextField(textLocation); } private TextLocation getTextLocation(ParserRuleContext ctx) { Token start = ctx.getStart(); int line = start.getLine(); int column = start.getCharPositionInLine(); return new TextLocation(line, column); } }