Package warthog.parsegen

Source Code of warthog.parsegen.MetaParser

package warthog.parsegen;

import java.io.*;
import java.util.*;

import warthog.cradle.Descent;
import warthog.cradle.JavaClass;

public class MetaParser extends Descent {
  private Generator gen;
  private Map<String, SemanticClass> types = new HashMap<String, SemanticClass>();
  GeneratorData data;
  private JavaClass javaClass;

  public MetaParser(File path) throws IOException {
    super(new FileReader(path));
    javaClass = new JavaClass(path);
    data = new GeneratorData();
    gen = new Generator();
  }
  public void run() throws IOException {
    parseHeader();
    matchSeparator();
    parseGrammar();
    gen.build();
    gen.writeAllCode(javaClass, data);
    javaClass.writeFile();
  }
  private void parseHeader() throws IOException {
    while (true) {
      if (inWhite()||inEOL()) skipLine();
      else if (inAlpha()) {
        String optionName = parseWord("option");
        skipSpace();
        if ("package".equals(optionName)) {
          javaClass.packageName = collectLine().toString();
          matchEOL();
        }
        else if ("import".equals(optionName)) {
          javaClass.preamble.append("import ");
          javaClass.preamble.append(collectWholeLine());
        }
        else if ("abstract".equals(optionName)) {
          javaClass.isAbstract = true;
          matchEOL();
        }
        else if ("final".equals(optionName)) {
          javaClass.isFinal = true;
          matchEOL();
        }
        else if ("public".equals(optionName)) {
          javaClass.isPublic = true;
          matchEOL();
        }
        else if ("type".equals(optionName)) {
          parseTypeDeclaration();
        }
        else if ("left".equals(optionName)) {
          gen.assoc(Assoc.LEFT, parseTokens());
          matchEOL();
        }
        else if ("right".equals(optionName)) {
          gen.assoc(Assoc.RIGHT, parseTokens());
          matchEOL();
        }
        else if ("non".equals(optionName)) {
          gen.assoc(Assoc.NON, parseTokens());
          matchEOL();
        }
        else if ("token".equals(optionName)) {
          for (String s:parseTokens()) {
            gen.sym(s);
          }
          matchEOL();
        }
        else {
          error("option "+optionName+" not understood.");
        }
      }
      else break;
    }
  }
  private void parseTypeDeclaration() throws IOException {
    Collection<String> tokens = parseTokens();
    match(':');
    skipSpace();
    String type=collectLine().toString();
    for (String t:tokens) setType(t,type);
    matchEOL();
  }
  private Collection<String> parseTokens() throws IOException {
    ArrayList<String> tokens = new ArrayList<String>();
    while (inAlpha()) {
      tokens.add(parseWord("token"));
      skipSpace();
    }
    return tokens;
  }
  private void setType(String symName, String javaType) {
    if (!types.containsKey(javaType)) types.put(javaType, new SemanticClass(javaType));
    Sym s = gen.sym(symName);
    // if (s.semanticClass != null) foo ;
    s.semanticClass = types.get(javaType);
  }
  private void matchSeparator() throws IOException {
    match('%');
    match('%');
    matchEOL();
  }
  private void parseGrammar() throws IOException {
    while (!atEOF()) {
      if (is('%')) {
        matchSeparator();
        parsePostamble();
        return;
      } else if (inAlpha()) {
        parseNonterminal();
      } else if (inEOL()) {
        matchEOL();
      }
      else error("Confused");
    }
  }
  String head;
  private void parseNonterminal() throws IOException {
    head = parseWord("nonterminal");
    skipSpace();
    if (maybe(':')) {
      skipSpace();
      String type=collectLine().toString();
      setType(head, type);
    }
    matchEOL();
    while (maybe('\t')) {
      parseRule(head);
    }
  }
  private void parseRule(String head) throws IOException {
    Collection<String> rhs = parseTokens();
    if (rhs.isEmpty() && inEOL()) {
      // If the line is completely whitespace, it doesn't count as a rule.
      matchEOL();
      return;
    }
    Rule rule = gen.rule(head, rhs);
    rule.line = lineNr;
    if (maybe(':')) {
      rule.note = collectWholeLine().toString();
    } else matchEOL();
  }
  private void parsePostamble() throws IOException {
    while(!atEOF()) {
      javaClass.code.append((char)look); read();
    }
  }

}
TOP

Related Classes of warthog.parsegen.MetaParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.