package qls.ast; import org.antlr.v4.runtime.misc.NotNull; import org.antlr.v4.runtime.tree.TerminalNode; import ql.ast.AstNode; import ql.ast.type.Type; import ql.ast.type.TypeFactory; import ql.util.StringHelper; import qls.ast.rule.*; import qls.ast.rule.widget.*; import qls.ast.statement.*; import qls.gen.QLSBaseVisitor; import qls.gen.QLSParser; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; /** * Created by bore on 02/03/15. */ public class AstBuilder extends QLSBaseVisitor<AstNode> { @Override public AstNode visitStylesheet(@NotNull QLSParser.StylesheetContext context) { List<Page> definitions = new ArrayList<>(); for (QLSParser.PageContext pageContext : context.page()) { Page s = (Page)this.visit(pageContext); definitions.add(s); } int lineNumber = context.Identifier().getSymbol().getLine(); return new Stylesheet(definitions, lineNumber); } @Override public AstNode visitPage(@NotNull QLSParser.PageContext context) { List<Statement> definitions = new ArrayList<Statement>(); for (QLSParser.StatementContext statementContext : context.statement()) { Statement s = (Statement)this.visit(statementContext); definitions.add(s); } TerminalNode n = context.String(); String id = StringHelper.unescapeString(n.getText()); int lineNumber = context.String().getSymbol().getLine(); return new Page(id, definitions, lineNumber); } @Override public AstNode visitStatement(@NotNull QLSParser.StatementContext context) { if (context.section() != null) { return visitSection(context.section()); } if (context.question() != null) { return visitQuestion(context.question()); } if (context.questionWithRules() != null) { return visitQuestionWithRules(context.questionWithRules()); } if (context.defaultStmt() != null) { return visitDefaultStmt(context.defaultStmt()); } throw new IllegalStateException("Unsupported statement"); } @Override public AstNode visitSection(@NotNull QLSParser.SectionContext context) { List<Statement> definitions = new ArrayList<Statement>(); for (QLSParser.StatementContext statementContext : context.statement()) { Statement s = (Statement)this.visit(statementContext); definitions.add(s); } String id = StringHelper.unescapeString(context.String().getText()); int lineNumber = context.String().getSymbol().getLine(); return new Section(id, definitions, lineNumber); } @Override public AstNode visitQuestion(@NotNull QLSParser.QuestionContext context) { String id = context.Identifier().getText(); int lineNumber = context.Identifier().getSymbol().getLine(); return new Question(id, lineNumber); } @Override public AstNode visitQuestionWithRules(@NotNull QLSParser.QuestionWithRulesContext context) { String id = context.Identifier().getText(); int lineNumber = context.Identifier().getSymbol().getLine(); List<Rule> rules = new ArrayList<>(); for (QLSParser.StylesheetRuleContext ruleContext : context.stylesheetRule()) { Rule s = (Rule)this.visit(ruleContext); rules.add(s); } return new QuestionWithRules(id, lineNumber, new Rules(rules)); } @Override public AstNode visitDefaultStmt(@NotNull QLSParser.DefaultStmtContext context) { List<Rule> rules = new ArrayList<Rule>(); for (QLSParser.StylesheetRuleContext ruleContext : context.stylesheetRule()) { Rule s = (Rule)this.visit(ruleContext); rules.add(s); } Type type = TypeFactory.createType(context.QuestionType().getText()); int lineNumber = context.QuestionType().getSymbol().getLine(); return new DefaultStat(type, new Rules(rules), lineNumber); } @Override public AstNode visitStylesheetRule(@NotNull QLSParser.StylesheetRuleContext context) { int lineNumber = context.label.getLine(); String label = context.label.getText(); if (label.equals("width")) { int value = Integer.parseInt(context.Integer().getText()); return new Width(value, lineNumber); } if (label.equals("backcolor")) { ColorValue c = new ColorValue(context.Color().getText()); return new BackColor(c, lineNumber); } if (label.equals("forecolor")) { ColorValue c = new ColorValue(context.Color().getText()); return new ForeColor(c, lineNumber); } if (label.equals("font")) { return new Font(StringHelper.unescapeString(context.String().getText()), lineNumber); } if (label.equals("fontsize")) { int value = Integer.parseInt(context.Integer().getText()); return new FontSize(value, lineNumber); } if (label.equals("widget")) { WidgetValue value = (WidgetValue)this.visitWidgetValue(context.widgetValue()); return new Widget(value, lineNumber); } throw new IllegalStateException("Unsupported stylesheet rule"); } @Override public AstNode visitWidgetValue(QLSParser.WidgetValueContext context) { String label = context.wlabel.getText(); if (label.equals("slider")) { if (context.decMin != null) { BigDecimal min = new BigDecimal(context.decMin.getText()); BigDecimal max = new BigDecimal(context.decMax.getText()); BigDecimal step = new BigDecimal(context.decStep.getText()); return new DecSlider(min, max, step); } Integer min = Integer.parseInt(context.intMin.getText()); Integer max = Integer.parseInt(context.intMax.getText()); Integer step = Integer.parseInt(context.intStep.getText()); return new IntSlider(min, max, step); } if (label.equals("radio")) { String yes = StringHelper.unescapeString(context.yesText.getText()); String no = StringHelper.unescapeString(context.noText.getText()); return new Radio(yes, no); } if (label.equals("dropdown")) { String yes = StringHelper.unescapeString(context.yesText.getText()); String no = StringHelper.unescapeString(context.noText.getText()); return new Dropdown(yes, no); } if (label.equals("checkbox")) { return new Checkbox(); } if (label.equals("textbox")) { return new Textbox(); } throw new IllegalStateException("Unsupported widget value"); } }