Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- namespace Vcl {
- public class Reader : GLib.Object {
- public Reader (string text) {
- GLib.Object (text : text);
- }
- internal int position;
- construct {
- position = text.length;
- }
- public unichar peek() {
- int pos = position;
- unichar u = 0;
- if (!text.get_prev_char (ref pos, out u))
- return 0;
- return u;
- }
- public unichar read() {
- unichar u = 0;
- if (!text.get_prev_char (ref position, out u))
- return 0;
- return u;
- }
- public bool eof { get { return peek() == 0; } }
- public string text { get; construct; }
- }
- public errordomain ExpressionError {
- UNKNOWN
- }
- public abstract class Expression : GLib.Object {
- public Expression previous { get; set; }
- public Expression next { get; set; }
- public string name { get; set; }
- static Character parse_character (Reader str) {
- str.read();
- unichar c = str.read();
- if (c == '\'' && str.peek() != '\\')
- throw new ExpressionError.UNKNOWN ("null char");
- if (c == '\'')
- str.read();
- if (str.read() != '\'')
- throw new ExpressionError.UNKNOWN ("invalid char");
- return new Character (c.to_string());
- }
- static String parse_string (Reader str) {
- str.read();
- int pos = str.position;
- bool multi = false;
- if (str.read() == '"' && str.read() == '"')
- multi = true;
- else
- str.position = pos;
- var builder = new StringBuilder("");
- bool end = false;
- while (!str.eof) {
- if (str.peek() != '"')
- builder.prepend_unichar (str.read());
- if (str.peek() == '"' && !multi) {
- str.read();
- if (str.peek() == '\\') {
- str.read();
- builder.prepend_unichar ('"');
- continue;
- }
- end = true;
- break;
- }
- pos = str.position;
- if (str.read() == '"' && str.read() == '"' && str.read() == '"' && multi) {
- end = true;
- break;
- }
- else
- str.position = pos;
- }
- if (!end)
- throw new ExpressionError.UNKNOWN ("can't find end of string");
- return new String (builder.str);
- }
- static Variable parse_variable (Reader str) {
- var builder = new StringBuilder();
- while (str.peek().isalnum() || str.peek() == '_')
- builder.prepend_unichar (str.read());
- return new Variable (builder.str);
- }
- static Method parse_method (Reader str) throws ExpressionError {
- str.read();
- var meth = new Method("");
- meth.parameters.add (parse_expression (str));
- while (str.peek() == ',')
- meth.parameters.insert (0, parse_expression (str));
- if (str.read() != '(')
- throw new ExpressionError.UNKNOWN ("can't find start of method parameters");
- while (str.peek().isspace())
- str.read();
- var builder = new StringBuilder();
- while (str.peek().isalnum() || str.peek() == '_')
- builder.prepend_unichar (str.read());
- meth.name = builder.str;
- return meth;
- }
- static Array parse_array (Reader str) throws ExpressionError {
- str.read();
- var index = parse_expression (str);
- if (str.read() != '[')
- throw new ExpressionError.UNKNOWN ("can't find start of array index");
- while (str.peek().isspace())
- str.read();
- var builder = new StringBuilder();
- while (str.peek().isalnum() || str.peek() == '_')
- builder.prepend_unichar (str.read());
- var arr = new Array (builder.str);
- arr.index = index;
- return arr;
- }
- static Expression parse_expression (Reader str) throws ExpressionError {
- while (str.peek().isspace())
- str.read();
- Expression expr = null;
- if (str.peek().isalnum() || str.peek() == '_')
- expr = parse_variable (str);
- else if (str.peek() == ')')
- expr = parse_method (str);
- else if (str.peek() == ']')
- expr = parse_array (str);
- else if (str.peek() == '"')
- expr = parse_string (str);
- else if (str.peek() == '\'')
- expr = parse_character (str);
- while (str.peek().isspace())
- str.read();
- if (str.peek() == '.') {
- str.read();
- var e = parse_expression (str);
- e.next = expr;
- expr.previous = e;
- }
- return expr;
- }
- public static Expression parse (string data) throws ExpressionError {
- var str = new Reader (data);
- return parse_expression (str);
- }
- }
- public class Array : Expression {
- public Array (string name = "") { GLib.Object (name : name); }
- public Expression index { get; set; }
- }
- public class Method : Expression {
- Gee.ArrayList<Expression> expr_list;
- public Method (string name = "") { GLib.Object (name : name); }
- construct {
- expr_list = new Gee.ArrayList<Expression>();
- }
- public Gee.List<Expression> parameters {
- get {
- return expr_list;
- }
- }
- }
- public class Variable : Expression {
- public Variable (string name = "") { GLib.Object (name : name); }
- }
- public class String : Expression {
- public String (string name = "") { GLib.Object (name : name); }
- }
- public class Character : Expression {
- public Character (string name = "") { GLib.Object (name : name); }
- }
- }
- public static void main (string[] args) {
- string data;
- FileUtils.get_contents ("data", out data);
- var expr = Vcl.Expression.parse (data);
- while (expr is Vcl.Expression) {
- print ("%s\n", expr.get_type().name());
- if (expr is Vcl.Method) {
- foreach (var e in (expr as Vcl.Method).parameters)
- print ("\t%s\n", e.get_type().name());
- }
- expr = expr.previous;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement