From 06e7a054011f00d81320a3098f3d45830907b8d1 Mon Sep 17 00:00:00 2001 From: adam Date: Tue, 28 Aug 2007 01:24:03 +0100 Subject: [PATCH] updates to fleet grammar --- src/edu/berkeley/fleet/assembler/Parser.java | 156 ++++++++++++++++---------- src/edu/berkeley/fleet/assembler/fleet.g | 121 ++++++++++---------- 2 files changed, 156 insertions(+), 121 deletions(-) diff --git a/src/edu/berkeley/fleet/assembler/Parser.java b/src/edu/berkeley/fleet/assembler/Parser.java index 28d3520..f59f03c 100644 --- a/src/edu/berkeley/fleet/assembler/Parser.java +++ b/src/edu/berkeley/fleet/assembler/Parser.java @@ -40,9 +40,11 @@ public class Parser { if (grammar != null) return grammar; InputStream grammarStream = Parser.class.getClassLoader().getResourceAsStream("edu/berkeley/fleet/assembler/fleet.g"); - CharParser metaGrammarParser = new CharParser(MetaGrammar.newInstance()); + CharParser metaGrammarParser = new CharParser(GrammarAST.getMetaGrammar()); Tree parsedGrammar = metaGrammarParser.parse(new CharInput(grammarStream)).expand1(); - grammar = GrammarAST.buildFromAST(parsedGrammar, "s", new File[0]); + grammar = GrammarAST.buildFromAST(parsedGrammar, "s", new GrammarAST.ImportResolver() { + public InputStream getImportStream(String importname) { return null; } + }); return grammar; } @@ -89,7 +91,6 @@ public class Parser { inst = new Instruction.CodeBagDescriptor(old.pump, offset, codeBags.get((int)old.offset).size()); - //System.out.println("cbd: " + offset + " " + codeBags.get((int)old.offset).size() + " " + codeBags.get((int)old.offset).name + " " + codeBags.get((int)old.offset)); } fleet.writeInstruction(dos, inst); count++; @@ -112,10 +113,10 @@ public class Parser { for(Tree statement : t.child(1)) fillCodeBag(statement, cb); - } else if (head.equals("Import")) { + } else if (head.equals("#import")) { // ignored - } else if (head.equals("Ship")) { + } else if (head.equals("#ship")) { String name = name(t.child(0)); String type = string(t.child(1)); Ship ship = null; @@ -130,16 +131,16 @@ public class Parser { } shipMap.put(name, ship); - } else if (head.equals("Include")) { + } else if (head.equals("#include")) { try { walk(parse(new InputStreamReader(new FileInputStream(string(t.child(0))))), cb); } catch (Exception e) { throw new RuntimeException(e); } - } else if (head.equals("Expect")) { - expect.add(Long.parseLong(string(t.child(0)))); - } else if (head.equals("Skip")) { + } else if (head.equals("#expect")) { + expect.add(number(t.child(0))); + } else if (head.equals("#skip")) { skip = true; } @@ -153,12 +154,19 @@ public class Parser { return ret; } + String stringBody(Tree t) { + String ret = ""; + for(Tree c : t) + ret += string(c); + return ret; + } + String name(Tree t) { return string(t.child(0))+string(t.child(1)); } Destination portReference(Tree t) { - if (!"Port".equals(t.head()) && !"SubPort".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head())) return null; + if (!"Pump".equals(t.head()) && !"Destination".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head())) return null; String shipName = name(t.child(0)); String portName = name(t.child(1)); String subPort = t.size()<3 ? null : name(t.child(2)); @@ -182,7 +190,7 @@ public class Parser { } Pump pump(Tree t) { - if (!"Port".equals(t.head()) && !"SubPort".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head())) + if (!"Pump".equals(t.head()) && !"Destination".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head())) throw new RuntimeException(t+""); String shipName = name(t.child(0)); String portName = name(t.child(1)); @@ -229,14 +237,15 @@ public class Parser { long literal = 0; for(int i=0; i t, CodeBag cb) { if (t.head()==null) return; - else if (t.head().equals("NamedCodeBag")) { + else if (t.head().equals("CodeBagDef")) { CodeBag cb2 = getCodeBag(name(t.child(0))); for(Tree statement : t.child(1)) fillCodeBag(statement, cb2); @@ -246,24 +255,61 @@ public class Parser { OUTER: for(Tree tt : t.child(1)) { int count = 1; - Tree ttx = null; - boolean requeue = false; - ttx = tt.child(1); - if (tt.size() > 1 && tt.child(0).size()>0) { - tt = tt.child(0).child(0); - if (tt.head().equals("BrackStar")) { - count = 0; - requeue = false; - } else if (tt.head().equals("ParenStar")) { + if ("unclog".equals(tt.head())) { + cb.add(new Instruction.UnClog(pump)); + continue; + } else if ("clog".equals(tt.head())) { + cb.add(new Instruction.Clog(pump)); + continue; + } else if ("kill".equals(tt.head())) { + count = tt.size()==0 ? 1 : (int)number(tt.child(0)); + cb.add(new Instruction.Kill(pump, count)); + continue; + } else if ("literal".equals(tt.head())) { + long literal = 0; + if (tt.child(0).head().equals("CodeBagBody")) { + Tree tq = tt; + CodeBag cb2 = getCodeBag("anon"+(anoncount++)); + for(Tree statement : tq.child(0)) + fillCodeBag(statement, cb2); + cb.add(new Instruction.CodeBagDescriptor(pump, cb2.getFakeAddress(), 0)); + continue OUTER; + } else if (tt.child(0).head().equals("Name")) { + String refname = name(tt.child(0)); + CodeBag cb2 = getCodeBag(refname); + cb.add(new Instruction.CodeBagDescriptor(pump, cb2.getFakeAddress(), 0)); + continue OUTER; + } else if (tt.child(0).head().equals("[")) { + literal = parseSSL(tt.child(0)); + } else { + literal = number(tt.child(0)); + } + count = 1; + if ("int".equals(tt.child(1).head())) { + count = (int)number(tt.child(1)); + } else if ("forever".equals(tt.child(1).head())) { count = 0; - requeue = true; - } else if (tt.head().equals("Brack")) { - count = Integer.parseInt(string(tt.child(0))); - requeue = false; - } else if (tt.head().equals("Paren")) { - count = Integer.parseInt(string(tt.child(0))); - requeue = true; } + cb.add(new Instruction.LocalLiteral(pump, literal, count)); + continue; + } + Tree ttx = null; + boolean requeue = false; + ttx = tt.child(1).head().equals("Commands") ? tt.child(1) : tt; + if ("int".equals(tt.child(2).head())) { + count = (int)number(tt.child(2)); + requeue = true; + } else if ("forever".equals(tt.child(2).head())) { + count = 0; + requeue = true; + } + tt = tt.child(0); + if (tt.head().equals("[*]")) { + count = 0; + requeue = false; + } else if (tt.head().equals("int")) { + count = (int)number(tt); + requeue = false; } boolean tokenIn = false; boolean dataIn = false; @@ -277,39 +323,21 @@ public class Parser { Destination dest = null; for(int i=0; i expect; public static boolean skip; + private static long number(Tree t) { + String ret = ""; + for(Object c : t.child(2)) ret += ((Tree)c).head(); + boolean negative = "-".equals(t.child(0).head()); + ret = ret.trim(); + long val = 0; + if ("0x".equals(t.child(1).head())) val = Long.parseLong(ret, 16); + else if ("0b".equals(t.child(1).head())) val = Long.parseLong(ret, 2); + else val = Long.parseLong(ret); + if (negative) val = -1L * val; + return val; + } } diff --git a/src/edu/berkeley/fleet/assembler/fleet.g b/src/edu/berkeley/fleet/assembler/fleet.g index 0aeb910..4964224 100644 --- a/src/edu/berkeley/fleet/assembler/fleet.g +++ b/src/edu/berkeley/fleet/assembler/fleet.g @@ -1,76 +1,71 @@ -// The FLEET Assembly Language Grammar -// Updated 05-Nov-2006 +// The FLEET Assembly Language Grammar [26-Aug-2007] // Note that this is the *entire, complete* formal specification of // the grammar. An equivalent lex+yacc grammar and support code would // be several times as long. -Comment = "//" ~[\n\r]!* [\r\n]! - | "/*" ~[\n\r]!* "*/" -ws = ([\r\n ] | Comment)!* -> ~[\r\n ] +s = ws Program ws +Program:: = Directives CodeBagBody /ws +Directives:: = Directive */ ws +CodeBagBody:: = (Fiber | CodeBagDef) */ ws +CodeBagDef:: = CodeBagName ":" "{" CodeBagBody "}" /ws +Fiber:: = Pump ":" Instructions /ws -s = ws! Program ws! -Program = Program:: Directive+/ws - | Program:: ("":: Directive+/ws) ws! CodeBagBody +Instructions:: = Instruction +/ ws +Instruction = ^"unclog" ";" /ws + | ^"clog" ";" /ws + | ^"kill" ";" /ws + | ^"kill" int ";" /ws + | ^"literal" Literal RequeueCount ";" /ws + | RepeatCount Commands RequeueCount ^";" /ws +RepeatCount = "" | ^"[*]" | "[" int "]" +RequeueCount = "" + | "," "requeue" (^"forever" | int ws "times") /ws -Statement = Fiber:: Source ":" ("":: Instruction +/ ws) /ws - | NamedCodeBag:: name ":" "{" CodeBagBody "}" /ws +// FIXME: ordering constraint on these +Commands:: = Command +/ (ws "," ws) +Command = ^"wait" + | ^"nop" + | ^"discard" + | ^"recieve" + | ^"take" + | ^"deliver" + | ^"send" + | ^"sendto" Destination /ws + | ^"notify" Destination /ws + | ^"notifyLast" Destination /ws -CountField = Brack:: "[" int "]" - | Paren:: "(" int ")" - | BrackStar:: "[*]" - | ParenStar:: "(*)" -Instruction = Instruction:: - ("":: (CountField ws!)?) - ("":: Command +/ (ws! "," ws!) ws! ";"!) -Command = Nop:: "nop" - | Kill:: "kill" - | KillStar:: "unclog" - | Clog:: "clog" - | Wait:: "wait" - | Discard:: "dismiss" - | Take:: ("take"|"receive") - | SendTo:: "sendto" ws! Port - | DataOutDest:: "send" - | Deliver:: "deliver" - | LocalLiteral:: "literal" ws! int - | LocalLiteralConst:: "literal" ws! SSL - | LocalLiteralCodeBag:: "literal" ws! CodeBag - | Ack:: "notify" ws! Port - | AckLast:: "notifyLast" ws! Port +Literal = int + | ShipType "." PortName ^"[" Constants "]" + | CodeBagName + | "{" CodeBagBody "}" /ws -Source = Port - | ShipSpecific +Pump:: = ShipName "." PortName +Destination:: = ShipName "." PortName +Constants:: = Constant +/ "," +Constant:: = [a-zA-Z0-9=_\-]++ -SSL = ShipSpecificLiteral:: shiptype "." portname "[" SSLSpec "]" -Port = Port:: shipname "." portname - | SubPort:: shipname "." portname "." portname - | ^"()" +CodeBagName = UpcaseWord +ShipType = UpcaseWord +ShipName = DowncaseWord +PortName = DowncaseWord +Word = UpcaseWord | DowncaseWord +UpcaseWord = Name:: [A-Z] ("":: [A-Za-z0-9_]**) +DowncaseWord = Name:: [a-z] ("":: [A-Za-z0-9_]**) +int:: = (^"-"|^"") (^"0x"|^"0b"|^"") (digits:: [0-9]++) -SSLSpec:: = SSLElement +/ "," -SSLElement = "":: [a-zA-Z0-9=_\-]++ +ws! = wsx -> ~[\r\n ] +wsx! = () + | wsx [\r\n ] + | wsx Comment +Comment! = "//" ~[\n\r]* [\r\n] + | "/*" ~[\n\r]* "*/" -CodeBagBody:: = Statement +/ ws -CodeBag = CodeBagRef:: CodeBagName - | AnonymousCodeBag:: "{" CodeBagBody "}" /ws - -CodeBagName = name -shipname = name -shiptype = Name:: [A-Z] ("":: [A-Za-z0-9_]**) -ShipSpecificLiteral = Name:: [A-Z] ("":: [A-Z0-9_]**) -portname = Name:: [a-z] ("":: [A-Za-z0-9_]**) -name = Name:: [A-Za-z] ("":: [A-Za-z0-9_]**) -index = "[" ("":: [0-9]+) "]" | ("":: [0-9]+) -int = "":: [\-0-9]++ -ShipSpecific = ShipSpecific:: "\"" (~[\"])++ "\"" - -// the following are not part of the official FLEET syntax and are -// specific to Adam's interpreter. - -Directive = "#memory" "{" (Memory:: int +/ (ws! "," ws!)) "}" /ws - | Import:: "#import" [A-Za-z_.]++ /ws - | Include:: "#include" ws! "\"" ~[\"]+ "\"" - | Ship:: "#ship" shipname ":" ("":: [0-9A-Za-z_.]++) /ws - | Expect:: "#expect" int /ws - | Skip:: "#skip" +// the following extensions are not part of the official FLEET syntax +Directive = ^"#memory" "{" (Memory:: int +/ (ws! "," ws!)) "}" /ws + | ^"#import" [A-Za-z_.]++ /ws + | ^"#include" ws! "\"" ~[\"]+ "\"" + | ^"#ship" ShipName ":" ("":: [0-9A-Za-z_.]++) /ws + | ^"#expect" int /ws + | ^"#skip" -- 1.7.10.4