Advertisement
Guest User

Untitled

a guest
Feb 20th, 2014
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
D 5.82 KB | None | 0 0
  1. module fvmc.Compiler.Parser;
  2. import std.stdio, std.file, std.string;
  3.  
  4. // A class encapsulating the parser functionality of fvmc. Use
  5. // this to parse any input into a set of statements.
  6. public class Parser {
  7.     @property bool hasLoadedText() { return this.has_loaded; }
  8.     @property Statement[] statements() { return this.fvmStmts; }
  9.  
  10.     public this(string filepath) {
  11.         this.loadCodeFile(filepath);
  12.         this.parseLoadedCode();
  13.         if (parser_error) return;//throw new ParserException();
  14.     }
  15.  
  16.     // load an FVM code file from a given path.
  17.     private void loadCodeFile(string filepath)
  18.     {
  19.         try {
  20.             if (!exists(filepath))
  21.                 throw new FileException("Could not access file \"" ~ filepath ~ "\":\n\t");
  22.  
  23.             this.fvm_Code = cast(string) read(filepath);
  24.             this.has_loaded = true;
  25.         }
  26.         catch (FileException ex) {
  27.             writeln(ex.msg);
  28.             this.parser_error = true;
  29.         }
  30.     }
  31.  
  32.     private void parseLoadedCode() {
  33.         if (!this.has_loaded) throw new Exception("No code loaded for parsing.");
  34.  
  35.         // The number of statements we've
  36.         // parsed through so far.
  37.         uint stmtCtr = 0;
  38.         // The pieces of one statement
  39.         string currMnemonic, arg0, arg1;
  40.  
  41.         string mnemonicValidChars = "abcdefghijklmnopqrstuvwxyz",
  42.             argValidChars = "0123456789";
  43.         // The current statement piece we're on
  44.         string* currSection = &currMnemonic;
  45.         // The curent set of valid characters.
  46.         string* currValidChars = &mnemonicValidChars;
  47.         // Counter for statement pieces iterated
  48.         // through.
  49.         int stmtPieceCtr = 0;
  50.         // Whether we're currently parsing a
  51.         // statement piece.
  52.         bool onStmtPiece = false,
  53.             newlineCheck = false;
  54.  
  55.         // Pass 1 - Transform into statements
  56.         // Iterate through every character in
  57.         // our loaded code. Statements are separated by
  58.         // line-breaks (\n or \r\n).
  59.         /*
  60.             Statement Grammar:
  61.                 <statement> ::= <mnemonic> | " " <argument> | " " <argument>
  62.                 <mnemonic>  ::= "mov" | "add" | "sub" | "mul" | "div" |
  63.                                 "swap" | "and" | "or" | "xor" | "jmp" |
  64.                                 "ret" | "bshr" | "bshl" | "end" | "not" |
  65.                                 "push" | "pop"
  66.                 <argument>  ::= <int-literal>
  67.         */
  68.         foreach (ubyte c; this.fvm_Code.toLower()) {
  69.             // How we treat whitespace depends on whether
  70.             // we're parsing a statement.
  71.             if (c == ' ') {
  72.                 // If we're parsing a statement piece, it marks the end
  73.                 // of this piece, so we switch to the next piece.
  74.                 if (onStmtPiece) {
  75.                     if (stmtPieceCtr % 3 == 0) {
  76.                         currSection = &currMnemonic;
  77.                         currValidChars = &mnemonicValidChars;
  78.                         // If this isn't the first statement we're
  79.                         // parsing, increment our statement counter.
  80.                         stmtCtr = stmtPieceCtr > 0 ? 0 : ++stmtCtr;
  81.                     }
  82.                     else if (stmtPieceCtr % 3 == 1) {
  83.                         currSection = &arg0;
  84.                         currValidChars = &argValidChars;
  85.                     }
  86.                     else if (stmtPieceCtr % 3 == 2) {
  87.                         currSection = &arg1;
  88.                         currValidChars = &argValidChars;
  89.                     }
  90.                     // Increment our statement piece counter.
  91.                     ++stmtPieceCtr;
  92.                     // We're now in-between statement pieces.
  93.                     onStmtPiece = false;
  94.                 }
  95.                 // If we're not on a statement piece, whitespace has
  96.                 // no meaning and we can just disregard it by moving on.
  97.                 else continue;
  98.             }
  99.             else if (c == '\r') {
  100.                 continue;
  101.             }
  102.             else if (c == '\n') {
  103.                 if ((*currSection).length == 0) continue;
  104.  
  105.                 this.fvmStmts.length++;
  106.                 this.fvmStmts[stmtCtr++] = Statement(currMnemonic, arg0, arg1);
  107.                 stmtPieceCtr = 3;
  108.                 onStmtPiece = false;
  109.                 currMnemonic = arg0 = arg1 = "";
  110.                 currSection = &currMnemonic;
  111.                 currValidChars = &mnemonicValidChars;
  112.             }
  113.             // If the character isn't one with a special meaning,
  114.             // we can move on to determining whether it is a valid
  115.             // character for the current statement piece.
  116.             else {
  117.                 int equalities = 0;
  118.                 foreach (char vc; *currValidChars)
  119.                     equalities = vc == c ? ++equalities : equalities;
  120.  
  121.                 if (equalities == 0) {
  122.                     writefln("Line %s: Invalid Character in statement (%s).",
  123.                              stmtCtr, cast(char) c);
  124.                     this.parser_error = true;
  125.                 } else {
  126.                     onStmtPiece = false;
  127.                     *currSection ~= c;
  128.                 }
  129.             }
  130.         }
  131.  
  132.         newlineCheck = false;
  133.     }
  134.  
  135.     private:
  136.         bool has_loaded;
  137.         string fvm_Code;
  138.         Statement[] fvmStmts;
  139.         // If true, this will prevent the parser/compiler/thing
  140.         // from advancing to its next pass and will throw a
  141.         // ParserException.
  142.         bool parser_error;
  143. };
  144.  
  145. public class ParserException : Exception { public this() { super(""); }; }
  146.  
  147. public struct Statement {
  148.     public this (string mnemonic, string arg0, string arg1) {
  149.         writefln("Statement Instantiated: %s :: %s :: %s",
  150.                  mnemonic, arg0, arg1
  151.                 );
  152.     }
  153. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement