- implement scanner token stream via channel
- change test_scanner to scan using both methods
- add -pscan flag to Go front-end to choose between conventional
synchronous or parallel asynchronous scanning
R=r
OCL=13937
CL=13937
diff --git a/usr/gri/gosrc/compilation.go b/usr/gri/gosrc/compilation.go
index dd10471..0f284d3 100644
--- a/usr/gri/gosrc/compilation.go
+++ b/usr/gri/gosrc/compilation.go
@@ -26,9 +26,15 @@
scanner := new(Scanner.Scanner);
scanner.Open(file_name, src);
+
+ var tstream *chan *Scanner.Token;
+ if comp.flags.pscan {
+ tstream = new(chan *Scanner.Token, 100);
+ go scanner.Server(tstream);
+ }
parser := new(Parser.Parser);
- parser.Open(comp, scanner);
+ parser.Open(comp, scanner, tstream);
parser.ParseProgram();
if parser.S.nerrors > 0 {
diff --git a/usr/gri/gosrc/globals.go b/usr/gri/gosrc/globals.go
index ed42e4a..121052c 100644
--- a/usr/gri/gosrc/globals.go
+++ b/usr/gri/gosrc/globals.go
@@ -63,7 +63,8 @@
print_export bool;
semantic_checks bool;
verbose int;
- sixg bool;
+ sixg bool; // 6g compatibility
+ pscan bool; // parallel scanning using a token channel
}
diff --git a/usr/gri/gosrc/go.go b/usr/gri/gosrc/go.go
index 31f1b87..1097c4e 100644
--- a/usr/gri/gosrc/go.go
+++ b/usr/gri/gosrc/go.go
@@ -23,6 +23,7 @@
print " -v verbose mode\n";
print " -vv very verbose mode\n";
print " -6g 6g compatibility mode\n";
+ print " -pscan scan and parse in parallel (use token channel)\n";
}
@@ -43,6 +44,7 @@
case "-v": flags.verbose = 1;
case "-vv": flags.verbose = 2;
case "-6g": flags.sixg = true;
+ case "-pscan": flags.pscan = true;
default: files.AddStr(arg);
}
}
diff --git a/usr/gri/gosrc/parser.go b/usr/gri/gosrc/parser.go
index 3433b63..2e2346e 100644
--- a/usr/gri/gosrc/parser.go
+++ b/usr/gri/gosrc/parser.go
@@ -19,6 +19,7 @@
semantic_checks bool;
verbose, indent int;
S *Scanner.Scanner;
+ C *chan *Scanner.Token;
// Token
tok int; // one token look-ahead
@@ -62,7 +63,12 @@
func (P *Parser) Next() {
- P.tok, P.pos, P.val = P.S.Scan();
+ if P.C == nil {
+ P.tok, P.pos, P.val = P.S.Scan();
+ } else {
+ t := <- P.C;
+ P.tok, P.pos, P.val = t.tok, t.pos, t.val;
+ }
if P.verbose > 1 {
P.PrintIndent();
print "[", P.pos, "] ", Scanner.TokenName(P.tok), "\n";
@@ -70,12 +76,13 @@
}
-func (P *Parser) Open(comp *Globals.Compilation, S *Scanner.Scanner) {
+func (P *Parser) Open(comp *Globals.Compilation, S *Scanner.Scanner, C *chan *Scanner.Token) {
P.comp = comp;
P.semantic_checks = comp.flags.semantic_checks;
P.verbose = comp.flags.verbose;
P.indent = 0;
P.S = S;
+ P.C = C;
P.Next();
P.level = 0;
P.top_scope = Universe.scope;
diff --git a/usr/gri/gosrc/scanner.go b/usr/gri/gosrc/scanner.go
index add320e..a50ad2a 100644
--- a/usr/gri/gosrc/scanner.go
+++ b/usr/gri/gosrc/scanner.go
@@ -804,3 +804,22 @@
return tok, pos, val;
}
+
+
+export type Token struct {
+ pos int;
+ tok int;
+ val string;
+}
+
+
+func (S *Scanner) Server(c *chan *Token) {
+ for {
+ t := new(Token);
+ t.tok, t.pos, t.val = S.Scan();
+ c -< t;
+ if t.tok == EOF {
+ break;
+ }
+ }
+}
diff --git a/usr/gri/gosrc/test_scanner.go b/usr/gri/gosrc/test_scanner.go
index 2ce097f..5c23acf 100644
--- a/usr/gri/gosrc/test_scanner.go
+++ b/usr/gri/gosrc/test_scanner.go
@@ -7,7 +7,7 @@
import Scanner "scanner"
-func Scan(filename, src string) {
+func Scan1(filename, src string) {
S := new(Scanner.Scanner);
S.Open(filename, src);
for {
@@ -24,16 +24,41 @@
}
+func Scan2(filename, src string) {
+ S := new(Scanner.Scanner);
+ S.Open(filename, src);
+ c := new(chan *Scanner.Token, 32);
+ go S.Server(c);
+ for {
+ var t *Scanner.Token;
+ t = <- c;
+ tok, pos, val := t.tok, t.pos, t.val;
+ print pos, ": ", Scanner.TokenName(tok);
+ if tok == Scanner.IDENT || tok == Scanner.INT || tok == Scanner.FLOAT || tok == Scanner.STRING {
+ print " ", val;
+ }
+ print "\n";
+ if tok == Scanner.EOF {
+ return;
+ }
+ }
+}
+
+
func main() {
for i := 1; i < sys.argc(); i++ {
var src string;
var ok bool;
src, ok = sys.readfile(sys.argv(i));
if ok {
- print "scanning " + sys.argv(i) + "\n";
- Scan(sys.argv(i), src);
+ print "scanning (standard) " + sys.argv(i) + "\n";
+ Scan1(sys.argv(i), src);
+ print "\n";
+ print "scanning (channels) " + sys.argv(i) + "\n";
+ Scan2(sys.argv(i), src);
} else {
print "error: cannot read " + sys.argv(i) + "\n";
}
+ print "\n";
}
}