Giter Site home page Giter Site logo

syncpp's Introduction

Syn

Overview

A parser generator for context-free grammars, written in C++. Accepts a grammar in an EBNF notation, generates parser code in C++. The parser produces an AST at runtime.

Features:

  • Grammar is written in an EBNF notation.
  • Generation of AST with attributes.
  • Mapping AST nodes to objects of arbitrary C++ classes.
  • Uses GLR parsing algorithm.
  • Supports Windows and Linux.

Getting Started

Consider a fragment of a grammar:

@Statement : IfStatement | OtherStatement ;
IfStatement : "if" "(" expr=Expression ")" tStmt=Statement ("else" fStmt=Statement)? ;

And C++ classes:

class Statement {
public:
    Statement(){}
    virtual void execute() = 0;
};

class IfStatement : public Statement {
public:
    std::shared_ptr<Expression> m_expr;
    std::shared_ptr<Statement> m_tStmt;
    std::shared_ptr<Statement> m_fStmt;
    
    IfStatement(){}

    void execute() override {
        if (m_expr->evaluate()) {
            m_tStmt->execute();
        } else if (!!m_fStmt) {
            m_fStmt->execute();
        }
    }   
};

Syn generates a parser that converts a text into corresponding C++ objects:

Scanner scanner(text);
std::shared_ptr<Statement> statement = syngen::SynParser::parse_Statement(scanner);
statement->execute();

Sample: a Simple Scripting Language

A simple Javascript-like language interpreter.

Features:

  • Garbage collection.
  • Dynamic type-checking and binding.
  • Lambda expressions.
  • File and socket API.
  • Supports Windows and Linux.

See the Syn grammar of the language.

Code Examples

Try-catch-finally block:

var in = open_file();
try {
    in.read();
} catch (e) {
    sys.out.println("Failed!");
    e.print(sys.out);   // Prints the stack trace.
} finally {
    in.close();
}

Classes, constants, access modifiers:

class Foo {
    // Constants and variables are private by default.
    public const count = get_count();
    
    var name;
    var misc = 0;
    
    new(str) { // Constructor.
        name = str;
        misc = 12.34;
    }
    
    // Functions are public by default.
    function bar() {
        return name + "," + misc;
    }
    
    private function get_count() {
        return 123;
    }
}

Lambda expressions:

function repeat(n, fn) {
    for (var i = 0; i < n; ++i) fn(i);
}

repeat(5, (x){
    sys.out.println("x=" + x);
});

Anonymous classes:

function make_class(prop) {
    return class {
        var tag;
    
        new(z) { // Constructor.
            tag = z;
        }
        
        function get_tag() { return tag; }
        function get_prop() { return prop; }
    };
}

var cls = make_class(123);
var obj = new cls(456);
sys.out.println(obj.get_prop() + " " + obj.get_tag());

Typeof expression:

function print(value) {
    if ("array" == typeof(value)) {
        for (var e : value) print(e);
    } else {
        sys.out.println(value);
    }
}

String class:

const str = "Hello World";
print(str.length());
print(str.substring(0, 5));
print(str.index_of('w'));
print(str.char_at(7));

StringBuffer class:

var buf = new sys.StringBuffer();
buf.append("Hello ");
buf.append("World");
print(buf.to_string());   // Prints "Hello World"
buf.clear();
buf.append("Foo");
print(buf.to_string());   // Prints "Foo".

ArrayList class:

var list = new sys.ArrayList();
list.add("Apple");
list.add("Orange");
list.add("Banana");
list.sort();
for (var s : list) print(s);

HashMap class:

var map = new sys.HashMap();
map.put("Apple", 5);
map.put("Orange", 10);
map.put("Banana", 15);
map.put("Apple", 33);
map.remove("Banana");
for (var k : map.keys()) print(k + " : " + map.get(k));

File class:

var file = new sys.File("file.txt");
if (file.exists()) {
    print("File: " + file.get_absolute_path());
    print("Size: " + file.get_size());
    print("Text: " + file.read_text());
}

Stream API:

var file = new sys.File("file.txt");
var out = file.text_out();
try {
    out.println("Hello ");
    out.println("World");
} finally {
    out.close();
}
print(file.read_text());
file.delete();

Socket API:

var ss = new sys.ServerSocket(12345);
try {
    for (;;) {
        var s = ss.accept();
        try {
            s.write("Hello World".get_bytes());
        } finally {
            s.close();
        }
    }
} finally {
    ss.close();
}

Function sys.execute():

var scope = new sys.HashMap();
scope.put("x", 5);
scope.put("y", 10);

var s = sys.execute("filename.s", "return x + y;", scope);
sys.out.println(s);   // Prints 15.

Sample HTTP Server

A simlpe HTTP server written in the sample scripting language (source code).

Supports dynamic server pages written in the sample scripting language itself. An API similar to Java Servlet API is provided for dynamic server pages.

Sample dynamic page: Fibonacci Numbers (source code: fibonacci.s, html.s).

Dynamic Pages Code Examples

Setting HTTP response headers and body:

http.resp.set_content_type("text/plain; charset=UTF-8");
http.resp.add_header("Content-Language", "en");
http.resp.set_body("Hello World");

Writing response body as a stream:

var out = http.resp.get_out(); // The content type is "text/html" by default.
out.write("<html>");
out.write("<head><title>Hello World</title></head>");
out.write("<body><h1>Hello World</h1></body>");
out.write("</html>");

Getting URL parameters:

http.resp.set_content_type("text/plain");
var out = http.resp.get_out();

var params = http.req.get_parameters(); // Returns an array of parameter names, the order is undefined.
params.sort();
for (var param : params) {
    var value = http.req.get_parameter(param);
    out.write(param + " = " + value + "\n");
}

Context attributes (exist during server lifetime):

var cnt = http.context.get_attribute("visit_count");
if (cnt == null) cnt = 0;
http.context.set_attribute("visit_count", cnt + 1);

http.resp.set_content_type("text/plain");
http.resp.set_body("This page has already been visited " + cnt + " time(s).");

Cookies:

var body;

var cookie = http.req.get_cookie("my_cookie");
if (cookie == null) {
    body = "No cookie.";
    cookie = "0";
} else {
    body = "Cookie : " + cookie;
}

http.resp.set_content_type("text/plain");
http.resp.set_cookie("my_cookie", cookie + cookie.length());
http.resp.set_body(body);

Sessions and session attributes (sessions are maintained via cookies):

var s = http.req.get_session();
var cnt = s.get_attribute("cnt");
if (cnt == null) cnt = 0;

var body = "You have already visited this page " + cnt + " time(s).";
if (cnt >= 5) {
    body += "\nClosing the session.";
    s.close();
} else {
    s.set_attribute("cnt", cnt + 1);
}

http.resp.set_content_type("text/plain");
http.resp.set_body(body);

How to Run?

Download the binary distribution: script-cpp-win32-1.0.zip (Windows only).

To execute an arbitrary script, run script.cmd, passing the script file name in the command line.

syncpp's People

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.