Commit ecc3b58a authored by Sarah Spall's avatar Sarah Spall Committed by Vikram Narayanan

Adding vembyr, needed to generator parser, as well as a starting grammar based...

Adding vembyr, needed to generator parser, as well as a starting grammar based on Barrelfish's flounder, and other supporting files. Waited until code compiled to commit
parent 4cdb5e83
all: compiler
compiler: flounder_parser.o idl_compiler.o ast.o
g++ flounder_parser.o idl_compiler.o ast.o -o compiler
idl_compiler.o: idl_compiler.cpp flounder_parser.h
g++ -c idl_compiler.cpp flounder_parser.h
ast.o: ast.cpp ast.h
g++ -c ast.cpp ast.h
flounder_parser.o: flounder_parser.cpp flounder_parser.h
g++ -c flounder_parser.cpp flounder_parser.h
flounder_parser.cpp:
vembyr-1.1/peg.py --cpp flounder > flounder_parser.cpp
flounder_parser.h:
vembyr-1.1/peg.py --h flounder > flounder_parser.h
clean:
rm flounder_parser.* *.o compiler
\ No newline at end of file
Note: run make, then add #include <string> to the top of "flounder_parser.h",
then run make again.
Currently idl_compiler does not do anything
\ No newline at end of file
#include "ast.h"
Interface::Interface(char * n, char * desc, std::vector<Message*> * m)
{
name = n;
description = desc;
function_decs = m;
}
Interface::Interface(char * n, std::vector<Message*> * m)
{
name = n;
description = 0;
function_decs = m;
}
Message::Message(char * n, std::vector<Argument*> * a)
{
name = n;
args = a;
}
Argument::Argument(Type * t_, char * n, char * s)
{
array = true;
t = t_;
name = n;
size = s;
}
Argument::Argument(Type * t_, char * n)
{
array = false;
t = t_;
name = n;
size = 0;
}
Type::Type()
{
}
#ifndef AST_H
#define AST_H
#include <vector>
#include <stdint.h>
class Type
{
public:
Type();
};
class Argument
{
bool array; // true if arg of form: int name[size]
Type * t;
char * name;
char * size; // NULL if array = false
public:
Argument(Type * t, char * n, char * s);
Argument(Type * t, char *n);
};
class Message
{
char * name;
std::vector<Argument*> * args;
public:
Message(char * n, std::vector<Argument* > * a);
};
class Interface
{
char * name;
char * description;
std::vector<Message*> * function_decs;
public:
Interface(char * n, char * desc, std::vector<Message*> * m);
Interface(char * n, std::vector<Message*> * m);
};
enum builtin_type { bool_=1, cap_, char_, give_away_cap,
int_, int8, int16, int32, int64,
intptr, iref, size, string, uint8,
uint16, uint32, uint64, uintptr };
#endif
start-symbol: File
include: {{ #include "ast.h"
#include <vector>
#include <stdlib.h> }}
code: {{
void cast_m(std::vector<Message* > * v, Value & val)
{
for(Value::iterator it = val.getValues().begin(); it != val.getValues().end(); it++)
{
const Value & v2 = *it;
Message* ms = (Message*) v2.getValue();
v->push_back(ms);
}
}
void cast_a(std::vector<Argument* > * v, Value & val)
{
for(Value::iterator it = val.getValues().begin(); it != val.getValues().end(); it++)
{
const Value & v2 = *it;
Argument* ms = (Argument*) v2.getValue();
v->push_back(ms);
}
}
}}
rules:
File = Interface Spacing <eof> {{ value = $1; }}
Interface = INTERFACE n:Identifier OPENC m:Message+ CLOSEC SEMI {{ std::vector<Message*> * functions = new std::vector<Message*>;
cast_m(functions, m);
value = new Interface((char *)n.getValue(), functions); }}
| INTERFACE n:Identifier d:Description OPENC m:Message+ CLOSEC SEMI {{ std::vector<Message* > * functions = new std::vector<Message*>;
cast_m(functions, m);
value = new Interface((char *)n.getValue(),(char *)d.getValue(), functions); }}
Message = MESSAGE i:Identifier OPEN a:Arguments CLOSE SEMI Spacing {{ std::vector<Argument*> * args = new std::vector<Argument*>;
cast_a(args, a);
value = new Message((char*)i.getValue(), args); }}
Arguments = a:ArgStart* {{ std::vector<Argument*> * args = new std::vector<Argument*>;
cast_a(args, a);
value = args; }}
| a:ArgStart* a2:ArgLast {{ std::vector<Argument*> * args = new std::vector<Argument*>;
cast_a(args, a);
Argument * as = (Argument *) a2.getValue();
args->push_back(as);
value = args; }}
ArgStart = s:SimpleArg COMMA {{ value = s; }}
| d:DynamicArg COMMA {{ value = d; }}
ArgLast = s:SimpleArg {{ value = s; }}
| d:DynamicArg {{ value = d; }}
SimpleArg = t:Type i:Identifier {{ value = new Argument((Type*) t.getValue(), (char *) i.getValue()); }}
DynamicArg = t:Type i:Identifier OPENS i2:Identifier CLOSES {{ value = new Argument((Type*) t.getValue(), (char *) i.getValue(), (char *) i2.getValue()); }}
#Types = #incomplete
Type = "bool" | "int32" | "char"
Description = """ d:.* """ Spacing
Identifier = i1:IdentStart i2:IdentCont* Spacing {{ char * f = (char *) malloc(2*sizeof(char));
f[0] = (char) (intptr_t) i1.getValue();
f[1] = '\0';
char * str = (char *) malloc(sizeof(char)+1+(sizeof(char)*i2.getValues().size()));
strcpy(str, f);
for(Value::iterator it = i2.getValues().begin(); it != i2.getValues().end(); it ++)
{
const Value & v = *it;
char * temp = (char *) malloc(2*sizeof(char));
char ms = (char) (intptr_t) v.getValue();
temp[0] = ms;
temp[1] = '\0';
strcat(str, temp);
}
value = str; }}
IdentStart = i:[a-zA-Z_] {{
value = i; }}
IdentCont = i:IdentStart {{
value = i; }}
| i:[0-9] {{
value = i; }}
## reserved words
MESSAGE = "message" Spacing
INTERFACE = "interface" Spacing
SEMI = ";"
OPENC = "{"
CLOSEC = "}"
OPENS = "["
CLOSES = "]"
OPEN = "("
CLOSE = ")"
COMMA = ","
Spacing = Space*
Space = " " | "\t" | EndOfLine
Comment = "/*" .* "*/"
| "//" (!EndOfLine .)* EndOfLine
EndOfLine = "\r\n" | "\n" | "\r"
File <-
Interface <- INTERFACE Identifier Description?
OPENC Type* Message+ CLOSEC SEMI SPACING
Message <- MESSAGE Identifier OPEN Arguments CLOSE SEMI SPACING
Arguments <- ArgStart* ArgLast?
ArgStart <- (SimpleArg / DynamicArg) COMMA
ArgLast <- (SimpleArg / DynamicArg)
SimpleArg <- Type Identifier
DynamicArg <- Type Identifier OPENS Identifier CLOSES
Type <- 'bool' / 'int32' / 'char'
Identifier <- IdentStart IdentCont* Spacing
IdentStart <- [a-zA-Z_]
IdentCont <- IdentStart / [0-9]
// reserved words
MESSAGE <- 'message' Spacing
INTERFACE <- 'interface' Spacing
SEMI <- ';'
OPENC <- '{'
CLOSEC <- '}'
OPENS <- '['
CLOSES <- ']'
OPEN <- '('
CLOSE <- ')'
COMMA <- ','
Spacing <- Space*
Space <- ' ' / '\t' / EndOfLine
Comment <- ('/*' .* '*/'
/ '//' (!EndOfLine .)* EndOfLine)
EndOfLine <- '\r\n' / '\n' / '\r'
#include "ast.h"
#include "flounder_parser.h"
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char ** argv)
{
if(argc < 2)
{
printf("Must provide a filename.");
exit(0);
}
char * filename = argv[1];
Interface * tree = (Interface *) Parser::parse(filename);
printf("testing");
exit(0);
}
This diff is collapsed.
Vembyr 0.1
Read doc/main.pdf
start-symbol: start
options: debug0
module: Mugen.Air
include: {{
#include "mugen/ast/all.h"
#include <map>
#include "gc.h"
typedef std::list<Ast::Section*> SectionList;
}}
code: {{
template<class X>
X as(const Value & value){
return (X) value.getValue();
}
std::string * toString(const Value & input){
std::ostringstream out;
for (Value::iterator it = input.getValues().begin(); it != input.getValues().end(); it++){
out << (char) (long) (*it).getValue();
}
std::string * object = new std::string(out.str());
GC::save(object);
return object;
}
Ast::String * makeString(std::string * str){
/* FIXME: fix line numbers here */
Ast::String * object = new Ast::String(-1, -1, str);
GC::save(object);
return object;
}
Ast::String * makeString(const Value & value){
/* FIXME: fix line numbers here */
Ast::String * object = new Ast::String(-1, -1, toString(value));
GC::save(object);
return object;
}
Ast::Section * makeSection(const Value & str){
Ast::Section * object = new Ast::Section(as<std::string*>(str));
GC::save(object);
return object;
}
Ast::Keyword * makeKeyword(const Value & value){
/* FIXME: fix line numbers here */
Ast::Keyword * object = new Ast::Keyword(-1, -1, as<char*>(value));
GC::save(object);
return object;
}
Ast::Value * makeValueList(const Value & n1, const Value & n2, const Value & n3, const Value & n4){
std::list<Ast::Value*> values;
values.push_back(as<Ast::Value*>(n1));
values.push_back(as<Ast::Value*>(n2));
values.push_back(as<Ast::Value*>(n3));
values.push_back(as<Ast::Value*>(n4));
Ast::ValueList * object = new Ast::ValueList(values);
GC::save(object);
return object;
}
Ast::Value * makeValueList(const Value & front, const Value & rest){
std::list<Ast::Value*> values;
values.push_back(as<Ast::Value*>(front));
for (Value::iterator it = rest.getValues().begin(); it != rest.getValues().end(); it++){
Ast::Value * value = as<Ast::Value*>(Value((*it).getValue()));
if (value == 0){
/* FIXME! replace empty with a new node */
value = makeKeyword(Value("empty"));
values.push_back(value);
} else {
values.push_back(value);
}
}
Ast::ValueList * object = new Ast::ValueList(values);
GC::save(object);
return object;
}
Ast::Value * makeNumber(const Value & sign, const Value & number){
double value = *(as<double*>(number));
if (sign.getValue() != 0 && strcmp(as<const char *>(sign), "-") == 0){
value = -value;
}
/* FIXME! replace empty with a new node */
Ast::Number * object = new Ast::Number(-1, -1, value);
GC::save(object);
return object;
}
double * parseDouble(const Value & value){
std::string * str = toString(value);
std::istringstream get(*str);
double * number = new double;
get >> *number;
GC::save(number);
return number;
}
std::string * makeHeader(const Value & begin, const Value & action, const Value & num){
std::ostringstream out;
out << as<char*>(begin) << " " << as<char*>(action) << " " << (as<Ast::Value*>(num))->toString();
std::string * object = new std::string(out.str());
GC::save(object);
return object;
}
SectionList * makeSectionList(){
SectionList * object = new SectionList();
GC::save(object);
return object;
}
Ast::Attribute * makeAttributeArray(Ast::Keyword * name, Ast::Value * index, Ast::Value * value){
/* FIXME! fix line numbers here */
Ast::AttributeArray * object = new Ast::AttributeArray(-1, -1, name, index, value);
GC::save(object);
return object;
}
void addSection(const Value & section_list_value, const Value & section_value){
SectionList * sections = (SectionList*) section_list_value.getValue();
Ast::Section * section = (Ast::Section*) section_value.getValue();
if (section == 0){
throw ParseException("Cannot add null section");
}
sections->push_back(section);
}
Ast::Attribute * makeAttributeKeyword(const Value & id, const Value & data){
/* FIXME: fix line numbers here */
Ast::AttributeKeyword * object = new Ast::AttributeKeyword(-1, -1, as<Ast::Keyword*>(id), as<Ast::Value*>(data));
GC::save(object);
return object;
}
Ast::Attribute * makeAttributeKeyword(const Value & id){
/* FIXME: fix line numbers here */
Ast::AttributeKeyword * object = new Ast::AttributeKeyword(-1, -1, as<Ast::Keyword*>(id));
GC::save(object);
return object;
}
}}
rules:
start = current:{{ value = makeSectionList(); }} whitespace newline* (sn line(current) whitespace line_end?)* sn <eof> {{ value = current; GC::cleanup(as<SectionList*>(value)); }} <fail> {{ GC::cleanup(0); }}
line(current) = s comment
| s action {{ addSection(current, $2); }}
action = action_start ast:{{value = makeSection($1); }} whitespace newline+ (action_line(ast) whitespace line_end)* {{ value = ast; }}
action_line(section) = s comment
| s data:collision_default {{ as<Ast::Section*>(section)->addAttribute(as<Ast::Attribute*>(data)); }}
| s data:collision {{ as<Ast::Section*>(section)->addAttribute(as<Ast::Attribute*>(data)); }}
| s data:valuelist {{ as<Ast::Section*>(section)->addValue(as<Ast::Value*>(data)); }}
| s data:loopstart {{ as<Ast::Section*>(section)->addAttribute(as<Ast::Attribute*>(data)); }}
| space s
| line:<line> !(s action_start) (!line_end .)+ &line_end {{ std::cout << "Warning: ignoring input at line " << getCurrentLine(line) << " column " << getCurrentColumn(line) << std::endl; }}
# | space+
line_end = newline+
| &<eof> <void>
newline = "\n"
| "\r"
loopstart = "loopstart"{case} ":"? {{ value = makeAttributeKeyword(Value(makeKeyword($1))); }}
whitespace = sw*
sn = space_newline*
space_newline = space
| newline
sw = space
| comment
inline s = space*
inline space = " "
| "\t"
| <ascii 255>
comment = ";" (!newline .)*
| "=" (!newline .)*
| "-" "-" (!newline .)*
collision_default = "Clsn2Default"{case} ":" s num:integer {{ value = makeAttributeKeyword(Value(makeKeyword($1)), num); }}
| "Clsn1Default"{case} ":" s num:integer {{ value = makeAttributeKeyword(Value(makeKeyword($1)), num); }}
| "Clsn2"{case} ":" s num:integer {{ value = makeAttributeKeyword(Value(makeKeyword($1)), num); }}
| "Clsn1"{case} ":" s num:integer {{ value = makeAttributeKeyword(Value(makeKeyword($1)), num); }}
# change int,int,int,int to valuelist ?
collision = name:"Clsn2"{case} s "[" s index:integer s "]" s "=" s n1:integer s "," s n2:integer s "," s n3:integer s "," s n4:integer {{ value = makeAttributeArray(makeKeyword(name), as<Ast::Value*>(index), makeValueList(n1, n2, n3, n4)); }}
| name:"Clsn1"{case} s "[" s index:integer s "]" s "=" s n1:integer s "," s n2:integer s "," s n3:integer s "," s n4:integer {{ value = makeAttributeArray(makeKeyword(name), as<Ast::Value*>(index), makeValueList(n1, n2, n3, n4)); }}
action_start = "[" s begin:"Begin"{case} s action:"Action"{case} s num:integer s (!"]" .)* "]" {{ value = makeHeader(begin, action, num); }}
inline digit = [0123456789]
integer = sign? digit+ {{ value = parseDouble($2); value = makeNumber($1,value); }}
inline sign = "-"
| "+"
valuelist = value (s "," s value?)* {{ value = makeValueList($1,$2); }}
# FIXME: handle the integer values
value = integer
# Are all these things part of .air files?
| "as"{case} integer "d"{case} integer {{ value = makeKeyword($1); }}
| "a"{case} integer {{ value = makeKeyword($1); }}
| "a"{case} {{ value = makeKeyword($1); }}
| "s"{case} integer {{ value = makeKeyword($1); }}
| "s"{case} {{ value = makeKeyword($1); }}
| "vh"{case} {{ value = makeKeyword($1); }}
| "hv"{case} {{ value = makeKeyword($1); }}
| "v"{case} {{ value = makeKeyword($1); }}
| "h"{case} {{ value = makeKeyword($1); }}
This diff is collapsed.
# Default class that generates code given some Peg description. Sub-classes
# should implement every generate_* method
class CodeGenerator:
def __init__(self):
pass
def fail(self):
raise Exception("this method has not been implemented yet")
def generate_not(self, *args):
self.fail()
def generate_ensure(self, *args):
self.fail()
def generate_rule(self, *args):
self.fail()
def generate_void(self, *args):
self.fail()
def generate_predicate(me, *args):
self.fail()
def generate_eof(self, *args):
self.fail()
def generate_sequence(self, *args):
self.fail()
def generate_repeat_once(self, *args):
self.fail()
def generate_code(self, *args):
self.fail()
def generate_repeat_many(self, *args):
self.fail()
def generate_any(self, *args):
self.fail()
def generate_maybe(self, *args):
self.fail()
def generate_or(self, *args):
self.fail()
def generate_bind(self, *args):
self.fail()
def generate_range(self, *args):
self.fail()
def generate_verbatim(self, *args):
self.fail()
def generate_line(self, *args):
self.fail()
def generate_call_rule(self, *args):
self.fail()
# create a variable name
next_var = 0
def nextVar():
global next_var;
next_var += 1;
return "peg_%d" % next_var
def resetGensym():
global next_var
next_var = 0
# create a variable using the argument as a prefix
def gensym(what = "temp"):
return "%s_%s" % (what, nextVar())
def newResult():
return gensym("result")
def newOut():
return gensym("out")
def indent(s):
space = ' '
return s.replace('\n', '\n%s' % space)
def special_char(s):
return s in ["\\