Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.smotricz.morgana6.client.parser;
- import java.util.ArrayList;
- import java.util.List;
- import com.smotricz.morgana6.client.nodes.AndNode;
- import com.smotricz.morgana6.client.nodes.ConstNode;
- import com.smotricz.morgana6.client.nodes.Node;
- import com.smotricz.morgana6.client.nodes.OrNode;
- import com.smotricz.morgana6.client.nodes.ParenNode;
- import com.smotricz.morgana6.client.nodes.SignedNode;
- import com.smotricz.morgana6.client.nodes.VarNode;
- import static com.smotricz.morgana6.client.parser.Token.*;
- public class Parser {
- private List<Token> tokens;
- private int ptr;
- /**
- * Constructor.
- */
- public Parser() {
- this.tokens = new ArrayList<Token>();
- }
- public Node parse(String input, StringBuilder cleaned) throws ParseException {
- String clean = Scanner.scan(input, this.tokens);
- if (cleaned != null) {
- cleaned.setLength(0);
- cleaned.append(clean);
- }
- setPtr(0);
- Node exp = orExp();
- if (exp == null) {
- throw new ParseException("Syntax error", 0);
- }
- if (la(0) != EOD) {
- throw new ParseException("Syntax error", this.ptr);
- }
- return exp;
- }
- /**
- * Look Ahead.
- * @param offset
- * @return the token type of the input token at {@link #ptr} + offset.
- */
- private TT la(int offset) {
- return tokens.get(ptr + offset).type;
- }
- private Token nextToken() {
- return tokens.get(ptr);
- }
- private void setPtr(int position) {
- this.ptr = position;
- }
- private int getPtr() {
- return this.ptr;
- }
- private void consume() {
- this.ptr++;
- }
- // and-exp (OR and-exp)*
- private Node orExp() {
- Node a1 = andExp();
- if (a1 == null) return null;
- if (la(0) != OR) return a1;
- consume();
- Node a2 = andExp();
- if (a2 == null) return a1;
- ArrayList<Node> terms = new ArrayList<Node>();
- terms.add(a1);
- terms.add(a2);
- while (la(0) == OR) {
- consume();
- Node aN = andExp();
- if (aN == null) break;
- terms.add(aN);
- }
- return new OrNode(terms);
- }
- // signed-exp ([AND] signed-exp)*
- private Node andExp() {
- Node s1 = signed();
- if (s1 == null) return null;
- if (la(0) == AND) {
- consume();
- }
- Node s2 = signed();
- if (s2 == null) return s1;
- ArrayList<Node> terms = new ArrayList<Node>();
- terms.add(s1);
- terms.add(s2);
- while (true) {
- if (la(0) == AND) {
- consume();
- }
- Node sN = signed();
- if (sN == null) break;
- terms.add(sN);
- }
- return new AndNode(terms);
- }
- // NOT scalar
- // | scalar [PRIME]
- private Node signed() {
- boolean negative = (la(0) == NOT);
- if (negative) {
- consume();
- }
- Node scx = scalar();
- if (scx == null) return null;
- if (negative) return ((SignedNode) scx).negate();
- if (la(0) == PRIME) {
- consume();
- return ((SignedNode) scx).negate();
- } else {
- return scx;
- }
- }
- // VAR
- // | CONSTANT
- // | LP or-exp RP
- private Node scalar() {
- int savPtr = getPtr();
- Node scx;
- if (la(0) == VAR) {
- scx = VarNode.forName(String.valueOf(nextToken().text));
- consume();
- return scx;
- }
- if (la(0) == CONST) {
- scx = ConstNode.forBoolean(nextToken().text == '1');
- consume();
- return scx;
- }
- if (la(0) == LP) {
- consume();
- scx = orExp();
- if (scx == null || la(0) != RP) {
- setPtr(savPtr);
- return null;
- }
- consume();
- return ParenNode.forNested(scx);
- }
- return null;
- }
- }
Add Comment
Please, Sign In to add comment