[Monodevelop-patches-list] r1421 - in trunk/MonoDevelop/src: . Tools Tools/SharpCoco Tools/SharpCoco/src
commit-watcher at mono-cvs.ximian.com
commit-watcher at mono-cvs.ximian.com
Fri Apr 9 13:17:47 EDT 2004
Author: jluke
Date: 2004-04-09 13:17:47 -0400 (Fri, 09 Apr 2004)
New Revision: 1421
Modified:
trunk/MonoDevelop/src/Makefile.am
trunk/MonoDevelop/src/Tools/
trunk/MonoDevelop/src/Tools/SharpCoco/readme.txt
trunk/MonoDevelop/src/Tools/SharpCoco/src/AssemblyInfo.cs
trunk/MonoDevelop/src/Tools/SharpCoco/src/Coco.atg
trunk/MonoDevelop/src/Tools/SharpCoco/src/Coco.cs
trunk/MonoDevelop/src/Tools/SharpCoco/src/DFA.cs
trunk/MonoDevelop/src/Tools/SharpCoco/src/Parser.cs
trunk/MonoDevelop/src/Tools/SharpCoco/src/Parser.frame
trunk/MonoDevelop/src/Tools/SharpCoco/src/ParserGen.cs
trunk/MonoDevelop/src/Tools/SharpCoco/src/Scanner.cs
trunk/MonoDevelop/src/Tools/SharpCoco/src/Scanner.frame
trunk/MonoDevelop/src/Tools/SharpCoco/src/Tab.cs
trunk/MonoDevelop/src/Tools/SharpCoco/src/Trace.cs
Log:
whoops
no need to build the Tools by default
Modified: trunk/MonoDevelop/src/Makefile.am
===================================================================
--- trunk/MonoDevelop/src/Makefile.am 2004-04-09 12:41:44 UTC (rev 1420)
+++ trunk/MonoDevelop/src/Makefile.am 2004-04-09 17:17:47 UTC (rev 1421)
@@ -1,3 +1,3 @@
-SUBDIRS = Tools Libraries Main AddIns
+SUBDIRS = Libraries Main AddIns
Property changes on: trunk/MonoDevelop/src/Tools
___________________________________________________________________
Name: svn:ignore
- Makefile
Makefile.am
Makefile.in
+ Makefile
Makefile.in
Modified: trunk/MonoDevelop/src/Tools/SharpCoco/readme.txt
===================================================================
--- trunk/MonoDevelop/src/Tools/SharpCoco/readme.txt 2004-04-09 12:41:44 UTC (rev 1420)
+++ trunk/MonoDevelop/src/Tools/SharpCoco/readme.txt 2004-04-09 17:17:47 UTC (rev 1421)
@@ -1,14 +1,14 @@
-Modified version of Coco/R
-
-The original version can be found at:
-http://www.ssw.uni-linz.ac.at/Research/Projects/Coco/CSharp/
-
-Changes
-
-+ Added #line pragmas for the generated parser
-+ Now Coco uses more enums than ints...
-+ no static method generation (now all is public)
-+ Error & Scanner are now fields inside the parser, no more static
- calling
-
+Modified version of Coco/R
+
+The original version can be found at:
+http://www.ssw.uni-linz.ac.at/Research/Projects/Coco/CSharp/
+
+Changes
+
++ Added #line pragmas for the generated parser
++ Now Coco uses more enums than ints...
++ no static method generation (now all is public)
++ Error & Scanner are now fields inside the parser, no more static
+ calling
+
Mike
\ No newline at end of file
Modified: trunk/MonoDevelop/src/Tools/SharpCoco/src/AssemblyInfo.cs
===================================================================
--- trunk/MonoDevelop/src/Tools/SharpCoco/src/AssemblyInfo.cs 2004-04-09 12:41:44 UTC (rev 1420)
+++ trunk/MonoDevelop/src/Tools/SharpCoco/src/AssemblyInfo.cs 2004-04-09 17:17:47 UTC (rev 1421)
@@ -1,32 +1,32 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-// Information about this assembly is defined by the following
-// attributes.
-//
-// change them to the information which is associated with the assembly
-// you compile.
-
-[assembly: AssemblyTitle("")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("")]
-[assembly: AssemblyCopyright("")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// The assembly version has following format :
-//
-// Major.Minor.Build.Revision
-//
-// You can specify all values by your own or you can build default build and revision
-// numbers with the '*' character (the default):
-
-[assembly: AssemblyVersion("1.0.*")]
-
-// The following attributes specify the key for the sign of your assembly. See the
-// .NET Framework documentation for more information about signing.
-// This is not required, if you don't want signing let these attributes like they're.
-[assembly: AssemblyDelaySign(false)]
-[assembly: AssemblyKeyFile("")]
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following
+// attributes.
+//
+// change them to the information which is associated with the assembly
+// you compile.
+
+[assembly: AssemblyTitle("")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// The assembly version has following format :
+//
+// Major.Minor.Build.Revision
+//
+// You can specify all values by your own or you can build default build and revision
+// numbers with the '*' character (the default):
+
+[assembly: AssemblyVersion("1.0.*")]
+
+// The following attributes specify the key for the sign of your assembly. See the
+// .NET Framework documentation for more information about signing.
+// This is not required, if you don't want signing let these attributes like they're.
+[assembly: AssemblyDelaySign(false)]
+[assembly: AssemblyKeyFile("")]
Modified: trunk/MonoDevelop/src/Tools/SharpCoco/src/Coco.atg
===================================================================
--- trunk/MonoDevelop/src/Tools/SharpCoco/src/Coco.atg 2004-04-09 12:41:44 UTC (rev 1420)
+++ trunk/MonoDevelop/src/Tools/SharpCoco/src/Coco.atg 2004-04-09 17:17:47 UTC (rev 1421)
@@ -1,432 +1,432 @@
-/* ------------------------------------------------------------------------
- * Coco.ATG
- * Attributed grammer of Coco/R
- * by H. Moessenboeck, Univ. of Linz
- * extended by
- * M. Loeberbauer & A. Woess, Univ. of Linz
- * ------------------------------------------------------------------------*/
-
-using System.Collections;
-using System.Text;
-
-COMPILER Coco
-
- const int id = 0;
- const int str = 1;
-
- static bool genScanner;
-
-/*-------------------------------------------------------------------------*/
-
-CHARACTERS
- letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".
- digit = "0123456789".
- cr = '\r'.
- lf = '\n'.
- tab = '\t'.
- stringCh = ANY - '"' - '\\' - cr - lf.
- charCh = ANY - '\'' - '\\' - cr - lf.
- printable = '\u0020' .. '\u007e'.
- hex = "0123456789abcdef".
-
-IGNORE cr + lf + tab
-
-TOKENS
- ident = letter { letter | digit }.
- number = digit { digit }.
- string = '"' { stringCh | '\\' printable } '"'.
- badString = '"' { stringCh | '\\' printable } (cr | lf).
- char = '\'' ( charCh | '\\' printable { hex } ) '\''.
-
-PRAGMAS
- ddtSym = '$' { digit | letter }. (. Tab.SetDDT(la.val); .)
-
-COMMENTS FROM "/*" TO "*/" NESTED
-
-/*-------------------------------------------------------------------------*/
-
-PRODUCTIONS
-
-Coco (. Symbol sym; Graph g; string gramName; .)
-=
- [ UsingDecl<out ParserGen.usingPos> ]
-
- "COMPILER" (. int gramLine = t.line;
- genScanner = true;
- bool ok = true;
- Tab.ignored = null;
- .)
- ident (. gramName = t.val;
- int beg = la.pos;
- .)
- { ANY } (. Tab.semDeclPos = new Position(beg, la.pos-beg, 0); .)
- { Declaration }
- SYNC
- "PRODUCTIONS" (. if (genScanner) DFA.MakeDeterministic();
- Graph.DeleteNodes();
- .)
- { ident (. sym = Symbol.Find(t.val);
- bool undef = sym == null;
- if (undef) sym = new Symbol(Node.nt, t.val, t.line);
- else {
- if (sym.typ == Node.nt) {
- if (sym.graph != null) SemErr("name declared twice");
- } else SemErr("this symbol kind not allowed on left side of production");
- sym.line = t.line;
- }
- bool noAttrs = sym.attrPos == null;
- sym.attrPos = null;
- .)
- [ AttrDecl<sym> ] (. if (!undef)
- if (noAttrs != (sym.attrPos == null))
- SemErr("attribute mismatch between declaration and use of this symbol");
- .)
- [ SemText<out sym.semPos> ] WEAK
- '='
- Expression<out g> (. sym.graph = g.l;
- Graph.Finish(g);
- .)
- WEAK
- '.'
- }
- "END" ident (. if (gramName != t.val)
- SemErr("name does not match grammar name");
- Tab.gramSy = Symbol.Find(gramName);
- if (Tab.gramSy == null)
- SemErr("missing production for grammar name");
- else {
- sym = Tab.gramSy;
- if (sym.attrPos != null)
- SemErr("grammar symbol must not have attributes");
- }
- Tab.noSym = new Symbol(Node.t, "???", 0); // noSym gets highest number
- Tab.SetupAnys();
- Tab.RenumberPragmas();
- if (Tab.ddt[2]) Node.PrintNodes();
- if (Errors.count == 0) {
- Console.WriteLine("checking");
- Tab.CompSymbolSets();
- ok = ok && Tab.GrammarOk();
- if (Tab.ddt[7]) Tab.XRef();
- if (ok) {
- Console.Write("parser");
- ParserGen.WriteParser();
- if (genScanner) {
- Console.Write(" + scanner");
- DFA.WriteScanner();
- if (Tab.ddt[0]) DFA.PrintStates();
- }
- Console.WriteLine(" generated");
- if (Tab.ddt[8]) ParserGen.WriteStatistics();
- }
- }
- if (Tab.ddt[6]) Tab.PrintSymbolTable();
- .)
- '.'
-.
-
-/*------------------------------------------------------------------------------------*/
-
-Declaration (. Graph g1, g2; bool nested = false; .)
-=
- "CHARACTERS" { SetDecl }
-| "TOKENS" { TokenDecl<Node.t> }
-| "PRAGMAS" { TokenDecl<Node.pr> }
-| "COMMENTS"
- "FROM" TokenExpr<out g1>
- "TO" TokenExpr<out g2>
- ( "NESTED" (. nested = true; .)
- | (. nested = false; .)
- ) (. new Comment(g1.l, g2.l, nested); .)
-| "IGNORE" Set<out Tab.ignored> (. Tab.ignored[' '] = true; /* ' ' is always ignored */
- if (Tab.ignored[0]) SemErr("may not ignore \'\\0\'"); .)
-| "TOKENNAMES" (. Symbol.tokenNames = new Hashtable(); .)
- { ( string | ident ) (. string key = t.val; .)
- "=" ident (. string val = t.val; Symbol.tokenNames.Add(key, val); .)
- }
-.
-
-/*------------------------------------------------------------------------------------*/
-
-SetDecl (. BitArray s; .)
-=
- ident (. string name = t.val;
- CharClass c = CharClass.Find(name);
- if (c != null) SemErr("name declared twice");
- .)
- '=' Set<out s> (. if (Sets.Elements(s) == 0) SemErr("character set must not be empty");
- c = new CharClass(name, s);
- .)
- '.'
-.
-
-/*------------------------------------------------------------------------------------*/
-
-Set<out BitArray s> (. BitArray s2; .)
-=
- SimSet<out s>
- { '+' SimSet<out s2> (. s.Or(s2); .)
- | '-' SimSet<out s2> (. Sets.Subtract(s, s2); .)
- }
-.
-
-/*------------------------------------------------------------------------------------*/
-
-SimSet<out BitArray s> (. int n1, n2; .)
-= (. s = new BitArray(CharClass.charSetSize); .)
-( ident (. CharClass c = CharClass.Find(t.val);
- if (c == null) SemErr("undefined name"); else s.Or(c.set);
- .)
-| string (. string name = t.val;
- name = DFA.Unescape(name.Substring(1, name.Length-2));
- foreach (char ch in name) s[ch] = true;
- .)
-| Char<out n1> (. s[n1] = true; .)
- [ ".." Char<out n2> (. for (int i = n1; i <= n2; i++) s[i] = true; .)
- ]
-| "ANY" (. s = new BitArray(CharClass.charSetSize, true);
- s[0] = false;
- .)
-)
-.
-
-/*--------------------------------------------------------------------------------------*/
-
-Char<out int n>
-=
- char (. string name = t.val;
- name = DFA.Unescape(name.Substring(1, name.Length-2));
- int max = CharClass.charSetSize;
- if (name.Length != 1 || name[0] > max-1) SemErr("unacceptable character value");
- n = name[0] % max;
- .)
-.
-
-/*------------------------------------------------------------------------------------*/
-
-TokenDecl<int typ> (. string name; int kind; Symbol sym; Graph g; .)
-=
- Sym<out name, out kind> (. sym = Symbol.Find(name);
- if (sym != null) SemErr("name declared twice");
- else {
- sym = new Symbol(typ, name, t.line);
- sym.tokenKind = Symbol.classToken;
- }
- .)
- SYNC
- ( '=' TokenExpr<out g> '.' (. if (kind != id) SemErr("a literal must not be declared with a structure");
- Graph.Finish(g);
- DFA.ConvertToStates(g.l, sym);
- .)
- | '.' (. if (typ != Node.rslv) SemErr("resolver is only allowed in RESOLVERS section"); .) /* ML-AW */
- | (. if (kind == id) genScanner = false;
- else DFA.MatchLiteral(sym);
- .)
- )
- ( SemText<out sym.semPos> (. if (typ == Node.t) SemErr("semantic action not allowed here"); .)
- | (. if (typ == Node.rslv) SemErr("resolvers must have a semantic action"); .) /* ML-AW */
- )
-.
-
-/*------------------------------------------------------------------------------------*/
-
-AttrDecl<Symbol sym>
-=
- '<' (. int beg = la.pos; int col = la.col; .)
- { ANY
- | badString (. SemErr("bad string in semantic action"); .)
- }
- '>' (. sym.attrPos = new Position(beg, t.pos - beg, col); .)
-.
-
-/*------------------------------------------------------------------------------------*/
-
-Expression<out Graph g> (. Graph g2; .)
-=
- Term<out g> (. bool first = true; .)
- { WEAK
- '|'
- Term<out g2> (. if (first) { Graph.MakeFirstAlt(g); first = false; }
- Graph.MakeAlternative(g, g2);
- .)
- }
-.
-
-/*------------------------------------------------------------------------------------*/
-
-Term<out Graph g> (. Graph g2; Position pos; Node rslv = null;
- g = null;
- .)
-= [ (. rslv = new Node(Node.rslv, null, la.line); .)
- ResolveExpr<out pos> (. rslv.pos = pos;
- g = new Graph(rslv);
- .)
- ]
- Factor<out g2> (. if (rslv != null) Graph.MakeSequence(g, g2);
- else g = g2;
- .)
- { Factor<out g2> (. Graph.MakeSequence(g, g2); .)
- }
-| (. g = new Graph(new Node(Node.eps, null, 0)); .)
-.
-
-/*------------------------------------------------------------------------------------*/
-
-Factor<out Graph g> (. string name; int kind; Position pos; bool weak = false;
- g = null;
- .)
-= [ "WEAK" (. weak = true; .)
- ]
- Sym<out name, out kind> (. Symbol sym = Symbol.Find(name);
- bool undef = sym == null;
- if (undef) {
- if (kind == id)
- sym = new Symbol(Node.nt, name, 0); // forward nt
- else if (genScanner) {
- sym = new Symbol(Node.t, name, t.line);
- DFA.MatchLiteral(sym);
- } else { // undefined string in production
- SemErr("undefined string in production");
- sym = Tab.eofSy; // dummy
- }
- }
- int typ = sym.typ;
- if (typ != Node.t && typ != Node.nt && typ != Node.rslv) /* ML */
- SemErr("this symbol kind is not allowed in a production");
- if (weak)
- if (typ == Node.t) typ = Node.wt;
- else SemErr("only terminals may be weak");
- Node p = new Node(typ, sym, t.line);
- g = new Graph(p);
- .)
- [ Attribs<p> (. if (kind != id) SemErr("a literal must not have attributes"); .)
- ] (. if (undef)
- sym.attrPos = p.pos; // dummy
- else if ((p.pos == null) != (sym.attrPos == null))
- SemErr("attribute mismatch between declaration and use of this symbol");
- .)
-| '(' Expression<out g> ')'
-| '[' Expression<out g> ']' (. Graph.MakeOption(g); .)
-| '{' Expression<out g> '}' (. Graph.MakeIteration(g); .)
-| SemText<out pos> (. Node p = new Node(Node.sem, null, 0);
- p.pos = pos;
- g = new Graph(p);
- .)
-| "ANY" (. Node p = new Node(Node.any, null, 0); // p.set is set in Tab.SetupAnys
- g = new Graph(p);
- .)
-| "SYNC" (. Node p = new Node(Node.sync, null, 0);
- g = new Graph(p);
- .)
-.
-
-/*------------------------------------------------------------------------------------*/
-
-ResolveExpr<out Position pos>
-=
- "IF" "(" (. int beg = la.pos; int col = la.col; .)
- ( ("=" | "!=") CondPart /* indicate the beginning of a syntax snippet.
- The condition is true if the actual input matches
- the given syntax snippet (or does not match for "!=")
- */
- | "(" CondPart ")"
- | ANY CondPart
- ) (. pos = new Position(beg, t.pos - beg, col); .)
-.
-
-/* ConPart exists to guarantee an equal number of opening and *
- * closing parentheses inside the conditional expression. */
-CondPart = { "(" CondPart | ANY } ")" .
-
-/*------------------------------------------------------------------------------------*/
-
-TokenExpr<out Graph g> (. Graph g2; .)
-=
- TokenTerm<out g> (. bool first = true; .)
- { WEAK
- '|'
- TokenTerm<out g2> (. if (first) { Graph.MakeFirstAlt(g); first = false; }
- Graph.MakeAlternative(g, g2);
- .)
- }
-.
-
-/*------------------------------------------------------------------------------------*/
-
-TokenTerm<out Graph g> (. Graph g2; .)
-=
- TokenFactor<out g>
- { TokenFactor<out g2> (. Graph.MakeSequence(g, g2); .)
- }
- [ "CONTEXT"
- '(' TokenExpr<out g2> (. Graph.SetContextTrans(g2.l); Graph.MakeSequence(g, g2); .)
- ')'
- ]
-.
-
-/*------------------------------------------------------------------------------------*/
-
-TokenFactor<out Graph g> (. string name; int kind; .)
-=
- (. g = new Graph(); .)
-( Sym<out name, out kind> (. if (kind == id) {
- CharClass c = CharClass.Find(name);
- if (c == null) {
- SemErr("undefined name");
- c = new CharClass(name, new BitArray(CharClass.charSetSize));
- }
- Node p = new Node(Node.clas, null, 0); p.val = c.n;
- g = new Graph(p);
- } else g = Graph.StrToGraph(name); // str
- .)
-| '(' TokenExpr<out g> ')'
-| '[' TokenExpr<out g> ']' (. Graph.MakeOption(g); .)
-| '{' TokenExpr<out g> '}' (. Graph.MakeIteration(g); .)
-)
-.
-
-/*------------------------------------------------------------------------------------*/
-
-Sym<out string name, out int kind>
-= (. name = "???"; kind = id; .)
-( ident (. kind = id; name = t.val; .)
-| (string (. name = t.val; .)
- | char (. name = "\"" + t.val.Substring(1, t.val.Length-2) + "\""; .)
- ) (. kind = str; .)
-)
-.
-
-/*------------------------------------------------------------------------------------*/
-
-Attribs<Node p>
-=
- '<' (. int beg = la.pos; int col = la.col; .)
- { ANY
- | badString (. SemErr("bad string in attributes"); .)
- }
- '>' (. p.pos = new Position(beg, t.pos - beg, col); .)
-.
-
-/*------------------------------------------------------------------------------------*/
-
-SemText<out Position pos>
-=
- "(." (. int beg = la.pos; int col = la.col; .)
- { ANY
- | badString (. SemErr("bad string in semantic action"); .)
- | "(." (. SemErr("missing end of previous semantic action"); .)
- }
- ".)" (. pos = new Position(beg, t.pos - beg, col); .)
-.
-
-/*------------------------------------------------------------------------------------*/
-
-UsingDecl<out Position pos>
-=
- "using" (. int beg = t.pos; .)
- { ANY } ';' (. int end = t.pos; .)
- { "using" { ANY } ';' (. end = t.pos; .)
- } (. pos = new Position(beg, end - beg + 1, 0); .)
-.
-
-END Coco.
+/* ------------------------------------------------------------------------
+ * Coco.ATG
+ * Attributed grammer of Coco/R
+ * by H. Moessenboeck, Univ. of Linz
+ * extended by
+ * M. Loeberbauer & A. Woess, Univ. of Linz
+ * ------------------------------------------------------------------------*/
+
+using System.Collections;
+using System.Text;
+
+COMPILER Coco
+
+ const int id = 0;
+ const int str = 1;
+
+ static bool genScanner;
+
+/*-------------------------------------------------------------------------*/
+
+CHARACTERS
+ letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".
+ digit = "0123456789".
+ cr = '\r'.
+ lf = '\n'.
+ tab = '\t'.
+ stringCh = ANY - '"' - '\\' - cr - lf.
+ charCh = ANY - '\'' - '\\' - cr - lf.
+ printable = '\u0020' .. '\u007e'.
+ hex = "0123456789abcdef".
+
+IGNORE cr + lf + tab
+
+TOKENS
+ ident = letter { letter | digit }.
+ number = digit { digit }.
+ string = '"' { stringCh | '\\' printable } '"'.
+ badString = '"' { stringCh | '\\' printable } (cr | lf).
+ char = '\'' ( charCh | '\\' printable { hex } ) '\''.
+
+PRAGMAS
+ ddtSym = '$' { digit | letter }. (. Tab.SetDDT(la.val); .)
+
+COMMENTS FROM "/*" TO "*/" NESTED
+
+/*-------------------------------------------------------------------------*/
+
+PRODUCTIONS
+
+Coco (. Symbol sym; Graph g; string gramName; .)
+=
+ [ UsingDecl<out ParserGen.usingPos> ]
+
+ "COMPILER" (. int gramLine = t.line;
+ genScanner = true;
+ bool ok = true;
+ Tab.ignored = null;
+ .)
+ ident (. gramName = t.val;
+ int beg = la.pos;
+ .)
+ { ANY } (. Tab.semDeclPos = new Position(beg, la.pos-beg, 0); .)
+ { Declaration }
+ SYNC
+ "PRODUCTIONS" (. if (genScanner) DFA.MakeDeterministic();
+ Graph.DeleteNodes();
+ .)
+ { ident (. sym = Symbol.Find(t.val);
+ bool undef = sym == null;
+ if (undef) sym = new Symbol(Node.nt, t.val, t.line);
+ else {
+ if (sym.typ == Node.nt) {
+ if (sym.graph != null) SemErr("name declared twice");
+ } else SemErr("this symbol kind not allowed on left side of production");
+ sym.line = t.line;
+ }
+ bool noAttrs = sym.attrPos == null;
+ sym.attrPos = null;
+ .)
+ [ AttrDecl<sym> ] (. if (!undef)
+ if (noAttrs != (sym.attrPos == null))
+ SemErr("attribute mismatch between declaration and use of this symbol");
+ .)
+ [ SemText<out sym.semPos> ] WEAK
+ '='
+ Expression<out g> (. sym.graph = g.l;
+ Graph.Finish(g);
+ .)
+ WEAK
+ '.'
+ }
+ "END" ident (. if (gramName != t.val)
+ SemErr("name does not match grammar name");
+ Tab.gramSy = Symbol.Find(gramName);
+ if (Tab.gramSy == null)
+ SemErr("missing production for grammar name");
+ else {
+ sym = Tab.gramSy;
+ if (sym.attrPos != null)
+ SemErr("grammar symbol must not have attributes");
+ }
+ Tab.noSym = new Symbol(Node.t, "???", 0); // noSym gets highest number
+ Tab.SetupAnys();
+ Tab.RenumberPragmas();
+ if (Tab.ddt[2]) Node.PrintNodes();
+ if (Errors.count == 0) {
+ Console.WriteLine("checking");
+ Tab.CompSymbolSets();
+ ok = ok && Tab.GrammarOk();
+ if (Tab.ddt[7]) Tab.XRef();
+ if (ok) {
+ Console.Write("parser");
+ ParserGen.WriteParser();
+ if (genScanner) {
+ Console.Write(" + scanner");
+ DFA.WriteScanner();
+ if (Tab.ddt[0]) DFA.PrintStates();
+ }
+ Console.WriteLine(" generated");
+ if (Tab.ddt[8]) ParserGen.WriteStatistics();
+ }
+ }
+ if (Tab.ddt[6]) Tab.PrintSymbolTable();
+ .)
+ '.'
+.
+
+/*------------------------------------------------------------------------------------*/
+
+Declaration (. Graph g1, g2; bool nested = false; .)
+=
+ "CHARACTERS" { SetDecl }
+| "TOKENS" { TokenDecl<Node.t> }
+| "PRAGMAS" { TokenDecl<Node.pr> }
+| "COMMENTS"
+ "FROM" TokenExpr<out g1>
+ "TO" TokenExpr<out g2>
+ ( "NESTED" (. nested = true; .)
+ | (. nested = false; .)
+ ) (. new Comment(g1.l, g2.l, nested); .)
+| "IGNORE" Set<out Tab.ignored> (. Tab.ignored[' '] = true; /* ' ' is always ignored */
+ if (Tab.ignored[0]) SemErr("may not ignore \'\\0\'"); .)
+| "TOKENNAMES" (. Symbol.tokenNames = new Hashtable(); .)
+ { ( string | ident ) (. string key = t.val; .)
+ "=" ident (. string val = t.val; Symbol.tokenNames.Add(key, val); .)
+ }
+.
+
+/*------------------------------------------------------------------------------------*/
+
+SetDecl (. BitArray s; .)
+=
+ ident (. string name = t.val;
+ CharClass c = CharClass.Find(name);
+ if (c != null) SemErr("name declared twice");
+ .)
+ '=' Set<out s> (. if (Sets.Elements(s) == 0) SemErr("character set must not be empty");
+ c = new CharClass(name, s);
+ .)
+ '.'
+.
+
+/*------------------------------------------------------------------------------------*/
+
+Set<out BitArray s> (. BitArray s2; .)
+=
+ SimSet<out s>
+ { '+' SimSet<out s2> (. s.Or(s2); .)
+ | '-' SimSet<out s2> (. Sets.Subtract(s, s2); .)
+ }
+.
+
+/*------------------------------------------------------------------------------------*/
+
+SimSet<out BitArray s> (. int n1, n2; .)
+= (. s = new BitArray(CharClass.charSetSize); .)
+( ident (. CharClass c = CharClass.Find(t.val);
+ if (c == null) SemErr("undefined name"); else s.Or(c.set);
+ .)
+| string (. string name = t.val;
+ name = DFA.Unescape(name.Substring(1, name.Length-2));
+ foreach (char ch in name) s[ch] = true;
+ .)
+| Char<out n1> (. s[n1] = true; .)
+ [ ".." Char<out n2> (. for (int i = n1; i <= n2; i++) s[i] = true; .)
+ ]
+| "ANY" (. s = new BitArray(CharClass.charSetSize, true);
+ s[0] = false;
+ .)
+)
+.
+
+/*--------------------------------------------------------------------------------------*/
+
+Char<out int n>
+=
+ char (. string name = t.val;
+ name = DFA.Unescape(name.Substring(1, name.Length-2));
+ int max = CharClass.charSetSize;
+ if (name.Length != 1 || name[0] > max-1) SemErr("unacceptable character value");
+ n = name[0] % max;
+ .)
+.
+
+/*------------------------------------------------------------------------------------*/
+
+TokenDecl<int typ> (. string name; int kind; Symbol sym; Graph g; .)
+=
+ Sym<out name, out kind> (. sym = Symbol.Find(name);
+ if (sym != null) SemErr("name declared twice");
+ else {
+ sym = new Symbol(typ, name, t.line);
+ sym.tokenKind = Symbol.classToken;
+ }
+ .)
+ SYNC
+ ( '=' TokenExpr<out g> '.' (. if (kind != id) SemErr("a literal must not be declared with a structure");
+ Graph.Finish(g);
+ DFA.ConvertToStates(g.l, sym);
+ .)
+ | '.' (. if (typ != Node.rslv) SemErr("resolver is only allowed in RESOLVERS section"); .) /* ML-AW */
+ | (. if (kind == id) genScanner = false;
+ else DFA.MatchLiteral(sym);
+ .)
+ )
+ ( SemText<out sym.semPos> (. if (typ == Node.t) SemErr("semantic action not allowed here"); .)
+ | (. if (typ == Node.rslv) SemErr("resolvers must have a semantic action"); .) /* ML-AW */
+ )
+.
+
+/*------------------------------------------------------------------------------------*/
+
+AttrDecl<Symbol sym>
+=
+ '<' (. int beg = la.pos; int col = la.col; .)
+ { ANY
+ | badString (. SemErr("bad string in semantic action"); .)
+ }
+ '>' (. sym.attrPos = new Position(beg, t.pos - beg, col); .)
+.
+
+/*------------------------------------------------------------------------------------*/
+
+Expression<out Graph g> (. Graph g2; .)
+=
+ Term<out g> (. bool first = true; .)
+ { WEAK
+ '|'
+ Term<out g2> (. if (first) { Graph.MakeFirstAlt(g); first = false; }
+ Graph.MakeAlternative(g, g2);
+ .)
+ }
+.
+
+/*------------------------------------------------------------------------------------*/
+
+Term<out Graph g> (. Graph g2; Position pos; Node rslv = null;
+ g = null;
+ .)
+= [ (. rslv = new Node(Node.rslv, null, la.line); .)
+ ResolveExpr<out pos> (. rslv.pos = pos;
+ g = new Graph(rslv);
+ .)
+ ]
+ Factor<out g2> (. if (rslv != null) Graph.MakeSequence(g, g2);
+ else g = g2;
+ .)
+ { Factor<out g2> (. Graph.MakeSequence(g, g2); .)
+ }
+| (. g = new Graph(new Node(Node.eps, null, 0)); .)
+.
+
+/*------------------------------------------------------------------------------------*/
+
+Factor<out Graph g> (. string name; int kind; Position pos; bool weak = false;
+ g = null;
+ .)
+= [ "WEAK" (. weak = true; .)
+ ]
+ Sym<out name, out kind> (. Symbol sym = Symbol.Find(name);
+ bool undef = sym == null;
+ if (undef) {
+ if (kind == id)
+ sym = new Symbol(Node.nt, name, 0); // forward nt
+ else if (genScanner) {
+ sym = new Symbol(Node.t, name, t.line);
+ DFA.MatchLiteral(sym);
+ } else { // undefined string in production
+ SemErr("undefined string in production");
+ sym = Tab.eofSy; // dummy
+ }
+ }
+ int typ = sym.typ;
+ if (typ != Node.t && typ != Node.nt && typ != Node.rslv) /* ML */
+ SemErr("this symbol kind is not allowed in a production");
+ if (weak)
+ if (typ == Node.t) typ = Node.wt;
+ else SemErr("only terminals may be weak");
+ Node p = new Node(typ, sym, t.line);
+ g = new Graph(p);
+ .)
+ [ Attribs<p> (. if (kind != id) SemErr("a literal must not have attributes"); .)
+ ] (. if (undef)
+ sym.attrPos = p.pos; // dummy
+ else if ((p.pos == null) != (sym.attrPos == null))
+ SemErr("attribute mismatch between declaration and use of this symbol");
+ .)
+| '(' Expression<out g> ')'
+| '[' Expression<out g> ']' (. Graph.MakeOption(g); .)
+| '{' Expression<out g> '}' (. Graph.MakeIteration(g); .)
+| SemText<out pos> (. Node p = new Node(Node.sem, null, 0);
+ p.pos = pos;
+ g = new Graph(p);
+ .)
+| "ANY" (. Node p = new Node(Node.any, null, 0); // p.set is set in Tab.SetupAnys
+ g = new Graph(p);
+ .)
+| "SYNC" (. Node p = new Node(Node.sync, null, 0);
+ g = new Graph(p);
+ .)
+.
+
+/*------------------------------------------------------------------------------------*/
+
+ResolveExpr<out Position pos>
+=
+ "IF" "(" (. int beg = la.pos; int col = la.col; .)
+ ( ("=" | "!=") CondPart /* indicate the beginning of a syntax snippet.
+ The condition is true if the actual input matches
+ the given syntax snippet (or does not match for "!=")
+ */
+ | "(" CondPart ")"
+ | ANY CondPart
+ ) (. pos = new Position(beg, t.pos - beg, col); .)
+.
+
+/* ConPart exists to guarantee an equal number of opening and *
+ * closing parentheses inside the conditional expression. */
+CondPart = { "(" CondPart | ANY } ")" .
+
+/*------------------------------------------------------------------------------------*/
+
+TokenExpr<out Graph g> (. Graph g2; .)
+=
+ TokenTerm<out g> (. bool first = true; .)
+ { WEAK
+ '|'
+ TokenTerm<out g2> (. if (first) { Graph.MakeFirstAlt(g); first = false; }
+ Graph.MakeAlternative(g, g2);
+ .)
+ }
+.
+
+/*------------------------------------------------------------------------------------*/
+
+TokenTerm<out Graph g> (. Graph g2; .)
+=
+ TokenFactor<out g>
+ { TokenFactor<out g2> (. Graph.MakeSequence(g, g2); .)
+ }
+ [ "CONTEXT"
+ '(' TokenExpr<out g2> (. Graph.SetContextTrans(g2.l); Graph.MakeSequence(g, g2); .)
+ ')'
+ ]
+.
+
+/*------------------------------------------------------------------------------------*/
+
+TokenFactor<out Graph g> (. string name; int kind; .)
+=
+ (. g = new Graph(); .)
+( Sym<out name, out kind> (. if (kind == id) {
+ CharClass c = CharClass.Find(name);
+ if (c == null) {
+ SemErr("undefined name");
+ c = new CharClass(name, new BitArray(CharClass.charSetSize));
+ }
+ Node p = new Node(Node.clas, null, 0); p.val = c.n;
+ g = new Graph(p);
+ } else g = Graph.StrToGraph(name); // str
+ .)
+| '(' TokenExpr<out g> ')'
+| '[' TokenExpr<out g> ']' (. Graph.MakeOption(g); .)
+| '{' TokenExpr<out g> '}' (. Graph.MakeIteration(g); .)
+)
+.
+
+/*------------------------------------------------------------------------------------*/
+
+Sym<out string name, out int kind>
+= (. name = "???"; kind = id; .)
+( ident (. kind = id; name = t.val; .)
+| (string (. name = t.val; .)
+ | char (. name = "\"" + t.val.Substring(1, t.val.Length-2) + "\""; .)
+ ) (. kind = str; .)
+)
+.
+
+/*------------------------------------------------------------------------------------*/
+
+Attribs<Node p>
+=
+ '<' (. int beg = la.pos; int col = la.col; .)
+ { ANY
+ | badString (. SemErr("bad string in attributes"); .)
+ }
+ '>' (. p.pos = new Position(beg, t.pos - beg, col); .)
+.
+
+/*------------------------------------------------------------------------------------*/
+
+SemText<out Position pos>
+=
+ "(." (. int beg = la.pos; int col = la.col; .)
+ { ANY
+ | badString (. SemErr("bad string in semantic action"); .)
+ | "(." (. SemErr("missing end of previous semantic action"); .)
+ }
+ ".)" (. pos = new Position(beg, t.pos - beg, col); .)
+.
+
+/*------------------------------------------------------------------------------------*/
+
+UsingDecl<out Position pos>
+=
+ "using" (. int beg = t.pos; .)
+ { ANY } ';' (. int end = t.pos; .)
+ { "using" { ANY } ';' (. end = t.pos; .)
+ } (. pos = new Position(beg, end - beg + 1, 0); .)
+.
+
+END Coco.
Modified: trunk/MonoDevelop/src/Tools/SharpCoco/src/Coco.cs
===================================================================
--- trunk/MonoDevelop/src/Tools/SharpCoco/src/Coco.cs 2004-04-09 12:41:44 UTC (rev 1420)
+++ trunk/MonoDevelop/src/Tools/SharpCoco/src/Coco.cs 2004-04-09 17:17:47 UTC (rev 1421)
@@ -1,71 +1,71 @@
-/*-------------------------------------------------------------------------
- Trace output options
- 0 | A: prints the states of the scanner automaton
- 1 | F: prints the First and Follow sets of all nonterminals
- 2 | G: prints the syntax graph of the productions
- 3 | I: traces the computation of the First sets
- 4 | J: prints the sets associated with ANYs and synchronisation sets
- 6 | S: prints the symbol table (terminals, nonterminals, pragmas)
- 7 | X: prints a cross reference list of all syntax symbols
- 8 | P: prints statistics about the Coco run
-
- Trace output can be switched on by the pragma
- $ { digit | letter }
- in the attributed grammar or as a command-line option
- -------------------------------------------------------------------------*/
-
-using System;
-using System.IO;
-
-namespace at.jku.ssw.Coco {
-
-public class Coco {
-
- public static void Main (string[] arg) {
- Console.WriteLine("Coco/R (Aug 4, 2003)");
- string ATGName = null;
- for (int i = 0; i < arg.Length; i++) {
- if (arg[i] == "-nonamespace") Tab.nsName = null;
- else if (arg[i] == "-namespace") Tab.nsName = arg[++i];
- else if (arg[i] == "-trace") Tab.SetDDT(arg[++i]);
- else ATGName = arg[i];
- }
- if (arg.Length > 0 && ATGName != null) {
- int pos = ATGName.LastIndexOf('/');
- if (pos < 0) pos = ATGName.LastIndexOf('\\');
- string file = ATGName;
- string dir = ATGName.Substring(0, pos+1);
-
- Scanner.Init(file);
- Trace.Init(dir);
- Tab.Init();
- DFA.Init(dir);
- ParserGen.Init(file, dir);
-
- Parser.Parse();
-
- Trace.Close();
- Console.WriteLine();
- Console.WriteLine("{0} errors detected", Errors.count);
- } else {
- Console.WriteLine("Usage: Coco {{Option}} Grammar.ATG {{Option}}{0}" +
- "Options:{0}" +
- " -nonamespace{0}" +
- " -namespace <packageName>{0}" +
- " -trace <traceString>{0}" +
- "Valid characters in the trace string:{0}" +
- " A trace automaton{0}" +
- " F list first/follow sets{0}" +
- " G print syntax graph{0}" +
- " I trace computation of first sets{0}" +
- " P print statistics{0}" +
- " S list symbol table{0}" +
- " X list cross reference table{0}" +
- "Scanner.frame and Parser.frame files needed in ATG directory{0}" +
- "or in a directory referenced by the environment variable CRFRAMES.",
- Environment.NewLine);
- }
- }
-} // end Coco
-
-} // end namespace
+/*-------------------------------------------------------------------------
+ Trace output options
+ 0 | A: prints the states of the scanner automaton
+ 1 | F: prints the First and Follow sets of all nonterminals
+ 2 | G: prints the syntax graph of the productions
+ 3 | I: traces the computation of the First sets
+ 4 | J: prints the sets associated with ANYs and synchronisation sets
+ 6 | S: prints the symbol table (terminals, nonterminals, pragmas)
+ 7 | X: prints a cross reference list of all syntax symbols
+ 8 | P: prints statistics about the Coco run
+
+ Trace output can be switched on by the pragma
+ $ { digit | letter }
+ in the attributed grammar or as a command-line option
+ -------------------------------------------------------------------------*/
+
+using System;
+using System.IO;
+
+namespace at.jku.ssw.Coco {
+
+public class Coco {
+
+ public static void Main (string[] arg) {
+ Console.WriteLine("Coco/R (Aug 4, 2003)");
+ string ATGName = null;
+ for (int i = 0; i < arg.Length; i++) {
+ if (arg[i] == "-nonamespace") Tab.nsName = null;
+ else if (arg[i] == "-namespace") Tab.nsName = arg[++i];
+ else if (arg[i] == "-trace") Tab.SetDDT(arg[++i]);
+ else ATGName = arg[i];
+ }
+ if (arg.Length > 0 && ATGName != null) {
+ int pos = ATGName.LastIndexOf('/');
+ if (pos < 0) pos = ATGName.LastIndexOf('\\');
+ string file = ATGName;
+ string dir = ATGName.Substring(0, pos+1);
+
+ Scanner.Init(file);
+ Trace.Init(dir);
+ Tab.Init();
+ DFA.Init(dir);
+ ParserGen.Init(file, dir);
+
+ Parser.Parse();
+
+ Trace.Close();
+ Console.WriteLine();
+ Console.WriteLine("{0} errors detected", Errors.count);
+ } else {
+ Console.WriteLine("Usage: Coco {{Option}} Grammar.ATG {{Option}}{0}" +
+ "Options:{0}" +
+ " -nonamespace{0}" +
+ " -namespace <packageName>{0}" +
+ " -trace <traceString>{0}" +
+ "Valid characters in the trace string:{0}" +
+ " A trace automaton{0}" +
+ " F list first/follow sets{0}" +
+ " G print syntax graph{0}" +
+ " I trace computation of first sets{0}" +
+ " P print statistics{0}" +
+ " S list symbol table{0}" +
+ " X list cross reference table{0}" +
+ "Scanner.frame and Parser.frame files needed in ATG directory{0}" +
+ "or in a directory referenced by the environment variable CRFRAMES.",
+ Environment.NewLine);
+ }
+ }
+} // end Coco
+
+} // end namespace
Modified: trunk/MonoDevelop/src/Tools/SharpCoco/src/DFA.cs
===================================================================
--- trunk/MonoDevelop/src/Tools/SharpCoco/src/DFA.cs 2004-04-09 12:41:44 UTC (rev 1420)
+++ trunk/MonoDevelop/src/Tools/SharpCoco/src/DFA.cs 2004-04-09 17:17:47 UTC (rev 1421)
@@ -1,889 +1,889 @@
-// DFA.cs Scaner automaton gnerated by Coco/R H.Moessenboeck, Univ. of Linz
-//----------------------------------------------------------------------------
-using System;
-using System.IO;
-using System.Collections;
-using System.Text;
-
-namespace at.jku.ssw.Coco {
-
-//-----------------------------------------------------------------------------
-// State
-//-----------------------------------------------------------------------------
-
-public class State { // state of finite automaton
- public static int lastNr; // highest state number
- public int nr; // state number
- public Action firstAction;// to first action of this state
- public Symbol endOf; // recognized token if state is final
- public bool ctx; // true if state is reached via contextTrans
- public State next;
-
- public State() {
- nr = ++lastNr;
- }
-
- public void AddAction(Action act) {
- Action lasta = null, a = firstAction;
- while (a != null && act.typ >= a.typ) {lasta = a; a = a.next;}
- // collecting classes at the beginning gives better performance
- act.next = a;
- if (a==firstAction) firstAction = act; else lasta.next = act;
- }
-
- public void DetachAction(Action act) {
- Action lasta = null, a = firstAction;
- while (a != null && a != act) {lasta = a; a = a.next;}
- if (a != null)
- if (a == firstAction) firstAction = a.next; else lasta.next = a.next;
- }
-
- public Action TheAction(char ch) {
- BitArray s;
- for (Action a = firstAction; a != null; a = a.next)
- if (a.typ == Node.chr && ch == a.sym) return a;
- else if (a.typ == Node.clas) {
- s = CharClass.Set(a.sym);
- if (s[ch]) return a;
- }
- return null;
- }
-
- public void MeltWith(State s) { // copy actions of s to state
- Action a;
- for (Action action = s.firstAction; action != null; action = action.next) {
- a = new Action(action.typ, action.sym, action.tc);
- a.AddTargets(action);
- AddAction(a);
- }
- }
-
-}
-
-//-----------------------------------------------------------------------------
-// Action
-//-----------------------------------------------------------------------------
-
-public class Action { // action of finite automaton
- public int typ; // type of action symbol: clas, chr
- public int sym; // action symbol
- public int tc; // transition code: normalTrans, contextTrans
- public Target target; // states reached from this action
- public Action next;
-
- public Action(int typ, int sym, int tc) {
- this.typ = typ; this.sym = sym; this.tc = tc;
- }
-
- public void AddTarget(Target t) { // add t to the action.targets
- Target last = null;
- Target p = target;
- while (p != null && t.state.nr >= p.state.nr) {
- if (t.state == p.state) return;
- last = p; p = p.next;
- }
- t.next = p;
- if (p == target) target = t; else last.next = t;
- }
-
- public void AddTargets(Action a) { // add copy of a.targets to action.targets
- for (Target p = a.target; p != null; p = p.next) {
- Target t = new Target(p.state);
- AddTarget(t);
- }
- if (a.tc == Node.contextTrans) tc = Node.contextTrans;
- }
-
- public BitArray Symbols() {
- BitArray s;
- if (typ == Node.clas)
- s = (BitArray) CharClass.Set(sym).Clone();
- else {
- s = new BitArray(CharClass.charSetSize); s[sym] = true;
- }
- return s;
- }
-
- public void ShiftWith(BitArray s) {
- if (Sets.Elements(s) == 1) {
- typ = Node.chr; sym = Sets.First(s);
- } else {
- CharClass c = CharClass.Find(s);
- if (c == null) c = new CharClass("#", s); // class with dummy name
- typ = Node.clas; sym = c.n;
- }
- }
-
- public void GetTargetStates(out BitArray targets, out Symbol endOf, out bool ctx) {
- // compute the set of target states
- targets = new BitArray(DFA.maxStates); endOf = null;
- ctx = false;
- for (Target t = target; t != null; t = t.next) {
- int stateNr = t.state.nr;
- if (stateNr <= DFA.lastSimState) targets[stateNr] = true;
- else targets.Or(Melted.Set(stateNr));
- if (t.state.endOf != null)
- if (endOf == null || endOf == t.state.endOf)
- endOf = t.state.endOf;
- else {
- Console.WriteLine("Tokens {0} and {1} cannot be distinguished", endOf.name, t.state.endOf.name);
- Errors.count++;
- }
- if (t.state.ctx) {
- ctx = true;
- // The following check seems to be unnecessary. It reported an error
- // if a symbol + context was the prefix of another symbol, e.g.
- // s1 = "a" "b" "c".
- // s2 = "a" CONTEXT("b").
- // But this is ok.
- // if (t.state.endOf != null) {
- // Console.WriteLine("Ambiguous context clause");
- // Errors.count++;
- // }
- }
- }
- }
-
-}
-
-//-----------------------------------------------------------------------------
-// Target
-//-----------------------------------------------------------------------------
-
-public class Target { // set of states that are reached by an action
- public State state; // target state
- public Target next;
-
- public Target (State s) {
- state = s;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Melted
-//-----------------------------------------------------------------------------
-
-public class Melted { // info about melted states
- public static Melted first; // head of melted state list
- public BitArray set; // set of old states
- public State state; // new state
- public Melted next;
-
- public Melted(BitArray set, State state) {
- this.set = set; this.state = state;
- this.next = first; first = this;
- }
-
- public static BitArray Set(int nr) {
- Melted m = first;
- while (m != null) {
- if (m.state.nr == nr) return m.set; else m = m.next;
- }
- throw new Exception("-- compiler error in Melted.Set");
- }
-
- public static Melted StateWithSet(BitArray s) {
- for (Melted m = first; m != null; m = m.next)
- if (Sets.Equals(s, m.set)) return m;
- return null;
- }
-
-}
-
-//-----------------------------------------------------------------------------
-// Comment
-//-----------------------------------------------------------------------------
-
-public class Comment { // info about comment syntax
- public static Comment first; // list of comments
- public string start;
- public string stop;
- public bool nested;
- public Comment next;
-
- static string Str(Node p) {
- StringBuilder s = new StringBuilder();
- while (p != null) {
- if (p.typ == Node.chr) {
- s.Append((char)p.val);
- } else if (p.typ == Node.clas) {
- BitArray set = CharClass.Set(p.val);
- if (Sets.Elements(set) != 1) Parser.SemErr("character set contains more than 1 character");
- s.Append((char)Sets.First(set));
- } else Parser.SemErr("comment delimiters may not be structured");
- p = p.next;
- }
- if (s.Length == 0 || s.Length > 2) {
- Parser.SemErr("comment delimiters must be 1 or 2 characters long");
- s = new StringBuilder("?");
- }
- return s.ToString();
- }
-
- public Comment(Node from, Node to, bool nested) {
- start = Str(from);
- stop = Str(to);
- this.nested = nested;
- this.next = first; first = this;
- }
-
-}
-
-//-----------------------------------------------------------------------------
-// DFA
-//-----------------------------------------------------------------------------
-
-public class DFA {
- public static int maxStates;
- public const int EOF = -1;
- public const char CR = '\r';
- public const char LF = '\n';
-
- public static State firstState;
- public static State lastState; // last allocated state
- public static int lastSimState; // last non melted state
- public static FileStream fram; // scanner frame input
- public static StreamWriter gen; // generated scanner file
- static string srcDir; // directory of attributed grammar file
- public static Symbol curSy; // current token to be recognized (in FindTrans)
- public static Node curGraph; // start of graph for current token (in FindTrans)
- public static bool dirtyDFA; // DFA may become nondeterministic in MatchedDFA
- public static bool hasCtxMoves; // DFA has context transitions
-
- //---------- Output primitives
- private static string Ch(char ch) {
- if (ch < ' ' || ch >= 127 || ch == '\'' || ch == '\\') return Convert.ToString((int)ch);
- else return String.Format("'{0}'", ch);
- }
-
- private static string ChCond(char ch) {
- return String.Format("ch == {0}", Ch(ch));
- }
-
- private static void PutRange(BitArray s) {
- int[] lo = new int[32];
- int[] hi = new int[32];
- // fill lo and hi
- int max = CharClass.charSetSize;
- int top = -1;
- int i = 0;
- while (i < max) {
- if (s[i]) {
- top++; lo[top] = i; i++;
- while (i < max && s[i]) i++;
- hi[top] = i-1;
- } else i++;
- }
- // print ranges
- if (top == 1 && lo[0] == 0 && hi[1] == max-1 && hi[0]+2 == lo[1]) {
- BitArray s1 = new BitArray(max); s1[hi[0]+1] = true;
- gen.Write("!"); PutRange(s1);
- } else {
- gen.Write("(");
- for (i = 0; i <= top; i++) {
- if (hi[i] == lo[i]) gen.Write("ch == {0}", Ch((char)lo[i]));
- else if (lo[i] == 0) gen.Write("ch <= {0}", Ch((char)hi[i]));
- else if (hi[i] == max-1) gen.Write("ch >= {0}", Ch((char)lo[i]));
- else gen.Write("ch >= {0} && ch <= {1}", Ch((char)lo[i]), Ch((char)hi[i]));
- if (i < top) gen.Write(" || ");
- }
- gen.Write(")");
- }
- }
-
- //---------- String handling
- static char Hex2Char(string s) {
- int val = 0;
- for (int i = 0; i < s.Length; i++) {
- char ch = s[i];
- if ('0' <= ch && ch <= '9') val = 16 * val + (ch - '0');
- else if ('a' <= ch && ch <= 'f') val = 16 * val + (10 + ch - 'a');
- else if ('A' <= ch && ch <= 'Z') val = 16 * val + (10 + ch - 'A');
- else Parser.SemErr("bad escape sequence in string or character");
- }
- return (char)val;
- }
-
- static string Char2Hex(char ch) {
- StringWriter w = new StringWriter();
- w.Write("\\u{0:x4}", (int)ch);
- return w.ToString();
- }
-
- public static string Unescape (string s) {
- /* replaces escape sequences in s by their Unicode values. */
- StringBuilder buf = new StringBuilder();
- int i = 0;
- while (i < s.Length) {
- if (s[i] == '\\') {
- switch (s[i+1]) {
- case '\\': buf.Append('\\'); i += 2; break;
- case '\'': buf.Append('\''); i += 2; break;
- case '\"': buf.Append('\"'); i += 2; break;
- case 'r': buf.Append('\r'); i += 2; break;
- case 'n': buf.Append('\n'); i += 2; break;
- case 't': buf.Append('\t'); i += 2; break;
- case '0': buf.Append('\0'); i += 2; break;
- case 'a': buf.Append('\a'); i += 2; break;
- case 'b': buf.Append('\b'); i += 2; break;
- case 'f': buf.Append('\f'); i += 2; break;
- case 'v': buf.Append('\v'); i += 2; break;
- case 'u': case 'x':
- if (i + 6 <= s.Length) {
- buf.Append(Hex2Char(s.Substring(i+2, 4))); i += 6; break;
- } else {
- Parser.SemErr("bad escape sequence in string or character"); i = s.Length; break;
- }
- default: Parser.SemErr("bad escape sequence in string or character"); i += 2; break;
- }
- } else {
- buf.Append(s[i]);
- i++;
- }
- }
- return buf.ToString();
- }
-
- public static string Escape (string s) {
- StringBuilder buf = new StringBuilder();
- foreach (char ch in s) {
- if (ch == '\\') buf.Append("\\\\");
- else if (ch == '"') buf.Append("\\\"");
- else if (ch < ' ' || ch > '\u007f') buf.Append(Char2Hex(ch));
- else buf.Append(ch);
- }
- return buf.ToString();
- }
-
- //---------- State handling
- static State NewState() {
- State s = new State();
- if (firstState == null) firstState = s; else lastState.next = s;
- lastState = s;
- return s;
- }
-
- static void NewTransition(State from, State to, int typ, int sym, int tc) {
- if (to == firstState) Parser.SemErr("token must not start with an iteration");
- Target t = new Target(to);
- Action a = new Action(typ, sym, tc); a.target = t;
- from.AddAction(a);
- }
-
- static void CombineShifts() {
- State state;
- Action a, b, c;
- BitArray seta, setb;
- for (state = firstState; state != null; state = state.next) {
- for (a = state.firstAction; a != null; a = a.next) {
- b = a.next;
- while (b != null)
- if (a.target.state == b.target.state && a.tc == b.tc) {
- seta = a.Symbols(); setb = b.Symbols();
- seta.Or(setb);
- a.ShiftWith(seta);
- c = b; b = b.next; state.DetachAction(c);
- } else b = b.next;
- }
- }
- }
-
- static void FindUsedStates(State state, BitArray used) {
- if (used[state.nr]) return;
- used[state.nr] = true;
- for (Action a = state.firstAction; a != null; a = a.next)
- FindUsedStates(a.target.state, used);
- }
-
- static void DeleteRedundantStates() {
- State[] newState = new State[State.lastNr + 1];
- BitArray used = new BitArray(State.lastNr + 1);
- FindUsedStates(firstState, used);
- // combine equal final states
- for (State s1 = firstState.next; s1 != null; s1 = s1.next) // firstState cannot be final
- if (used[s1.nr] && s1.endOf != null && s1.firstAction == null && !s1.ctx)
- for (State s2 = s1.next; s2 != null; s2 = s2.next)
- if (used[s2.nr] && s1.endOf == s2.endOf && s2.firstAction == null & !s2.ctx) {
- used[s2.nr] = false; newState[s2.nr] = s1;
- }
- for (State state = firstState; state != null; state = state.next)
- if (used[state.nr])
- for (Action a = state.firstAction; a != null; a = a.next)
- if (!used[a.target.state.nr])
- a.target.state = newState[a.target.state.nr];
- // delete unused states
- lastState = firstState; State.lastNr = 0; // firstState has number 0
- for (State state = firstState.next; state != null; state = state.next)
- if (used[state.nr]) {state.nr = ++State.lastNr; lastState = state;}
- else lastState.next = state.next;
- }
-
- static State TheState(Node p) {
- State state;
- if (p == null) {state = NewState(); state.endOf = curSy; return state;}
- else return p.state;
- }
-
- static void Step(State from, Node p, BitArray stepped) {
- if (p == null) return;
- stepped[p.n] = true;
- switch (p.typ) {
- case Node.clas: case Node.chr: {
- NewTransition(from, TheState(p.next), p.typ, p.val, p.code);
- break;
- }
- case Node.alt: {
- Step(from, p.sub, stepped); Step(from, p.down, stepped);
- break;
- }
- case Node.iter: case Node.opt: {
- if (p.next != null && !stepped[p.next.n]) Step(from, p.next, stepped);
- Step(from, p.sub, stepped);
- break;
- }
- }
- }
-
- static void NumberNodes(Node p, State state) {
- /* Assigns a state n.state to every node n. There will be a transition from
- n.state to n.next.state triggered by n.val. All nodes in an alternative
- chain are represented by the same state.
- */
- if (p == null) return;
- if (p.state != null) return; // already visited;
- if (state == null) state = NewState();
- p.state = state;
- if (Node.DelGraph(p)) state.endOf = curSy;
- switch (p.typ) {
- case Node.clas: case Node.chr: {
- NumberNodes(p.next, null);
- break;
- }
- case Node.opt: {
- NumberNodes(p.next, null); NumberNodes(p.sub, state);
- break;
- }
- case Node.iter: {
- NumberNodes(p.next, state); NumberNodes(p.sub, state);
- break;
- }
- case Node.alt: {
- NumberNodes(p.sub, state); NumberNodes(p.down, state);
- break;
- }
- }
- }
-
- static void FindTrans (Node p, bool start, BitArray marked) {
- if (p == null || marked[p.n]) return;
- marked[p.n] = true;
- if (start) Step(p.state, p, new BitArray(Node.nodes.Count)); // start of group of equally numbered nodes
- switch (p.typ) {
- case Node.clas: case Node.chr: {
- FindTrans(p.next, true, marked);
- break;
- }
- case Node.opt: {
- FindTrans(p.next, true, marked); FindTrans(p.sub, false, marked);
- break;
- }
- case Node.iter: {
- FindTrans(p.next, false, marked); FindTrans(p.sub, false, marked);
- break;
- }
- case Node.alt: {
- FindTrans(p.sub, false, marked); FindTrans(p.down, false, marked);
- break;
- }
- }
- }
-
- public static void ConvertToStates(Node p, Symbol sym) {
- curGraph = p; curSy = sym;
- if (Node.DelGraph(curGraph)) Parser.SemErr("token might be empty");
- NumberNodes(curGraph, firstState);
- FindTrans(curGraph, true, new BitArray(Node.nodes.Count));
- }
-
- static Symbol MatchedDFA(string s, Symbol sym) {
- int i, len = s.Length;
- bool weakMatch = false;
- // s has no quotes
- State state = firstState;
- for (i = 0; i < len; i++) { // try to match s against existing DFA
- Action a = state.TheAction(s[i]);
- if (a == null) break;
- if (a.typ == Node.clas) weakMatch = true;
- state = a.target.state;
- }
- // don't execute the following block if s was totally consumed and the DFA is in a final state
- if (weakMatch && (i != len || state.endOf == null)) {
- state = firstState; i = 0;
- dirtyDFA = true;
- }
- for (; i < len; i++) { // make new DFA for s[i..len-1]
- State to = NewState();
- NewTransition(state, to, Node.chr, s[i], Node.normalTrans);
- state = to;
- }
- Symbol matchedSym = state.endOf;
- if (state.endOf == null) state.endOf = sym;
- return matchedSym;
- }
-
- public static void MatchLiteral(Symbol sym) { // store string either as token or as literal
- string name = Unescape(sym.name.Substring(1, sym.name.Length-2));
- if (name.IndexOf('\0') >= 0) Parser.SemErr("\\0 not allowed here. Used as eof character");
- Symbol matchedSym = MatchedDFA(name, sym);
- if (matchedSym == null)
- sym.tokenKind = Symbol.classToken;
- else {
- matchedSym.tokenKind = Symbol.classLitToken;
- sym.tokenKind = Symbol.litToken;
- }
- }
-
- static void SplitActions(State state, Action a, Action b) {
- Action c; BitArray seta, setb, setc;
- seta = a.Symbols(); setb = b.Symbols();
- if (Sets.Equals(seta, setb)) {
- a.AddTargets(b);
- state.DetachAction(b);
- } else if (Sets.Includes(seta, setb)) {
- setc = (BitArray)seta.Clone(); Sets.Subtract(setc, setb);
- b.AddTargets(a);
- a.ShiftWith(setc);
- } else if (Sets.Includes(setb, seta)) {
- setc = (BitArray)setb.Clone(); Sets.Subtract(setc, seta);
- a.AddTargets(b);
- b.ShiftWith(setc);
- } else {
- setc = (BitArray)seta.Clone(); setc.And(setb);
- Sets.Subtract(seta, setc);
- Sets.Subtract(setb, setc);
- a.ShiftWith(seta);
- b.ShiftWith(setb);
- c = new Action(0, 0, Node.normalTrans); // typ and sym are set in ShiftWith
- c.AddTargets(a);
- c.AddTargets(b);
- c.ShiftWith(setc);
- state.AddAction(c);
- }
- }
-
- private static bool Overlap(Action a, Action b) {
- BitArray seta, setb;
- if (a.typ == Node.chr)
- if (b.typ == Node.chr) return a.sym == b.sym;
- else {setb = CharClass.Set(b.sym); return setb[a.sym];}
- else {
- seta = CharClass.Set(a.sym);
- if (b.typ ==Node.chr) return seta[b.sym];
- else {setb = CharClass.Set(b.sym); return Sets.Intersect(seta, setb);}
- }
- }
-
- static bool MakeUnique(State state) { // return true if actions were split
- bool changed = false;
- for (Action a = state.firstAction; a != null; a = a.next)
- for (Action b = a.next; b != null; b = b.next)
- if (Overlap(a, b)) {SplitActions(state, a, b); changed = true;}
- return changed;
- }
-
- static void MeltStates(State state) {
- bool changed, ctx;
- BitArray targets;
- Symbol endOf;
- for (Action action = state.firstAction; action != null; action = action.next) {
- if (action.target.next != null) {
- action.GetTargetStates(out targets, out endOf, out ctx);
- Melted melt = Melted.StateWithSet(targets);
- if (melt == null) {
- State s = NewState(); s.endOf = endOf; s.ctx = ctx;
- for (Target targ = action.target; targ != null; targ = targ.next)
- s.MeltWith(targ.state);
- do {changed = MakeUnique(s);} while (changed);
- melt = new Melted(targets, s);
- }
- action.target.next = null;
- action.target.state = melt.state;
- }
- }
- }
-
- static void FindCtxStates() {
- for (State state = firstState; state != null; state = state.next)
- for (Action a = state.firstAction; a != null; a = a.next)
- if (a.tc == Node.contextTrans) a.target.state.ctx = true;
- }
-
- public static void MakeDeterministic() {
- State state;
- bool changed;
- lastSimState = lastState.nr;
- maxStates = 2 * lastSimState; // heuristic for set size in Melted.set
- FindCtxStates();
- for (state = firstState; state != null; state = state.next)
- do {changed = MakeUnique(state);} while (changed);
- for (state = firstState; state != null; state = state.next)
- MeltStates(state);
- DeleteRedundantStates();
- CombineShifts();
- }
-
- public static void PrintStates() {
- Trace.WriteLine("\n---------- states ----------");
- for (State state = firstState; state != null; state = state.next) {
- bool first = true;
- if (state.endOf == null) Trace.Write(" ");
- else Trace.Write("E({0,12})", Node.Name(state.endOf.name));
- Trace.Write("{0,3}:", state.nr);
- if (state.firstAction == null) Trace.WriteLine();
- for (Action action = state.firstAction; action != null; action = action.next) {
- if (first) {Trace.Write(" "); first = false;} else Trace.Write(" ");
- if (action.typ == Node.clas) Trace.Write(((CharClass)CharClass.classes[action.sym]).name);
- else Trace.Write("{0, 3}", Ch((char)action.sym));
- for (Target targ = action.target; targ != null; targ = targ.next)
- Trace.Write(" {0, 3}", targ.state.nr);
- if (action.tc == Node.contextTrans) Trace.WriteLine(" context"); else Trace.WriteLine();
- }
- }
- Trace.WriteLine("\n---------- character classes ----------");
- CharClass.WriteClasses();
- }
-
- static void GenComBody(Comment com) {
- gen.WriteLine( "\t\t\tfor(;;) {");
- gen.Write ( "\t\t\t\tif ({0}) ", ChCond(com.stop[0])); gen.WriteLine("{");
- if (com.stop.Length == 1) {
- gen.WriteLine("\t\t\t\t\tlevel--;");
- gen.WriteLine("\t\t\t\t\tif (level == 0) { oldEols = line - line0; NextCh(); return true; }");
- gen.WriteLine("\t\t\t\t\tNextCh();");
- } else {
- gen.WriteLine("\t\t\t\t\tNextCh();");
- gen.WriteLine("\t\t\t\t\tif ({0}) {{", ChCond(com.stop[1]));
- gen.WriteLine("\t\t\t\t\t\tlevel--;");
- gen.WriteLine("\t\t\t\t\t\tif (level == 0) { oldEols = line - line0; NextCh(); return true; }");
- gen.WriteLine("\t\t\t\t\t\tNextCh();");
- gen.WriteLine("\t\t\t\t\t}");
- }
- if (com.nested) {
- gen.Write ("\t\t\t\t}"); gen.Write(" else if ({0}) ", ChCond(com.start[0])); gen.WriteLine("{");
- if (com.start.Length == 1)
- gen.WriteLine("\t\t\t\t\tlevel++; NextCh();");
- else {
- gen.WriteLine("\t\t\t\t\tNextCh();");
- gen.Write ("\t\t\t\t\tif ({0}) ", ChCond(com.start[1])); gen.WriteLine("{");
- gen.WriteLine("\t\t\t\t\t\tlevel++; NextCh();");
- gen.WriteLine("\t\t\t\t\t}");
- }
- }
- gen.WriteLine( "\t\t\t\t} else if (ch == EOF) return false;");
- gen.WriteLine( "\t\t\t\telse NextCh();");
- gen.WriteLine( "\t\t\t}");
- }
-
- static void GenComment(Comment com, int i) {
- gen.Write ("\n\tstatic bool Comment{0}() ", i); gen.WriteLine("{");
- gen.WriteLine("\t\tint level = 1, line0 = line, lineStart0 = lineStart;");
- if (com.start.Length == 1) {
- gen.WriteLine("\t\tNextCh();");
- GenComBody(com);
- } else {
- gen.WriteLine("\t\tNextCh();");
- gen.Write ("\t\tif ({0}) ", ChCond(com.start[1])); gen.WriteLine("{");
- gen.WriteLine("\t\t\tNextCh();");
- GenComBody(com);
- gen.WriteLine("\t\t} else {");
- gen.WriteLine("\t\t\tif (ch==EOL) {line--; lineStart = lineStart0;}");
- gen.WriteLine("\t\t\tpos = pos - 2; Buffer.Pos = pos+1; NextCh();");
- gen.WriteLine("\t\t}");
- gen.WriteLine("\t\treturn false;");
- }
- gen.WriteLine("\t}");
- }
-
- static void CopyFramePart(string stop) {
- char startCh = stop[0];
- int endOfStopString = stop.Length-1;
- int ch = fram.ReadByte();
- while (ch != EOF)
- if (ch == startCh) {
- int i = 0;
- do {
- if (i == endOfStopString) return; // stop[0..i] found
- ch = fram.ReadByte(); i++;
- } while (ch == stop[i]);
- // stop[0..i-1] found; continue with last read character
- gen.Write(stop.Substring(0, i));
- } else {
- gen.Write((char)ch); ch = fram.ReadByte();
- }
- Errors.Exception(" -- incomplete or corrupt scanner frame file");
- }
-
- static void GenLiterals () {
- foreach (Symbol sym in Symbol.terminals) {
- if (sym.tokenKind == Symbol.litToken) {
- // sym.name stores literals with quotes, e.g. "\"Literal\"",
- // therefore do NOT place any quotes around {0} after the case
- // or you'll get: case ""Literal"": t.kind = ..., which causes an error
- gen.WriteLine("\t\t\tcase {0}: t.kind = {1}; break;", sym.name, sym.n);
- }
- }
- gen.WriteLine("\t\t\tdefault: break;");
- }
-
- static void WriteState(State state) {
- Symbol endOf = state.endOf;
- gen.WriteLine("\t\t\tcase {0}:", state.nr);
- bool ctxEnd = state.ctx;
- for (Action action = state.firstAction; action != null; action = action.next) {
- if (action == state.firstAction) gen.Write("\t\t\t\tif (");
- else gen.Write("\t\t\t\telse if (");
- if (action.typ == Node.chr) gen.Write(ChCond((char)action.sym));
- else PutRange(CharClass.Set(action.sym));
- gen.Write(") {");
- if (action.tc == Node.contextTrans) {
- gen.Write("apx++; "); ctxEnd = false;
- } else if (state.ctx)
- gen.Write("apx = 0; ");
- gen.Write("buf.Append(ch); NextCh(); goto case {0};", action.target.state.nr);
- gen.WriteLine("}");
- }
- if (state.firstAction == null)
- gen.Write("\t\t\t\t{");
- else
- gen.Write("\t\t\t\telse {");
- if (ctxEnd) { // final context state: cut appendix
- gen.WriteLine();
- gen.WriteLine("\t\t\t\t\tbuf.Length = buf.Length - apx;");
- gen.WriteLine("\t\t\t\t\tpos = pos - apx - 1; line = t.line;");
- gen.WriteLine("\t\t\t\t\tBuffer.Pos = pos+1; NextCh();");
- gen.Write( "\t\t\t\t\t");
- }
- if (endOf == null) {
- gen.WriteLine("t.kind = noSym; goto done;}");
- } else {
- gen.Write("t.kind = {0}; ", endOf.n);
- if (endOf.tokenKind == Symbol.classLitToken) {
- gen.WriteLine("t.val = buf.ToString(); CheckLiteral(); return t;}");
- } else {
- gen.WriteLine("goto done;}");
- }
- }
- }
-
- static void FillStartTab(int[] startTab) {
- startTab[0] = State.lastNr + 1; // eof
- for (Action action = firstState.firstAction; action != null; action = action.next) {
- int targetState = action.target.state.nr;
- if (action.typ == Node.chr) startTab[action.sym] = targetState;
- else {
- BitArray s = CharClass.Set(action.sym);
- for (int i = 0; i < s.Count; i++)
- if (s[i]) startTab[i] = targetState;
- }
- }
- }
-
- public static void WriteScanner() {
- int i, j;
- int[] startTab = new int[CharClass.charSetSize];
- string dir = System.Environment.CurrentDirectory;
- string fr = Path.Combine (dir, "Scanner.frame");
- if (!File.Exists(fr)) {
- string frameDir = Environment.GetEnvironmentVariable("crframes");
- if (frameDir != null) fr = Path.Combine (frameDir.Trim(), "Scanner.frame");
- if (!File.Exists(fr)) Errors.Exception("-- Cannot find Scanner.frame");
- }
- try {
- fram = new FileStream(fr, FileMode.Open, FileAccess.Read, FileShare.Read);
- } catch (FileNotFoundException) {
- Errors.Exception("-- Cannot open Scanner.frame.");
- }
- try {
- string fn = dir + "\\Scanner.cs";
- if (File.Exists(fn)) File.Copy(fn, fn+".old", true);
- FileStream s = new FileStream(fn, FileMode.Create);
- gen = new StreamWriter(s);
- } catch (IOException) {
- Errors.Exception("-- Cannot generate scanner file.");
- }
- if (dirtyDFA) MakeDeterministic();
- FillStartTab(startTab);
-
- CopyFramePart("-->namespace");
- /* AW add namespace, if it exists */
- if (Tab.nsName != null && Tab.nsName.Length > 0) {
- gen.Write("namespace ");
- gen.Write(Tab.nsName);
- gen.Write(" {");
- }
- CopyFramePart("-->constants");
- gen.WriteLine("\tconst int maxT = {0};", Symbol.terminals.Count - 1);
- CopyFramePart("-->declarations");
- gen.WriteLine("\tconst int noSym = {0};", Tab.noSym.n);
- gen.WriteLine("\tstatic short[] start = {");
- for (i = 0; i < CharClass.charSetSize / 16; i++) {
- gen.Write("\t");
- for (j = 0; j < 16; j++)
- gen.Write("{0,3},", startTab[16*i+j]);
- gen.WriteLine();
- }
- gen.WriteLine("\t 0};");
- CopyFramePart("-->initialization");
- gen.WriteLine("\t\tignore = new BitArray({0});", CharClass.charSetSize);
- gen.Write("\t\t");
- if (Tab.ignored == null) gen.Write("ignore[' '] = true;");
- else {
- j = 0;
- for (i = 0; i < Tab.ignored.Count; i++)
- if (Tab.ignored[i]) {
- gen.Write("ignore[{0}] = true; ", i);
- if (++j % 4 == 0) { gen.WriteLine(); gen.Write("\t\t"); }
- }
- }
- CopyFramePart("-->comment");
- Comment com = Comment.first; i = 0;
- while (com != null) {
- GenComment(com, i);
- com = com.next; i++;
- }
- CopyFramePart("-->literals"); GenLiterals();
- CopyFramePart("-->scan1");
- if (Comment.first!=null) {
- gen.Write("\t\tif (");
- com = Comment.first; i = 0;
- while (com != null) {
- gen.Write(ChCond(com.start[0]));
- gen.Write(" && Comment{0}()", i);
- if (com.next != null) gen.Write(" ||");
- com = com.next; i++;
- }
- gen.Write(") return NextToken();");
- }
- if (hasCtxMoves) gen.WriteLine("\t\tint apx = 0;");
- CopyFramePart("-->scan2");
- for (State state = firstState.next; state != null; state = state.next)
- WriteState(state);
- gen.Write("\t\t\tcase "+(State.lastNr+1)+": {t.kind = 0; goto done;}");
- CopyFramePart("$$$");
- /* AW 12-20-02 close namespace, if it exists */
- if (Tab.nsName != null && Tab.nsName.Length > 0) gen.Write("}");
- gen.Close();
- }
-
- public static void Init (string dir) {
- srcDir = dir;
- firstState = null; lastState = null; State.lastNr = -1;
- firstState = NewState();
- Melted.first = null; Comment.first = null;
- dirtyDFA = false;
- hasCtxMoves = false;
- }
-
-} // end DFA
-
-} // end namespace
+// DFA.cs Scaner automaton gnerated by Coco/R H.Moessenboeck, Univ. of Linz
+//----------------------------------------------------------------------------
+using System;
+using System.IO;
+using System.Collections;
+using System.Text;
+
+namespace at.jku.ssw.Coco {
+
+//-----------------------------------------------------------------------------
+// State
+//-----------------------------------------------------------------------------
+
+public class State { // state of finite automaton
+ public static int lastNr; // highest state number
+ public int nr; // state number
+ public Action firstAction;// to first action of this state
+ public Symbol endOf; // recognized token if state is final
+ public bool ctx; // true if state is reached via contextTrans
+ public State next;
+
+ public State() {
+ nr = ++lastNr;
+ }
+
+ public void AddAction(Action act) {
+ Action lasta = null, a = firstAction;
+ while (a != null && act.typ >= a.typ) {lasta = a; a = a.next;}
+ // collecting classes at the beginning gives better performance
+ act.next = a;
+ if (a==firstAction) firstAction = act; else lasta.next = act;
+ }
+
+ public void DetachAction(Action act) {
+ Action lasta = null, a = firstAction;
+ while (a != null && a != act) {lasta = a; a = a.next;}
+ if (a != null)
+ if (a == firstAction) firstAction = a.next; else lasta.next = a.next;
+ }
+
+ public Action TheAction(char ch) {
+ BitArray s;
+ for (Action a = firstAction; a != null; a = a.next)
+ if (a.typ == Node.chr && ch == a.sym) return a;
+ else if (a.typ == Node.clas) {
+ s = CharClass.Set(a.sym);
+ if (s[ch]) return a;
+ }
+ return null;
+ }
+
+ public void MeltWith(State s) { // copy actions of s to state
+ Action a;
+ for (Action action = s.firstAction; action != null; action = action.next) {
+ a = new Action(action.typ, action.sym, action.tc);
+ a.AddTargets(action);
+ AddAction(a);
+ }
+ }
+
+}
+
+//-----------------------------------------------------------------------------
+// Action
+//-----------------------------------------------------------------------------
+
+public class Action { // action of finite automaton
+ public int typ; // type of action symbol: clas, chr
+ public int sym; // action symbol
+ public int tc; // transition code: normalTrans, contextTrans
+ public Target target; // states reached from this action
+ public Action next;
+
+ public Action(int typ, int sym, int tc) {
+ this.typ = typ; this.sym = sym; this.tc = tc;
+ }
+
+ public void AddTarget(Target t) { // add t to the action.targets
+ Target last = null;
+ Target p = target;
+ while (p != null && t.state.nr >= p.state.nr) {
+ if (t.state == p.state) return;
+ last = p; p = p.next;
+ }
+ t.next = p;
+ if (p == target) target = t; else last.next = t;
+ }
+
+ public void AddTargets(Action a) { // add copy of a.targets to action.targets
+ for (Target p = a.target; p != null; p = p.next) {
+ Target t = new Target(p.state);
+ AddTarget(t);
+ }
+ if (a.tc == Node.contextTrans) tc = Node.contextTrans;
+ }
+
+ public BitArray Symbols() {
+ BitArray s;
+ if (typ == Node.clas)
+ s = (BitArray) CharClass.Set(sym).Clone();
+ else {
+ s = new BitArray(CharClass.charSetSize); s[sym] = true;
+ }
+ return s;
+ }
+
+ public void ShiftWith(BitArray s) {
+ if (Sets.Elements(s) == 1) {
+ typ = Node.chr; sym = Sets.First(s);
+ } else {
+ CharClass c = CharClass.Find(s);
+ if (c == null) c = new CharClass("#", s); // class with dummy name
+ typ = Node.clas; sym = c.n;
+ }
+ }
+
+ public void GetTargetStates(out BitArray targets, out Symbol endOf, out bool ctx) {
+ // compute the set of target states
+ targets = new BitArray(DFA.maxStates); endOf = null;
+ ctx = false;
+ for (Target t = target; t != null; t = t.next) {
+ int stateNr = t.state.nr;
+ if (stateNr <= DFA.lastSimState) targets[stateNr] = true;
+ else targets.Or(Melted.Set(stateNr));
+ if (t.state.endOf != null)
+ if (endOf == null || endOf == t.state.endOf)
+ endOf = t.state.endOf;
+ else {
+ Console.WriteLine("Tokens {0} and {1} cannot be distinguished", endOf.name, t.state.endOf.name);
+ Errors.count++;
+ }
+ if (t.state.ctx) {
+ ctx = true;
+ // The following check seems to be unnecessary. It reported an error
+ // if a symbol + context was the prefix of another symbol, e.g.
+ // s1 = "a" "b" "c".
+ // s2 = "a" CONTEXT("b").
+ // But this is ok.
+ // if (t.state.endOf != null) {
+ // Console.WriteLine("Ambiguous context clause");
+ // Errors.count++;
+ // }
+ }
+ }
+ }
+
+}
+
+//-----------------------------------------------------------------------------
+// Target
+//-----------------------------------------------------------------------------
+
+public class Target { // set of states that are reached by an action
+ public State state; // target state
+ public Target next;
+
+ public Target (State s) {
+ state = s;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Melted
+//-----------------------------------------------------------------------------
+
+public class Melted { // info about melted states
+ public static Melted first; // head of melted state list
+ public BitArray set; // set of old states
+ public State state; // new state
+ public Melted next;
+
+ public Melted(BitArray set, State state) {
+ this.set = set; this.state = state;
+ this.next = first; first = this;
+ }
+
+ public static BitArray Set(int nr) {
+ Melted m = first;
+ while (m != null) {
+ if (m.state.nr == nr) return m.set; else m = m.next;
+ }
+ throw new Exception("-- compiler error in Melted.Set");
+ }
+
+ public static Melted StateWithSet(BitArray s) {
+ for (Melted m = first; m != null; m = m.next)
+ if (Sets.Equals(s, m.set)) return m;
+ return null;
+ }
+
+}
+
+//-----------------------------------------------------------------------------
+// Comment
+//-----------------------------------------------------------------------------
+
+public class Comment { // info about comment syntax
+ public static Comment first; // list of comments
+ public string start;
+ public string stop;
+ public bool nested;
+ public Comment next;
+
+ static string Str(Node p) {
+ StringBuilder s = new StringBuilder();
+ while (p != null) {
+ if (p.typ == Node.chr) {
+ s.Append((char)p.val);
+ } else if (p.typ == Node.clas) {
+ BitArray set = CharClass.Set(p.val);
+ if (Sets.Elements(set) != 1) Parser.SemErr("character set contains more than 1 character");
+ s.Append((char)Sets.First(set));
+ } else Parser.SemErr("comment delimiters may not be structured");
+ p = p.next;
+ }
+ if (s.Length == 0 || s.Length > 2) {
+ Parser.SemErr("comment delimiters must be 1 or 2 characters long");
+ s = new StringBuilder("?");
+ }
+ return s.ToString();
+ }
+
+ public Comment(Node from, Node to, bool nested) {
+ start = Str(from);
+ stop = Str(to);
+ this.nested = nested;
+ this.next = first; first = this;
+ }
+
+}
+
+//-----------------------------------------------------------------------------
+// DFA
+//-----------------------------------------------------------------------------
+
+public class DFA {
+ public static int maxStates;
+ public const int EOF = -1;
+ public const char CR = '\r';
+ public const char LF = '\n';
+
+ public static State firstState;
+ public static State lastState; // last allocated state
+ public static int lastSimState; // last non melted state
+ public static FileStream fram; // scanner frame input
+ public static StreamWriter gen; // generated scanner file
+ static string srcDir; // directory of attributed grammar file
+ public static Symbol curSy; // current token to be recognized (in FindTrans)
+ public static Node curGraph; // start of graph for current token (in FindTrans)
+ public static bool dirtyDFA; // DFA may become nondeterministic in MatchedDFA
+ public static bool hasCtxMoves; // DFA has context transitions
+
+ //---------- Output primitives
+ private static string Ch(char ch) {
+ if (ch < ' ' || ch >= 127 || ch == '\'' || ch == '\\') return Convert.ToString((int)ch);
+ else return String.Format("'{0}'", ch);
+ }
+
+ private static string ChCond(char ch) {
+ return String.Format("ch == {0}", Ch(ch));
+ }
+
+ private static void PutRange(BitArray s) {
+ int[] lo = new int[32];
+ int[] hi = new int[32];
+ // fill lo and hi
+ int max = CharClass.charSetSize;
+ int top = -1;
+ int i = 0;
+ while (i < max) {
+ if (s[i]) {
+ top++; lo[top] = i; i++;
+ while (i < max && s[i]) i++;
+ hi[top] = i-1;
+ } else i++;
+ }
+ // print ranges
+ if (top == 1 && lo[0] == 0 && hi[1] == max-1 && hi[0]+2 == lo[1]) {
+ BitArray s1 = new BitArray(max); s1[hi[0]+1] = true;
+ gen.Write("!"); PutRange(s1);
+ } else {
+ gen.Write("(");
+ for (i = 0; i <= top; i++) {
+ if (hi[i] == lo[i]) gen.Write("ch == {0}", Ch((char)lo[i]));
+ else if (lo[i] == 0) gen.Write("ch <= {0}", Ch((char)hi[i]));
+ else if (hi[i] == max-1) gen.Write("ch >= {0}", Ch((char)lo[i]));
+ else gen.Write("ch >= {0} && ch <= {1}", Ch((char)lo[i]), Ch((char)hi[i]));
+ if (i < top) gen.Write(" || ");
+ }
+ gen.Write(")");
+ }
+ }
+
+ //---------- String handling
+ static char Hex2Char(string s) {
+ int val = 0;
+ for (int i = 0; i < s.Length; i++) {
+ char ch = s[i];
+ if ('0' <= ch && ch <= '9') val = 16 * val + (ch - '0');
+ else if ('a' <= ch && ch <= 'f') val = 16 * val + (10 + ch - 'a');
+ else if ('A' <= ch && ch <= 'Z') val = 16 * val + (10 + ch - 'A');
+ else Parser.SemErr("bad escape sequence in string or character");
+ }
+ return (char)val;
+ }
+
+ static string Char2Hex(char ch) {
+ StringWriter w = new StringWriter();
+ w.Write("\\u{0:x4}", (int)ch);
+ return w.ToString();
+ }
+
+ public static string Unescape (string s) {
+ /* replaces escape sequences in s by their Unicode values. */
+ StringBuilder buf = new StringBuilder();
+ int i = 0;
+ while (i < s.Length) {
+ if (s[i] == '\\') {
+ switch (s[i+1]) {
+ case '\\': buf.Append('\\'); i += 2; break;
+ case '\'': buf.Append('\''); i += 2; break;
+ case '\"': buf.Append('\"'); i += 2; break;
+ case 'r': buf.Append('\r'); i += 2; break;
+ case 'n': buf.Append('\n'); i += 2; break;
+ case 't': buf.Append('\t'); i += 2; break;
+ case '0': buf.Append('\0'); i += 2; break;
+ case 'a': buf.Append('\a'); i += 2; break;
+ case 'b': buf.Append('\b'); i += 2; break;
+ case 'f': buf.Append('\f'); i += 2; break;
+ case 'v': buf.Append('\v'); i += 2; break;
+ case 'u': case 'x':
+ if (i + 6 <= s.Length) {
+ buf.Append(Hex2Char(s.Substring(i+2, 4))); i += 6; break;
+ } else {
+ Parser.SemErr("bad escape sequence in string or character"); i = s.Length; break;
+ }
+ default: Parser.SemErr("bad escape sequence in string or character"); i += 2; break;
+ }
+ } else {
+ buf.Append(s[i]);
+ i++;
+ }
+ }
+ return buf.ToString();
+ }
+
+ public static string Escape (string s) {
+ StringBuilder buf = new StringBuilder();
+ foreach (char ch in s) {
+ if (ch == '\\') buf.Append("\\\\");
+ else if (ch == '"') buf.Append("\\\"");
+ else if (ch < ' ' || ch > '\u007f') buf.Append(Char2Hex(ch));
+ else buf.Append(ch);
+ }
+ return buf.ToString();
+ }
+
+ //---------- State handling
+ static State NewState() {
+ State s = new State();
+ if (firstState == null) firstState = s; else lastState.next = s;
+ lastState = s;
+ return s;
+ }
+
+ static void NewTransition(State from, State to, int typ, int sym, int tc) {
+ if (to == firstState) Parser.SemErr("token must not start with an iteration");
+ Target t = new Target(to);
+ Action a = new Action(typ, sym, tc); a.target = t;
+ from.AddAction(a);
+ }
+
+ static void CombineShifts() {
+ State state;
+ Action a, b, c;
+ BitArray seta, setb;
+ for (state = firstState; state != null; state = state.next) {
+ for (a = state.firstAction; a != null; a = a.next) {
+ b = a.next;
+ while (b != null)
+ if (a.target.state == b.target.state && a.tc == b.tc) {
+ seta = a.Symbols(); setb = b.Symbols();
+ seta.Or(setb);
+ a.ShiftWith(seta);
+ c = b; b = b.next; state.DetachAction(c);
+ } else b = b.next;
+ }
+ }
+ }
+
+ static void FindUsedStates(State state, BitArray used) {
+ if (used[state.nr]) return;
+ used[state.nr] = true;
+ for (Action a = state.firstAction; a != null; a = a.next)
+ FindUsedStates(a.target.state, used);
+ }
+
+ static void DeleteRedundantStates() {
+ State[] newState = new State[State.lastNr + 1];
+ BitArray used = new BitArray(State.lastNr + 1);
+ FindUsedStates(firstState, used);
+ // combine equal final states
+ for (State s1 = firstState.next; s1 != null; s1 = s1.next) // firstState cannot be final
+ if (used[s1.nr] && s1.endOf != null && s1.firstAction == null && !s1.ctx)
+ for (State s2 = s1.next; s2 != null; s2 = s2.next)
+ if (used[s2.nr] && s1.endOf == s2.endOf && s2.firstAction == null & !s2.ctx) {
+ used[s2.nr] = false; newState[s2.nr] = s1;
+ }
+ for (State state = firstState; state != null; state = state.next)
+ if (used[state.nr])
+ for (Action a = state.firstAction; a != null; a = a.next)
+ if (!used[a.target.state.nr])
+ a.target.state = newState[a.target.state.nr];
+ // delete unused states
+ lastState = firstState; State.lastNr = 0; // firstState has number 0
+ for (State state = firstState.next; state != null; state = state.next)
+ if (used[state.nr]) {state.nr = ++State.lastNr; lastState = state;}
+ else lastState.next = state.next;
+ }
+
+ static State TheState(Node p) {
+ State state;
+ if (p == null) {state = NewState(); state.endOf = curSy; return state;}
+ else return p.state;
+ }
+
+ static void Step(State from, Node p, BitArray stepped) {
+ if (p == null) return;
+ stepped[p.n] = true;
+ switch (p.typ) {
+ case Node.clas: case Node.chr: {
+ NewTransition(from, TheState(p.next), p.typ, p.val, p.code);
+ break;
+ }
+ case Node.alt: {
+ Step(from, p.sub, stepped); Step(from, p.down, stepped);
+ break;
+ }
+ case Node.iter: case Node.opt: {
+ if (p.next != null && !stepped[p.next.n]) Step(from, p.next, stepped);
+ Step(from, p.sub, stepped);
+ break;
+ }
+ }
+ }
+
+ static void NumberNodes(Node p, State state) {
+ /* Assigns a state n.state to every node n. There will be a transition from
+ n.state to n.next.state triggered by n.val. All nodes in an alternative
+ chain are represented by the same state.
+ */
+ if (p == null) return;
+ if (p.state != null) return; // already visited;
+ if (state == null) state = NewState();
+ p.state = state;
+ if (Node.DelGraph(p)) state.endOf = curSy;
+ switch (p.typ) {
+ case Node.clas: case Node.chr: {
+ NumberNodes(p.next, null);
+ break;
+ }
+ case Node.opt: {
+ NumberNodes(p.next, null); NumberNodes(p.sub, state);
+ break;
+ }
+ case Node.iter: {
+ NumberNodes(p.next, state); NumberNodes(p.sub, state);
+ break;
+ }
+ case Node.alt: {
+ NumberNodes(p.sub, state); NumberNodes(p.down, state);
+ break;
+ }
+ }
+ }
+
+ static void FindTrans (Node p, bool start, BitArray marked) {
+ if (p == null || marked[p.n]) return;
+ marked[p.n] = true;
+ if (start) Step(p.state, p, new BitArray(Node.nodes.Count)); // start of group of equally numbered nodes
+ switch (p.typ) {
+ case Node.clas: case Node.chr: {
+ FindTrans(p.next, true, marked);
+ break;
+ }
+ case Node.opt: {
+ FindTrans(p.next, true, marked); FindTrans(p.sub, false, marked);
+ break;
+ }
+ case Node.iter: {
+ FindTrans(p.next, false, marked); FindTrans(p.sub, false, marked);
+ break;
+ }
+ case Node.alt: {
+ FindTrans(p.sub, false, marked); FindTrans(p.down, false, marked);
+ break;
+ }
+ }
+ }
+
+ public static void ConvertToStates(Node p, Symbol sym) {
+ curGraph = p; curSy = sym;
+ if (Node.DelGraph(curGraph)) Parser.SemErr("token might be empty");
+ NumberNodes(curGraph, firstState);
+ FindTrans(curGraph, true, new BitArray(Node.nodes.Count));
+ }
+
+ static Symbol MatchedDFA(string s, Symbol sym) {
+ int i, len = s.Length;
+ bool weakMatch = false;
+ // s has no quotes
+ State state = firstState;
+ for (i = 0; i < len; i++) { // try to match s against existing DFA
+ Action a = state.TheAction(s[i]);
+ if (a == null) break;
+ if (a.typ == Node.clas) weakMatch = true;
+ state = a.target.state;
+ }
+ // don't execute the following block if s was totally consumed and the DFA is in a final state
+ if (weakMatch && (i != len || state.endOf == null)) {
+ state = firstState; i = 0;
+ dirtyDFA = true;
+ }
+ for (; i < len; i++) { // make new DFA for s[i..len-1]
+ State to = NewState();
+ NewTransition(state, to, Node.chr, s[i], Node.normalTrans);
+ state = to;
+ }
+ Symbol matchedSym = state.endOf;
+ if (state.endOf == null) state.endOf = sym;
+ return matchedSym;
+ }
+
+ public static void MatchLiteral(Symbol sym) { // store string either as token or as literal
+ string name = Unescape(sym.name.Substring(1, sym.name.Length-2));
+ if (name.IndexOf('\0') >= 0) Parser.SemErr("\\0 not allowed here. Used as eof character");
+ Symbol matchedSym = MatchedDFA(name, sym);
+ if (matchedSym == null)
+ sym.tokenKind = Symbol.classToken;
+ else {
+ matchedSym.tokenKind = Symbol.classLitToken;
+ sym.tokenKind = Symbol.litToken;
+ }
+ }
+
+ static void SplitActions(State state, Action a, Action b) {
+ Action c; BitArray seta, setb, setc;
+ seta = a.Symbols(); setb = b.Symbols();
+ if (Sets.Equals(seta, setb)) {
+ a.AddTargets(b);
+ state.DetachAction(b);
+ } else if (Sets.Includes(seta, setb)) {
+ setc = (BitArray)seta.Clone(); Sets.Subtract(setc, setb);
+ b.AddTargets(a);
+ a.ShiftWith(setc);
+ } else if (Sets.Includes(setb, seta)) {
+ setc = (BitArray)setb.Clone(); Sets.Subtract(setc, seta);
+ a.AddTargets(b);
+ b.ShiftWith(setc);
+ } else {
+ setc = (BitArray)seta.Clone(); setc.And(setb);
+ Sets.Subtract(seta, setc);
+ Sets.Subtract(setb, setc);
+ a.ShiftWith(seta);
+ b.ShiftWith(setb);
+ c = new Action(0, 0, Node.normalTrans); // typ and sym are set in ShiftWith
+ c.AddTargets(a);
+ c.AddTargets(b);
+ c.ShiftWith(setc);
+ state.AddAction(c);
+ }
+ }
+
+ private static bool Overlap(Action a, Action b) {
+ BitArray seta, setb;
+ if (a.typ == Node.chr)
+ if (b.typ == Node.chr) return a.sym == b.sym;
+ else {setb = CharClass.Set(b.sym); return setb[a.sym];}
+ else {
+ seta = CharClass.Set(a.sym);
+ if (b.typ ==Node.chr) return seta[b.sym];
+ else {setb = CharClass.Set(b.sym); return Sets.Intersect(seta, setb);}
+ }
+ }
+
+ static bool MakeUnique(State state) { // return true if actions were split
+ bool changed = false;
+ for (Action a = state.firstAction; a != null; a = a.next)
+ for (Action b = a.next; b != null; b = b.next)
+ if (Overlap(a, b)) {SplitActions(state, a, b); changed = true;}
+ return changed;
+ }
+
+ static void MeltStates(State state) {
+ bool changed, ctx;
+ BitArray targets;
+ Symbol endOf;
+ for (Action action = state.firstAction; action != null; action = action.next) {
+ if (action.target.next != null) {
+ action.GetTargetStates(out targets, out endOf, out ctx);
+ Melted melt = Melted.StateWithSet(targets);
+ if (melt == null) {
+ State s = NewState(); s.endOf = endOf; s.ctx = ctx;
+ for (Target targ = action.target; targ != null; targ = targ.next)
+ s.MeltWith(targ.state);
+ do {changed = MakeUnique(s);} while (changed);
+ melt = new Melted(targets, s);
+ }
+ action.target.next = null;
+ action.target.state = melt.state;
+ }
+ }
+ }
+
+ static void FindCtxStates() {
+ for (State state = firstState; state != null; state = state.next)
+ for (Action a = state.firstAction; a != null; a = a.next)
+ if (a.tc == Node.contextTrans) a.target.state.ctx = true;
+ }
+
+ public static void MakeDeterministic() {
+ State state;
+ bool changed;
+ lastSimState = lastState.nr;
+ maxStates = 2 * lastSimState; // heuristic for set size in Melted.set
+ FindCtxStates();
+ for (state = firstState; state != null; state = state.next)
+ do {changed = MakeUnique(state);} while (changed);
+ for (state = firstState; state != null; state = state.next)
+ MeltStates(state);
+ DeleteRedundantStates();
+ CombineShifts();
+ }
+
+ public static void PrintStates() {
+ Trace.WriteLine("\n---------- states ----------");
+ for (State state = firstState; state != null; state = state.next) {
+ bool first = true;
+ if (state.endOf == null) Trace.Write(" ");
+ else Trace.Write("E({0,12})", Node.Name(state.endOf.name));
+ Trace.Write("{0,3}:", state.nr);
+ if (state.firstAction == null) Trace.WriteLine();
+ for (Action action = state.firstAction; action != null; action = action.next) {
+ if (first) {Trace.Write(" "); first = false;} else Trace.Write(" ");
+ if (action.typ == Node.clas) Trace.Write(((CharClass)CharClass.classes[action.sym]).name);
+ else Trace.Write("{0, 3}", Ch((char)action.sym));
+ for (Target targ = action.target; targ != null; targ = targ.next)
+ Trace.Write(" {0, 3}", targ.state.nr);
+ if (action.tc == Node.contextTrans) Trace.WriteLine(" context"); else Trace.WriteLine();
+ }
+ }
+ Trace.WriteLine("\n---------- character classes ----------");
+ CharClass.WriteClasses();
+ }
+
+ static void GenComBody(Comment com) {
+ gen.WriteLine( "\t\t\tfor(;;) {");
+ gen.Write ( "\t\t\t\tif ({0}) ", ChCond(com.stop[0])); gen.WriteLine("{");
+ if (com.stop.Length == 1) {
+ gen.WriteLine("\t\t\t\t\tlevel--;");
+ gen.WriteLine("\t\t\t\t\tif (level == 0) { oldEols = line - line0; NextCh(); return true; }");
+ gen.WriteLine("\t\t\t\t\tNextCh();");
+ } else {
+ gen.WriteLine("\t\t\t\t\tNextCh();");
+ gen.WriteLine("\t\t\t\t\tif ({0}) {{", ChCond(com.stop[1]));
+ gen.WriteLine("\t\t\t\t\t\tlevel--;");
+ gen.WriteLine("\t\t\t\t\t\tif (level == 0) { oldEols = line - line0; NextCh(); return true; }");
+ gen.WriteLine("\t\t\t\t\t\tNextCh();");
+ gen.WriteLine("\t\t\t\t\t}");
+ }
+ if (com.nested) {
+ gen.Write ("\t\t\t\t}"); gen.Write(" else if ({0}) ", ChCond(com.start[0])); gen.WriteLine("{");
+ if (com.start.Length == 1)
+ gen.WriteLine("\t\t\t\t\tlevel++; NextCh();");
+ else {
+ gen.WriteLine("\t\t\t\t\tNextCh();");
+ gen.Write ("\t\t\t\t\tif ({0}) ", ChCond(com.start[1])); gen.WriteLine("{");
+ gen.WriteLine("\t\t\t\t\t\tlevel++; NextCh();");
+ gen.WriteLine("\t\t\t\t\t}");
+ }
+ }
+ gen.WriteLine( "\t\t\t\t} else if (ch == EOF) return false;");
+ gen.WriteLine( "\t\t\t\telse NextCh();");
+ gen.WriteLine( "\t\t\t}");
+ }
+
+ static void GenComment(Comment com, int i) {
+ gen.Write ("\n\tstatic bool Comment{0}() ", i); gen.WriteLine("{");
+ gen.WriteLine("\t\tint level = 1, line0 = line, lineStart0 = lineStart;");
+ if (com.start.Length == 1) {
+ gen.WriteLine("\t\tNextCh();");
+ GenComBody(com);
+ } else {
+ gen.WriteLine("\t\tNextCh();");
+ gen.Write ("\t\tif ({0}) ", ChCond(com.start[1])); gen.WriteLine("{");
+ gen.WriteLine("\t\t\tNextCh();");
+ GenComBody(com);
+ gen.WriteLine("\t\t} else {");
+ gen.WriteLine("\t\t\tif (ch==EOL) {line--; lineStart = lineStart0;}");
+ gen.WriteLine("\t\t\tpos = pos - 2; Buffer.Pos = pos+1; NextCh();");
+ gen.WriteLine("\t\t}");
+ gen.WriteLine("\t\treturn false;");
+ }
+ gen.WriteLine("\t}");
+ }
+
+ static void CopyFramePart(string stop) {
+ char startCh = stop[0];
+ int endOfStopString = stop.Length-1;
+ int ch = fram.ReadByte();
+ while (ch != EOF)
+ if (ch == startCh) {
+ int i = 0;
+ do {
+ if (i == endOfStopString) return; // stop[0..i] found
+ ch = fram.ReadByte(); i++;
+ } while (ch == stop[i]);
+ // stop[0..i-1] found; continue with last read character
+ gen.Write(stop.Substring(0, i));
+ } else {
+ gen.Write((char)ch); ch = fram.ReadByte();
+ }
+ Errors.Exception(" -- incomplete or corrupt scanner frame file");
+ }
+
+ static void GenLiterals () {
+ foreach (Symbol sym in Symbol.terminals) {
+ if (sym.tokenKind == Symbol.litToken) {
+ // sym.name stores literals with quotes, e.g. "\"Literal\"",
+ // therefore do NOT place any quotes around {0} after the case
+ // or you'll get: case ""Literal"": t.kind = ..., which causes an error
+ gen.WriteLine("\t\t\tcase {0}: t.kind = {1}; break;", sym.name, sym.n);
+ }
+ }
+ gen.WriteLine("\t\t\tdefault: break;");
+ }
+
+ static void WriteState(State state) {
+ Symbol endOf = state.endOf;
+ gen.WriteLine("\t\t\tcase {0}:", state.nr);
+ bool ctxEnd = state.ctx;
+ for (Action action = state.firstAction; action != null; action = action.next) {
+ if (action == state.firstAction) gen.Write("\t\t\t\tif (");
+ else gen.Write("\t\t\t\telse if (");
+ if (action.typ == Node.chr) gen.Write(ChCond((char)action.sym));
+ else PutRange(CharClass.Set(action.sym));
+ gen.Write(") {");
+ if (action.tc == Node.contextTrans) {
+ gen.Write("apx++; "); ctxEnd = false;
+ } else if (state.ctx)
+ gen.Write("apx = 0; ");
+ gen.Write("buf.Append(ch); NextCh(); goto case {0};", action.target.state.nr);
+ gen.WriteLine("}");
+ }
+ if (state.firstAction == null)
+ gen.Write("\t\t\t\t{");
+ else
+ gen.Write("\t\t\t\telse {");
+ if (ctxEnd) { // final context state: cut appendix
+ gen.WriteLine();
+ gen.WriteLine("\t\t\t\t\tbuf.Length = buf.Length - apx;");
+ gen.WriteLine("\t\t\t\t\tpos = pos - apx - 1; line = t.line;");
+ gen.WriteLine("\t\t\t\t\tBuffer.Pos = pos+1; NextCh();");
+ gen.Write( "\t\t\t\t\t");
+ }
+ if (endOf == null) {
+ gen.WriteLine("t.kind = noSym; goto done;}");
+ } else {
+ gen.Write("t.kind = {0}; ", endOf.n);
+ if (endOf.tokenKind == Symbol.classLitToken) {
+ gen.WriteLine("t.val = buf.ToString(); CheckLiteral(); return t;}");
+ } else {
+ gen.WriteLine("goto done;}");
+ }
+ }
+ }
+
+ static void FillStartTab(int[] startTab) {
+ startTab[0] = State.lastNr + 1; // eof
+ for (Action action = firstState.firstAction; action != null; action = action.next) {
+ int targetState = action.target.state.nr;
+ if (action.typ == Node.chr) startTab[action.sym] = targetState;
+ else {
+ BitArray s = CharClass.Set(action.sym);
+ for (int i = 0; i < s.Count; i++)
+ if (s[i]) startTab[i] = targetState;
+ }
+ }
+ }
+
+ public static void WriteScanner() {
+ int i, j;
+ int[] startTab = new int[CharClass.charSetSize];
+ string dir = System.Environment.CurrentDirectory;
+ string fr = Path.Combine (dir, "Scanner.frame");
+ if (!File.Exists(fr)) {
+ string frameDir = Environment.GetEnvironmentVariable("crframes");
+ if (frameDir != null) fr = Path.Combine (frameDir.Trim(), "Scanner.frame");
+ if (!File.Exists(fr)) Errors.Exception("-- Cannot find Scanner.frame");
+ }
+ try {
+ fram = new FileStream(fr, FileMode.Open, FileAccess.Read, FileShare.Read);
+ } catch (FileNotFoundException) {
+ Errors.Exception("-- Cannot open Scanner.frame.");
+ }
+ try {
+ string fn = dir + "\\Scanner.cs";
+ if (File.Exists(fn)) File.Copy(fn, fn+".old", true);
+ FileStream s = new FileStream(fn, FileMode.Create);
+ gen = new StreamWriter(s);
+ } catch (IOException) {
+ Errors.Exception("-- Cannot generate scanner file.");
+ }
+ if (dirtyDFA) MakeDeterministic();
+ FillStartTab(startTab);
+
+ CopyFramePart("-->namespace");
+ /* AW add namespace, if it exists */
+ if (Tab.nsName != null && Tab.nsName.Length > 0) {
+ gen.Write("namespace ");
+ gen.Write(Tab.nsName);
+ gen.Write(" {");
+ }
+ CopyFramePart("-->constants");
+ gen.WriteLine("\tconst int maxT = {0};", Symbol.terminals.Count - 1);
+ CopyFramePart("-->declarations");
+ gen.WriteLine("\tconst int noSym = {0};", Tab.noSym.n);
+ gen.WriteLine("\tstatic short[] start = {");
+ for (i = 0; i < CharClass.charSetSize / 16; i++) {
+ gen.Write("\t");
+ for (j = 0; j < 16; j++)
+ gen.Write("{0,3},", startTab[16*i+j]);
+ gen.WriteLine();
+ }
+ gen.WriteLine("\t 0};");
+ CopyFramePart("-->initialization");
+ gen.WriteLine("\t\tignore = new BitArray({0});", CharClass.charSetSize);
+ gen.Write("\t\t");
+ if (Tab.ignored == null) gen.Write("ignore[' '] = true;");
+ else {
+ j = 0;
+ for (i = 0; i < Tab.ignored.Count; i++)
+ if (Tab.ignored[i]) {
+ gen.Write("ignore[{0}] = true; ", i);
+ if (++j % 4 == 0) { gen.WriteLine(); gen.Write("\t\t"); }
+ }
+ }
+ CopyFramePart("-->comment");
+ Comment com = Comment.first; i = 0;
+ while (com != null) {
+ GenComment(com, i);
+ com = com.next; i++;
+ }
+ CopyFramePart("-->literals"); GenLiterals();
+ CopyFramePart("-->scan1");
+ if (Comment.first!=null) {
+ gen.Write("\t\tif (");
+ com = Comment.first; i = 0;
+ while (com != null) {
+ gen.Write(ChCond(com.start[0]));
+ gen.Write(" && Comment{0}()", i);
+ if (com.next != null) gen.Write(" ||");
+ com = com.next; i++;
+ }
+ gen.Write(") return NextToken();");
+ }
+ if (hasCtxMoves) gen.WriteLine("\t\tint apx = 0;");
+ CopyFramePart("-->scan2");
+ for (State state = firstState.next; state != null; state = state.next)
+ WriteState(state);
+ gen.Write("\t\t\tcase "+(State.lastNr+1)+": {t.kind = 0; goto done;}");
+ CopyFramePart("$$$");
+ /* AW 12-20-02 close namespace, if it exists */
+ if (Tab.nsName != null && Tab.nsName.Length > 0) gen.Write("}");
+ gen.Close();
+ }
+
+ public static void Init (string dir) {
+ srcDir = dir;
+ firstState = null; lastState = null; State.lastNr = -1;
+ firstState = NewState();
+ Melted.first = null; Comment.first = null;
+ dirtyDFA = false;
+ hasCtxMoves = false;
+ }
+
+} // end DFA
+
+} // end namespace
Modified: trunk/MonoDevelop/src/Tools/SharpCoco/src/Parser.cs
===================================================================
--- trunk/MonoDevelop/src/Tools/SharpCoco/src/Parser.cs 2004-04-09 12:41:44 UTC (rev 1420)
+++ trunk/MonoDevelop/src/Tools/SharpCoco/src/Parser.cs 2004-04-09 17:17:47 UTC (rev 1421)
@@ -1,761 +1,761 @@
-using System.Collections;
-using System.Text;
-using System;
-using System.Reflection;
-
-namespace at.jku.ssw.Coco {
-
-
-
-public class Parser {
- const int maxT = 42;
-
- const bool T = true;
- const bool x = false;
- const int minErrDist = 2;
- const string errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text
-
- static Token t; // last recognized token
- static Token la; // lookahead token
- static int errDist = minErrDist;
-
-const int id = 0;
- const int str = 1;
-
- static bool genScanner;
-
-/*-------------------------------------------------------------------------*/
-
-
-
- static void SynErr (int n) {
- if (errDist >= minErrDist) Errors.SynErr(la.line, la.col, n);
- errDist = 0;
- }
-
- public static void SemErr (string msg) {
- if (errDist >= minErrDist) Errors.Error(t.line, t.col, msg);
- errDist = 0;
- }
-
- static void Get () {
- for (;;) {
- t = la;
- la = Scanner.Scan();
- if (la.kind <= maxT) { ++errDist; break; } /* ML return changed to break */
- if (la.kind == 43) {
- Tab.SetDDT(la.val);
- }
-
- la = t;
- }
- }
-
- static void Expect (int n) {
- if (la.kind==n) Get(); else { SynErr(n); }
- }
-
- static bool StartOf (int s) {
- return set[s, la.kind];
- }
-
- static void ExpectWeak (int n, int follow) {
- if (la.kind == n) Get();
- else {
- SynErr(n);
- while (!StartOf(follow)) Get();
- }
- }
-
- static bool WeakSeparator (int n, int syFol, int repFol) {
- bool[] s = new bool[maxT+1];
- if (la.kind == n) { Get(); return true; }
- else if (StartOf(repFol)) return false;
- else {
- for (int i=0; i <= maxT; i++) {
- s[i] = set[syFol, i] || set[repFol, i] || set[0, i];
- }
- SynErr(n);
- while (!s[la.kind]) Get();
- return StartOf(syFol);
- }
- }
-
- static void Coco() {
- Symbol sym; Graph g; string gramName;
- if (la.kind == 40) {
- UsingDecl(out ParserGen.usingPos);
- }
- Expect(6);
- int gramLine = t.line;
- genScanner = true;
- bool ok = true;
- Tab.ignored = null;
-
- Expect(1);
- gramName = t.val;
- int beg = la.pos;
-
- while (StartOf(1)) {
- Get();
- }
- Tab.semDeclPos = new Position(beg, la.pos-beg, 0);
- while (StartOf(2)) {
- Declaration();
- }
- while (!(la.kind == 0 || la.kind == 7)) {SynErr(43); Get();}
- Expect(7);
- if (genScanner) DFA.MakeDeterministic();
- Graph.DeleteNodes();
-
- while (la.kind == 1) {
- Get();
- sym = Symbol.Find(t.val);
- bool undef = sym == null;
- if (undef) sym = new Symbol(Node.nt, t.val, t.line);
- else {
- if (sym.typ == Node.nt) {
- if (sym.graph != null) SemErr("name declared twice");
- } else SemErr("this symbol kind not allowed on left side of production");
- sym.line = t.line;
- }
- bool noAttrs = sym.attrPos == null;
- sym.attrPos = null;
-
- if (la.kind == 24) {
- AttrDecl(sym);
- }
- if (!undef)
- if (noAttrs != (sym.attrPos == null))
- SemErr("attribute mismatch between declaration and use of this symbol");
-
- if (la.kind == 38) {
- SemText(out sym.semPos);
- }
- ExpectWeak(8, 3);
- Expression(out g);
- sym.graph = g.l;
- Graph.Finish(g);
-
- ExpectWeak(9, 4);
- }
- Expect(10);
- Expect(1);
- if (gramName != t.val)
- SemErr("name does not match grammar name");
- Tab.gramSy = Symbol.Find(gramName);
- if (Tab.gramSy == null)
- SemErr("missing production for grammar name");
- else {
- sym = Tab.gramSy;
- if (sym.attrPos != null)
- SemErr("grammar symbol must not have attributes");
- }
- Tab.noSym = new Symbol(Node.t, "???", 0); // noSym gets highest number
- Tab.SetupAnys();
- Tab.RenumberPragmas();
- if (Tab.ddt[2]) Node.PrintNodes();
- if (Errors.count == 0) {
- Console.WriteLine("checking");
- Tab.CompSymbolSets();
- ok = ok && Tab.GrammarOk();
- if (Tab.ddt[7]) Tab.XRef();
- if (ok) {
- Console.Write("parser");
- ParserGen.WriteParser();
- if (genScanner) {
- Console.Write(" + scanner");
- DFA.WriteScanner();
- if (Tab.ddt[0]) DFA.PrintStates();
- }
- Console.WriteLine(" generated");
- if (Tab.ddt[8]) ParserGen.WriteStatistics();
- }
- }
- if (Tab.ddt[6]) Tab.PrintSymbolTable();
-
- Expect(9);
- }
-
- static void UsingDecl(out Position pos) {
- Expect(40);
- int beg = t.pos;
- while (StartOf(5)) {
- Get();
- }
- Expect(41);
- int end = t.pos;
- while (la.kind == 40) {
- Get();
- while (StartOf(5)) {
- Get();
- }
- Expect(41);
- end = t.pos;
- }
- pos = new Position(beg, end - beg + 1, 0);
- }
-
- static void Declaration() {
- Graph g1, g2; bool nested = false;
- switch (la.kind) {
- case 11: {
- Get();
- while (la.kind == 1) {
- SetDecl();
- }
- break;
- }
- case 12: {
- Get();
- while (la.kind == 1 || la.kind == 3 || la.kind == 5) {
- TokenDecl(Node.t);
- }
- break;
- }
- case 13: {
- Get();
- while (la.kind == 1 || la.kind == 3 || la.kind == 5) {
- TokenDecl(Node.pr);
- }
- break;
- }
- case 14: {
- Get();
- Expect(15);
- TokenExpr(out g1);
- Expect(16);
- TokenExpr(out g2);
- if (la.kind == 17) {
- Get();
- nested = true;
- } else if (StartOf(6)) {
- nested = false;
- } else SynErr(44);
- new Comment(g1.l, g2.l, nested);
- break;
- }
- case 18: {
- Get();
- Set(out Tab.ignored);
- Tab.ignored[' '] = true; /* ' ' is always ignored */
- if (Tab.ignored[0]) SemErr("may not ignore \'\\0\'");
- break;
- }
- case 19: {
- Get();
- Symbol.tokenNames = new Hashtable();
- while (la.kind == 1 || la.kind == 3) {
- if (la.kind == 3) {
- Get();
- } else {
- Get();
- }
- string key = t.val;
- Expect(8);
- Expect(1);
- string val = t.val; Symbol.tokenNames.Add(key, val);
- }
- break;
- }
- default: SynErr(45); break;
- }
- }
-
- static void AttrDecl(Symbol sym) {
- Expect(24);
- int beg = la.pos; int col = la.col;
- while (StartOf(7)) {
- if (StartOf(8)) {
- Get();
- } else {
- Get();
- SemErr("bad string in semantic action");
- }
- }
- Expect(25);
- sym.attrPos = new Position(beg, t.pos - beg, col);
- }
-
- static void SemText(out Position pos) {
- Expect(38);
- int beg = la.pos; int col = la.col;
- while (StartOf(9)) {
- if (StartOf(10)) {
- Get();
- } else if (la.kind == 4) {
- Get();
- SemErr("bad string in semantic action");
- } else {
- Get();
- SemErr("missing end of previous semantic action");
- }
- }
- Expect(39);
- pos = new Position(beg, t.pos - beg, col);
- }
-
- static void Expression(out Graph g) {
- Graph g2;
- Term(out g);
- bool first = true;
- while (WeakSeparator(26,11,12) ) {
- Term(out g2);
- if (first) { Graph.MakeFirstAlt(g); first = false; }
- Graph.MakeAlternative(g, g2);
-
- }
- }
-
- static void SetDecl() {
- BitArray s;
- Expect(1);
- string name = t.val;
- CharClass c = CharClass.Find(name);
- if (c != null) SemErr("name declared twice");
-
- Expect(8);
- Set(out s);
- if (Sets.Elements(s) == 0) SemErr("character set must not be empty");
- c = new CharClass(name, s);
-
- Expect(9);
- }
-
- static void TokenDecl(int typ) {
- string name; int kind; Symbol sym; Graph g;
- Sym(out name, out kind);
- sym = Symbol.Find(name);
- if (sym != null) SemErr("name declared twice");
- else {
- sym = new Symbol(typ, name, t.line);
- sym.tokenKind = Symbol.classToken;
- }
-
- while (!(StartOf(13))) {SynErr(46); Get();}
- if (la.kind == 8) {
- Get();
- TokenExpr(out g);
- Expect(9);
- if (kind != id) SemErr("a literal must not be declared with a structure");
- Graph.Finish(g);
- DFA.ConvertToStates(g.l, sym);
-
- } else if (la.kind == 9) {
- Get();
- if (typ != Node.rslv) SemErr("resolver is only allowed in RESOLVERS section");
- } else if (StartOf(14)) {
- if (kind == id) genScanner = false;
- else DFA.MatchLiteral(sym);
-
- } else SynErr(47);
- if (la.kind == 38) {
- SemText(out sym.semPos);
- if (typ == Node.t) SemErr("semantic action not allowed here");
- } else if (StartOf(15)) {
- if (typ == Node.rslv) SemErr("resolvers must have a semantic action");
- } else SynErr(48);
- }
-
- static void TokenExpr(out Graph g) {
- Graph g2;
- TokenTerm(out g);
- bool first = true;
- while (WeakSeparator(26,16,17) ) {
- TokenTerm(out g2);
- if (first) { Graph.MakeFirstAlt(g); first = false; }
- Graph.MakeAlternative(g, g2);
-
- }
- }
-
- static void Set(out BitArray s) {
- BitArray s2;
- SimSet(out s);
- while (la.kind == 20 || la.kind == 21) {
- if (la.kind == 20) {
- Get();
- SimSet(out s2);
- s.Or(s2);
- } else {
- Get();
- SimSet(out s2);
- Sets.Subtract(s, s2);
- }
- }
- }
-
- static void SimSet(out BitArray s) {
- int n1, n2;
- s = new BitArray(CharClass.charSetSize);
- if (la.kind == 1) {
- Get();
- CharClass c = CharClass.Find(t.val);
- if (c == null) SemErr("undefined name"); else s.Or(c.set);
-
- } else if (la.kind == 3) {
- Get();
- string name = t.val;
- name = DFA.Unescape(name.Substring(1, name.Length-2));
- foreach (char ch in name) s[ch] = true;
-
- } else if (la.kind == 5) {
- Char(out n1);
- s[n1] = true;
- if (la.kind == 22) {
- Get();
- Char(out n2);
- for (int i = n1; i <= n2; i++) s[i] = true;
- }
- } else if (la.kind == 23) {
- Get();
- s = new BitArray(CharClass.charSetSize, true);
- s[0] = false;
-
- } else SynErr(49);
- }
-
- static void Char(out int n) {
- Expect(5);
- string name = t.val;
- name = DFA.Unescape(name.Substring(1, name.Length-2));
- int max = CharClass.charSetSize;
- if (name.Length != 1 || name[0] > max-1) SemErr("unacceptable character value");
- n = name[0] % max;
-
- }
-
- static void Sym(out string name, out int kind) {
- name = "???"; kind = id;
- if (la.kind == 1) {
- Get();
- kind = id; name = t.val;
- } else if (la.kind == 3 || la.kind == 5) {
- if (la.kind == 3) {
- Get();
- name = t.val;
- } else {
- Get();
- name = "\"" + t.val.Substring(1, t.val.Length-2) + "\"";
- }
- kind = str;
- } else SynErr(50);
- }
-
- static void Term(out Graph g) {
- Graph g2; Position pos; Node rslv = null;
- g = null;
-
- if (StartOf(18)) {
- if (la.kind == 35) {
- rslv = new Node(Node.rslv, null, la.line);
- ResolveExpr(out pos);
- rslv.pos = pos;
- g = new Graph(rslv);
-
- }
- Factor(out g2);
- if (rslv != null) Graph.MakeSequence(g, g2);
- else g = g2;
-
- while (StartOf(19)) {
- Factor(out g2);
- Graph.MakeSequence(g, g2);
- }
- } else if (StartOf(20)) {
- g = new Graph(new Node(Node.eps, null, 0));
- } else SynErr(51);
- }
-
- static void ResolveExpr(out Position pos) {
- Expect(35);
- Expect(28);
- int beg = la.pos; int col = la.col;
- if (la.kind == 8 || la.kind == 36) {
- if (la.kind == 8) {
- Get();
- } else {
- Get();
- }
- CondPart();
- } else if (la.kind == 28) {
- Get();
- CondPart();
- Expect(29);
- } else if (StartOf(21)) {
- Get();
- CondPart();
- } else SynErr(52);
- pos = new Position(beg, t.pos - beg, col);
- }
-
- static void Factor(out Graph g) {
- string name; int kind; Position pos; bool weak = false;
- g = null;
-
- switch (la.kind) {
- case 1: case 3: case 5: case 27: {
- if (la.kind == 27) {
- Get();
- weak = true;
- }
- Sym(out name, out kind);
- Symbol sym = Symbol.Find(name);
- bool undef = sym == null;
- if (undef) {
- if (kind == id)
- sym = new Symbol(Node.nt, name, 0); // forward nt
- else if (genScanner) {
- sym = new Symbol(Node.t, name, t.line);
- DFA.MatchLiteral(sym);
- } else { // undefined string in production
- SemErr("undefined string in production");
- sym = Tab.eofSy; // dummy
- }
- }
- int typ = sym.typ;
- if (typ != Node.t && typ != Node.nt && typ != Node.rslv) /* ML */
- SemErr("this symbol kind is not allowed in a production");
- if (weak)
- if (typ == Node.t) typ = Node.wt;
- else SemErr("only terminals may be weak");
- Node p = new Node(typ, sym, t.line);
- g = new Graph(p);
-
- if (la.kind == 24) {
- Attribs(p);
- if (kind != id) SemErr("a literal must not have attributes");
- }
- if (undef)
- sym.attrPos = p.pos; // dummy
- else if ((p.pos == null) != (sym.attrPos == null))
- SemErr("attribute mismatch between declaration and use of this symbol");
-
- break;
- }
- case 28: {
- Get();
- Expression(out g);
- Expect(29);
- break;
- }
- case 30: {
- Get();
- Expression(out g);
- Expect(31);
- Graph.MakeOption(g);
- break;
- }
- case 32: {
- Get();
- Expression(out g);
- Expect(33);
- Graph.MakeIteration(g);
- break;
- }
- case 38: {
- SemText(out pos);
- Node p = new Node(Node.sem, null, 0);
- p.pos = pos;
- g = new Graph(p);
-
- break;
- }
- case 23: {
- Get();
- Node p = new Node(Node.any, null, 0); // p.set is set in Tab.SetupAnys
- g = new Graph(p);
-
- break;
- }
- case 34: {
- Get();
- Node p = new Node(Node.sync, null, 0);
- g = new Graph(p);
-
- break;
- }
- default: SynErr(53); break;
- }
- }
-
- static void Attribs(Node p) {
- Expect(24);
- int beg = la.pos; int col = la.col;
- while (StartOf(7)) {
- if (StartOf(8)) {
- Get();
- } else {
- Get();
- SemErr("bad string in attributes");
- }
- }
- Expect(25);
- p.pos = new Position(beg, t.pos - beg, col);
- }
-
- static void CondPart() {
- while (StartOf(22)) {
- if (la.kind == 28) {
- Get();
- CondPart();
- } else {
- Get();
- }
- }
- Expect(29);
- }
-
- static void TokenTerm(out Graph g) {
- Graph g2;
- TokenFactor(out g);
- while (StartOf(16)) {
- TokenFactor(out g2);
- Graph.MakeSequence(g, g2);
- }
- if (la.kind == 37) {
- Get();
- Expect(28);
- TokenExpr(out g2);
- Graph.SetContextTrans(g2.l); Graph.MakeSequence(g, g2);
- Expect(29);
- }
- }
-
- static void TokenFactor(out Graph g) {
- string name; int kind;
- g = new Graph();
- if (la.kind == 1 || la.kind == 3 || la.kind == 5) {
- Sym(out name, out kind);
- if (kind == id) {
- CharClass c = CharClass.Find(name);
- if (c == null) {
- SemErr("undefined name");
- c = new CharClass(name, new BitArray(CharClass.charSetSize));
- }
- Node p = new Node(Node.clas, null, 0); p.val = c.n;
- g = new Graph(p);
- } else g = Graph.StrToGraph(name); // str
-
- } else if (la.kind == 28) {
- Get();
- TokenExpr(out g);
- Expect(29);
- } else if (la.kind == 30) {
- Get();
- TokenExpr(out g);
- Expect(31);
- Graph.MakeOption(g);
- } else if (la.kind == 32) {
- Get();
- TokenExpr(out g);
- Expect(33);
- Graph.MakeIteration(g);
- } else SynErr(54);
- }
-
-
-
- public static void Parse() {
- Errors.SynErr = new ErrorCodeProc(SynErr);
- la = new Token();
- la.val = "";
- Get();
- Coco();
-
- }
-
- static void SynErr (int line, int col, int n) {
- Errors.count++;
- string s;
- switch (n) {
- case 0: s = "EOF expected"; break;
- case 1: s = "ident expected"; break;
- case 2: s = "number expected"; break;
- case 3: s = "string expected"; break;
- case 4: s = "badString expected"; break;
- case 5: s = "char expected"; break;
- case 6: s = "\"COMPILER\" expected"; break;
- case 7: s = "\"PRODUCTIONS\" expected"; break;
- case 8: s = "\"=\" expected"; break;
- case 9: s = "\".\" expected"; break;
- case 10: s = "\"END\" expected"; break;
- case 11: s = "\"CHARACTERS\" expected"; break;
- case 12: s = "\"TOKENS\" expected"; break;
- case 13: s = "\"PRAGMAS\" expected"; break;
- case 14: s = "\"COMMENTS\" expected"; break;
- case 15: s = "\"FROM\" expected"; break;
- case 16: s = "\"TO\" expected"; break;
- case 17: s = "\"NESTED\" expected"; break;
- case 18: s = "\"IGNORE\" expected"; break;
- case 19: s = "\"TOKENNAMES\" expected"; break;
- case 20: s = "\"+\" expected"; break;
- case 21: s = "\"-\" expected"; break;
- case 22: s = "\"..\" expected"; break;
- case 23: s = "\"ANY\" expected"; break;
- case 24: s = "\"<\" expected"; break;
- case 25: s = "\">\" expected"; break;
- case 26: s = "\"|\" expected"; break;
- case 27: s = "\"WEAK\" expected"; break;
- case 28: s = "\"(\" expected"; break;
- case 29: s = "\")\" expected"; break;
- case 30: s = "\"[\" expected"; break;
- case 31: s = "\"]\" expected"; break;
- case 32: s = "\"{\" expected"; break;
- case 33: s = "\"}\" expected"; break;
- case 34: s = "\"SYNC\" expected"; break;
- case 35: s = "\"IF\" expected"; break;
- case 36: s = "\"!=\" expected"; break;
- case 37: s = "\"CONTEXT\" expected"; break;
- case 38: s = "\"(.\" expected"; break;
- case 39: s = "\".)\" expected"; break;
- case 40: s = "\"using\" expected"; break;
- case 41: s = "\";\" expected"; break;
- case 42: s = "??? expected"; break;
- case 43: s = "this symbol not expected in Coco"; break;
- case 44: s = "invalid Declaration"; break;
- case 45: s = "invalid Declaration"; break;
- case 46: s = "this symbol not expected in TokenDecl"; break;
- case 47: s = "invalid TokenDecl"; break;
- case 48: s = "invalid TokenDecl"; break;
- case 49: s = "invalid SimSet"; break;
- case 50: s = "invalid Sym"; break;
- case 51: s = "invalid Term"; break;
- case 52: s = "invalid ResolveExpr"; break;
- case 53: s = "invalid Factor"; break;
- case 54: s = "invalid TokenFactor"; break;
-
- default: s = "error " + n; break;
- }
- Console.WriteLine(errMsgFormat, line, col, s);
- }
-
- static bool[,] set = {
- {T,T,x,T, x,T,x,T, T,T,x,T, T,T,T,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x},
- {x,T,T,T, T,T,T,x, T,T,T,x, x,x,x,T, T,T,x,x, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,x},
- {x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
- {T,T,x,T, x,T,x,T, T,T,x,T, T,T,T,x, x,x,T,T, x,x,x,T, x,x,T,T, T,x,T,x, T,x,T,T, x,x,T,x, x,x,x,x},
- {T,T,x,T, x,T,x,T, T,T,T,T, T,T,T,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x},
- {x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,T,x},
- {x,x,x,x, x,x,x,T, x,x,x,T, T,T,T,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
- {x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,x},
- {x,T,T,T, x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,x},
- {x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,x, T,T,T,x},
- {x,T,T,T, x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,x,x, T,T,T,x},
- {x,T,x,T, x,T,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,T,T, T,T,T,T, T,T,T,T, x,x,T,x, x,x,x,x},
- {x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x},
- {T,T,x,T, x,T,x,T, T,T,x,T, T,T,T,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x},
- {x,T,x,T, x,T,x,T, x,x,x,T, T,T,T,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x},
- {x,T,x,T, x,T,x,T, x,x,x,T, T,T,T,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
- {x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,T,x, T,x,x,x, x,x,x,x, x,x,x,x},
- {x,x,x,x, x,x,x,T, x,T,x,T, T,T,T,x, T,T,T,T, x,x,x,x, x,x,x,x, x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x},
- {x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,T, T,x,T,x, T,x,T,T, x,x,T,x, x,x,x,x},
- {x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,T, T,x,T,x, T,x,T,x, x,x,T,x, x,x,x,x},
- {x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x},
- {x,T,T,T, T,T,T,T, x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, x,T,T,T, T,T,T,T, x,T,T,T, T,T,T,x},
- {x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,T,T, T,T,T,T, T,T,T,T, T,T,T,x}
-
- };
-} // end Parser
-
-}
+using System.Collections;
+using System.Text;
+using System;
+using System.Reflection;
+
+namespace at.jku.ssw.Coco {
+
+
+
+public class Parser {
+ const int maxT = 42;
+
+ const bool T = true;
+ const bool x = false;
+ const int minErrDist = 2;
+ const string errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text
+
+ static Token t; // last recognized token
+ static Token la; // lookahead token
+ static int errDist = minErrDist;
+
+const int id = 0;
+ const int str = 1;
+
+ static bool genScanner;
+
+/*-------------------------------------------------------------------------*/
+
+
+
+ static void SynErr (int n) {
+ if (errDist >= minErrDist) Errors.SynErr(la.line, la.col, n);
+ errDist = 0;
+ }
+
+ public static void SemErr (string msg) {
+ if (errDist >= minErrDist) Errors.Error(t.line, t.col, msg);
+ errDist = 0;
+ }
+
+ static void Get () {
+ for (;;) {
+ t = la;
+ la = Scanner.Scan();
+ if (la.kind <= maxT) { ++errDist; break; } /* ML return changed to break */
+ if (la.kind == 43) {
+ Tab.SetDDT(la.val);
+ }
+
+ la = t;
+ }
+ }
+
+ static void Expect (int n) {
+ if (la.kind==n) Get(); else { SynErr(n); }
+ }
+
+ static bool StartOf (int s) {
+ return set[s, la.kind];
+ }
+
+ static void ExpectWeak (int n, int follow) {
+ if (la.kind == n) Get();
+ else {
+ SynErr(n);
+ while (!StartOf(follow)) Get();
+ }
+ }
+
+ static bool WeakSeparator (int n, int syFol, int repFol) {
+ bool[] s = new bool[maxT+1];
+ if (la.kind == n) { Get(); return true; }
+ else if (StartOf(repFol)) return false;
+ else {
+ for (int i=0; i <= maxT; i++) {
+ s[i] = set[syFol, i] || set[repFol, i] || set[0, i];
+ }
+ SynErr(n);
+ while (!s[la.kind]) Get();
+ return StartOf(syFol);
+ }
+ }
+
+ static void Coco() {
+ Symbol sym; Graph g; string gramName;
+ if (la.kind == 40) {
+ UsingDecl(out ParserGen.usingPos);
+ }
+ Expect(6);
+ int gramLine = t.line;
+ genScanner = true;
+ bool ok = true;
+ Tab.ignored = null;
+
+ Expect(1);
+ gramName = t.val;
+ int beg = la.pos;
+
+ while (StartOf(1)) {
+ Get();
+ }
+ Tab.semDeclPos = new Position(beg, la.pos-beg, 0);
+ while (StartOf(2)) {
+ Declaration();
+ }
+ while (!(la.kind == 0 || la.kind == 7)) {SynErr(43); Get();}
+ Expect(7);
+ if (genScanner) DFA.MakeDeterministic();
+ Graph.DeleteNodes();
+
+ while (la.kind == 1) {
+ Get();
+ sym = Symbol.Find(t.val);
+ bool undef = sym == null;
+ if (undef) sym = new Symbol(Node.nt, t.val, t.line);
+ else {
+ if (sym.typ == Node.nt) {
+ if (sym.graph != null) SemErr("name declared twice");
+ } else SemErr("this symbol kind not allowed on left side of production");
+ sym.line = t.line;
+ }
+ bool noAttrs = sym.attrPos == null;
+ sym.attrPos = null;
+
+ if (la.kind == 24) {
+ AttrDecl(sym);
+ }
+ if (!undef)
+ if (noAttrs != (sym.attrPos == null))
+ SemErr("attribute mismatch between declaration and use of this symbol");
+
+ if (la.kind == 38) {
+ SemText(out sym.semPos);
+ }
+ ExpectWeak(8, 3);
+ Expression(out g);
+ sym.graph = g.l;
+ Graph.Finish(g);
+
+ ExpectWeak(9, 4);
+ }
+ Expect(10);
+ Expect(1);
+ if (gramName != t.val)
+ SemErr("name does not match grammar name");
+ Tab.gramSy = Symbol.Find(gramName);
+ if (Tab.gramSy == null)
+ SemErr("missing production for grammar name");
+ else {
+ sym = Tab.gramSy;
+ if (sym.attrPos != null)
+ SemErr("grammar symbol must not have attributes");
+ }
+ Tab.noSym = new Symbol(Node.t, "???", 0); // noSym gets highest number
+ Tab.SetupAnys();
+ Tab.RenumberPragmas();
+ if (Tab.ddt[2]) Node.PrintNodes();
+ if (Errors.count == 0) {
+ Console.WriteLine("checking");
+ Tab.CompSymbolSets();
+ ok = ok && Tab.GrammarOk();
+ if (Tab.ddt[7]) Tab.XRef();
+ if (ok) {
+ Console.Write("parser");
+ ParserGen.WriteParser();
+ if (genScanner) {
+ Console.Write(" + scanner");
+ DFA.WriteScanner();
+ if (Tab.ddt[0]) DFA.PrintStates();
+ }
+ Console.WriteLine(" generated");
+ if (Tab.ddt[8]) ParserGen.WriteStatistics();
+ }
+ }
+ if (Tab.ddt[6]) Tab.PrintSymbolTable();
+
+ Expect(9);
+ }
+
+ static void UsingDecl(out Position pos) {
+ Expect(40);
+ int beg = t.pos;
+ while (StartOf(5)) {
+ Get();
+ }
+ Expect(41);
+ int end = t.pos;
+ while (la.kind == 40) {
+ Get();
+ while (StartOf(5)) {
+ Get();
+ }
+ Expect(41);
+ end = t.pos;
+ }
+ pos = new Position(beg, end - beg + 1, 0);
+ }
+
+ static void Declaration() {
+ Graph g1, g2; bool nested = false;
+ switch (la.kind) {
+ case 11: {
+ Get();
+ while (la.kind == 1) {
+ SetDecl();
+ }
+ break;
+ }
+ case 12: {
+ Get();
+ while (la.kind == 1 || la.kind == 3 || la.kind == 5) {
+ TokenDecl(Node.t);
+ }
+ break;
+ }
+ case 13: {
+ Get();
+ while (la.kind == 1 || la.kind == 3 || la.kind == 5) {
+ TokenDecl(Node.pr);
+ }
+ break;
+ }
+ case 14: {
+ Get();
+ Expect(15);
+ TokenExpr(out g1);
+ Expect(16);
+ TokenExpr(out g2);
+ if (la.kind == 17) {
+ Get();
+ nested = true;
+ } else if (StartOf(6)) {
+ nested = false;
+ } else SynErr(44);
+ new Comment(g1.l, g2.l, nested);
+ break;
+ }
+ case 18: {
+ Get();
+ Set(out Tab.ignored);
+ Tab.ignored[' '] = true; /* ' ' is always ignored */
+ if (Tab.ignored[0]) SemErr("may not ignore \'\\0\'");
+ break;
+ }
+ case 19: {
+ Get();
+ Symbol.tokenNames = new Hashtable();
+ while (la.kind == 1 || la.kind == 3) {
+ if (la.kind == 3) {
+ Get();
+ } else {
+ Get();
+ }
+ string key = t.val;
+ Expect(8);
+ Expect(1);
+ string val = t.val; Symbol.tokenNames.Add(key, val);
+ }
+ break;
+ }
+ default: SynErr(45); break;
+ }
+ }
+
+ static void AttrDecl(Symbol sym) {
+ Expect(24);
+ int beg = la.pos; int col = la.col;
+ while (StartOf(7)) {
+ if (StartOf(8)) {
+ Get();
+ } else {
+ Get();
+ SemErr("bad string in semantic action");
+ }
+ }
+ Expect(25);
+ sym.attrPos = new Position(beg, t.pos - beg, col);
+ }
+
+ static void SemText(out Position pos) {
+ Expect(38);
+ int beg = la.pos; int col = la.col;
+ while (StartOf(9)) {
+ if (StartOf(10)) {
+ Get();
+ } else if (la.kind == 4) {
+ Get();
+ SemErr("bad string in semantic action");
+ } else {
+ Get();
+ SemErr("missing end of previous semantic action");
+ }
+ }
+ Expect(39);
+ pos = new Position(beg, t.pos - beg, col);
+ }
+
+ static void Expression(out Graph g) {
+ Graph g2;
+ Term(out g);
+ bool first = true;
+ while (WeakSeparator(26,11,12) ) {
+ Term(out g2);
+ if (first) { Graph.MakeFirstAlt(g); first = false; }
+ Graph.MakeAlternative(g, g2);
+
+ }
+ }
+
+ static void SetDecl() {
+ BitArray s;
+ Expect(1);
+ string name = t.val;
+ CharClass c = CharClass.Find(name);
+ if (c != null) SemErr("name declared twice");
+
+ Expect(8);
+ Set(out s);
+ if (Sets.Elements(s) == 0) SemErr("character set must not be empty");
+ c = new CharClass(name, s);
+
+ Expect(9);
+ }
+
+ static void TokenDecl(int typ) {
+ string name; int kind; Symbol sym; Graph g;
+ Sym(out name, out kind);
+ sym = Symbol.Find(name);
+ if (sym != null) SemErr("name declared twice");
+ else {
+ sym = new Symbol(typ, name, t.line);
+ sym.tokenKind = Symbol.classToken;
+ }
+
+ while (!(StartOf(13))) {SynErr(46); Get();}
+ if (la.kind == 8) {
+ Get();
+ TokenExpr(out g);
+ Expect(9);
+ if (kind != id) SemErr("a literal must not be declared with a structure");
+ Graph.Finish(g);
+ DFA.ConvertToStates(g.l, sym);
+
+ } else if (la.kind == 9) {
+ Get();
+ if (typ != Node.rslv) SemErr("resolver is only allowed in RESOLVERS section");
+ } else if (StartOf(14)) {
+ if (kind == id) genScanner = false;
+ else DFA.MatchLiteral(sym);
+
+ } else SynErr(47);
+ if (la.kind == 38) {
+ SemText(out sym.semPos);
+ if (typ == Node.t) SemErr("semantic action not allowed here");
+ } else if (StartOf(15)) {
+ if (typ == Node.rslv) SemErr("resolvers must have a semantic action");
+ } else SynErr(48);
+ }
+
+ static void TokenExpr(out Graph g) {
+ Graph g2;
+ TokenTerm(out g);
+ bool first = true;
+ while (WeakSeparator(26,16,17) ) {
+ TokenTerm(out g2);
+ if (first) { Graph.MakeFirstAlt(g); first = false; }
+ Graph.MakeAlternative(g, g2);
+
+ }
+ }
+
+ static void Set(out BitArray s) {
+ BitArray s2;
+ SimSet(out s);
+ while (la.kind == 20 || la.kind == 21) {
+ if (la.kind == 20) {
+ Get();
+ SimSet(out s2);
+ s.Or(s2);
+ } else {
+ Get();
+ SimSet(out s2);
+ Sets.Subtract(s, s2);
+ }
+ }
+ }
+
+ static void SimSet(out BitArray s) {
+ int n1, n2;
+ s = new BitArray(CharClass.charSetSize);
+ if (la.kind == 1) {
+ Get();
+ CharClass c = CharClass.Find(t.val);
+ if (c == null) SemErr("undefined name"); else s.Or(c.set);
+
+ } else if (la.kind == 3) {
+ Get();
+ string name = t.val;
+ name = DFA.Unescape(name.Substring(1, name.Length-2));
+ foreach (char ch in name) s[ch] = true;
+
+ } else if (la.kind == 5) {
+ Char(out n1);
+ s[n1] = true;
+ if (la.kind == 22) {
+ Get();
+ Char(out n2);
+ for (int i = n1; i <= n2; i++) s[i] = true;
+ }
+ } else if (la.kind == 23) {
+ Get();
+ s = new BitArray(CharClass.charSetSize, true);
+ s[0] = false;
+
+ } else SynErr(49);
+ }
+
+ static void Char(out int n) {
+ Expect(5);
+ string name = t.val;
+ name = DFA.Unescape(name.Substring(1, name.Length-2));
+ int max = CharClass.charSetSize;
+ if (name.Length != 1 || name[0] > max-1) SemErr("unacceptable character value");
+ n = name[0] % max;
+
+ }
+
+ static void Sym(out string name, out int kind) {
+ name = "???"; kind = id;
+ if (la.kind == 1) {
+ Get();
+ kind = id; name = t.val;
+ } else if (la.kind == 3 || la.kind == 5) {
+ if (la.kind == 3) {
+ Get();
+ name = t.val;
+ } else {
+ Get();
+ name = "\"" + t.val.Substring(1, t.val.Length-2) + "\"";
+ }
+ kind = str;
+ } else SynErr(50);
+ }
+
+ static void Term(out Graph g) {
+ Graph g2; Position pos; Node rslv = null;
+ g = null;
+
+ if (StartOf(18)) {
+ if (la.kind == 35) {
+ rslv = new Node(Node.rslv, null, la.line);
+ ResolveExpr(out pos);
+ rslv.pos = pos;
+ g = new Graph(rslv);
+
+ }
+ Factor(out g2);
+ if (rslv != null) Graph.MakeSequence(g, g2);
+ else g = g2;
+
+ while (StartOf(19)) {
+ Factor(out g2);
+ Graph.MakeSequence(g, g2);
+ }
+ } else if (StartOf(20)) {
+ g = new Graph(new Node(Node.eps, null, 0));
+ } else SynErr(51);
+ }
+
+ static void ResolveExpr(out Position pos) {
+ Expect(35);
+ Expect(28);
+ int beg = la.pos; int col = la.col;
+ if (la.kind == 8 || la.kind == 36) {
+ if (la.kind == 8) {
+ Get();
+ } else {
+ Get();
+ }
+ CondPart();
+ } else if (la.kind == 28) {
+ Get();
+ CondPart();
+ Expect(29);
+ } else if (StartOf(21)) {
+ Get();
+ CondPart();
+ } else SynErr(52);
+ pos = new Position(beg, t.pos - beg, col);
+ }
+
+ static void Factor(out Graph g) {
+ string name; int kind; Position pos; bool weak = false;
+ g = null;
+
+ switch (la.kind) {
+ case 1: case 3: case 5: case 27: {
+ if (la.kind == 27) {
+ Get();
+ weak = true;
+ }
+ Sym(out name, out kind);
+ Symbol sym = Symbol.Find(name);
+ bool undef = sym == null;
+ if (undef) {
+ if (kind == id)
+ sym = new Symbol(Node.nt, name, 0); // forward nt
+ else if (genScanner) {
+ sym = new Symbol(Node.t, name, t.line);
+ DFA.MatchLiteral(sym);
+ } else { // undefined string in production
+ SemErr("undefined string in production");
+ sym = Tab.eofSy; // dummy
+ }
+ }
+ int typ = sym.typ;
+ if (typ != Node.t && typ != Node.nt && typ != Node.rslv) /* ML */
+ SemErr("this symbol kind is not allowed in a production");
+ if (weak)
+ if (typ == Node.t) typ = Node.wt;
+ else SemErr("only terminals may be weak");
+ Node p = new Node(typ, sym, t.line);
+ g = new Graph(p);
+
+ if (la.kind == 24) {
+ Attribs(p);
+ if (kind != id) SemErr("a literal must not have attributes");
+ }
+ if (undef)
+ sym.attrPos = p.pos; // dummy
+ else if ((p.pos == null) != (sym.attrPos == null))
+ SemErr("attribute mismatch between declaration and use of this symbol");
+
+ break;
+ }
+ case 28: {
+ Get();
+ Expression(out g);
+ Expect(29);
+ break;
+ }
+ case 30: {
+ Get();
+ Expression(out g);
+ Expect(31);
+ Graph.MakeOption(g);
+ break;
+ }
+ case 32: {
+ Get();
+ Expression(out g);
+ Expect(33);
+ Graph.MakeIteration(g);
+ break;
+ }
+ case 38: {
+ SemText(out pos);
+ Node p = new Node(Node.sem, null, 0);
+ p.pos = pos;
+ g = new Graph(p);
+
+ break;
+ }
+ case 23: {
+ Get();
+ Node p = new Node(Node.any, null, 0); // p.set is set in Tab.SetupAnys
+ g = new Graph(p);
+
+ break;
+ }
+ case 34: {
+ Get();
+ Node p = new Node(Node.sync, null, 0);
+ g = new Graph(p);
+
+ break;
+ }
+ default: SynErr(53); break;
+ }
+ }
+
+ static void Attribs(Node p) {
+ Expect(24);
+ int beg = la.pos; int col = la.col;
+ while (StartOf(7)) {
+ if (StartOf(8)) {
+ Get();
+ } else {
+ Get();
+ SemErr("bad string in attributes");
+ }
+ }
+ Expect(25);
+ p.pos = new Position(beg, t.pos - beg, col);
+ }
+
+ static void CondPart() {
+ while (StartOf(22)) {
+ if (la.kind == 28) {
+ Get();
+ CondPart();
+ } else {
+ Get();
+ }
+ }
+ Expect(29);
+ }
+
+ static void TokenTerm(out Graph g) {
+ Graph g2;
+ TokenFactor(out g);
+ while (StartOf(16)) {
+ TokenFactor(out g2);
+ Graph.MakeSequence(g, g2);
+ }
+ if (la.kind == 37) {
+ Get();
+ Expect(28);
+ TokenExpr(out g2);
+ Graph.SetContextTrans(g2.l); Graph.MakeSequence(g, g2);
+ Expect(29);
+ }
+ }
+
+ static void TokenFactor(out Graph g) {
+ string name; int kind;
+ g = new Graph();
+ if (la.kind == 1 || la.kind == 3 || la.kind == 5) {
+ Sym(out name, out kind);
+ if (kind == id) {
+ CharClass c = CharClass.Find(name);
+ if (c == null) {
+ SemErr("undefined name");
+ c = new CharClass(name, new BitArray(CharClass.charSetSize));
+ }
+ Node p = new Node(Node.clas, null, 0); p.val = c.n;
+ g = new Graph(p);
+ } else g = Graph.StrToGraph(name); // str
+
+ } else if (la.kind == 28) {
+ Get();
+ TokenExpr(out g);
+ Expect(29);
+ } else if (la.kind == 30) {
+ Get();
+ TokenExpr(out g);
+ Expect(31);
+ Graph.MakeOption(g);
+ } else if (la.kind == 32) {
+ Get();
+ TokenExpr(out g);
+ Expect(33);
+ Graph.MakeIteration(g);
+ } else SynErr(54);
+ }
+
+
+
+ public static void Parse() {
+ Errors.SynErr = new ErrorCodeProc(SynErr);
+ la = new Token();
+ la.val = "";
+ Get();
+ Coco();
+
+ }
+
+ static void SynErr (int line, int col, int n) {
+ Errors.count++;
+ string s;
+ switch (n) {
+ case 0: s = "EOF expected"; break;
+ case 1: s = "ident expected"; break;
+ case 2: s = "number expected"; break;
+ case 3: s = "string expected"; break;
+ case 4: s = "badString expected"; break;
+ case 5: s = "char expected"; break;
+ case 6: s = "\"COMPILER\" expected"; break;
+ case 7: s = "\"PRODUCTIONS\" expected"; break;
+ case 8: s = "\"=\" expected"; break;
+ case 9: s = "\".\" expected"; break;
+ case 10: s = "\"END\" expected"; break;
+ case 11: s = "\"CHARACTERS\" expected"; break;
+ case 12: s = "\"TOKENS\" expected"; break;
+ case 13: s = "\"PRAGMAS\" expected"; break;
+ case 14: s = "\"COMMENTS\" expected"; break;
+ case 15: s = "\"FROM\" expected"; break;
+ case 16: s = "\"TO\" expected"; break;
+ case 17: s = "\"NESTED\" expected"; break;
+ case 18: s = "\"IGNORE\" expected"; break;
+ case 19: s = "\"TOKENNAMES\" expected"; break;
+ case 20: s = "\"+\" expected"; break;
+ case 21: s = "\"-\" expected"; break;
+ case 22: s = "\"..\" expected"; break;
+ case 23: s = "\"ANY\" expected"; break;
+ case 24: s = "\"<\" expected"; break;
+ case 25: s = "\">\" expected"; break;
+ case 26: s = "\"|\" expected"; break;
+ case 27: s = "\"WEAK\" expected"; break;
+ case 28: s = "\"(\" expected"; break;
+ case 29: s = "\")\" expected"; break;
+ case 30: s = "\"[\" expected"; break;
+ case 31: s = "\"]\" expected"; break;
+ case 32: s = "\"{\" expected"; break;
+ case 33: s = "\"}\" expected"; break;
+ case 34: s = "\"SYNC\" expected"; break;
+ case 35: s = "\"IF\" expected"; break;
+ case 36: s = "\"!=\" expected"; break;
+ case 37: s = "\"CONTEXT\" expected"; break;
+ case 38: s = "\"(.\" expected"; break;
+ case 39: s = "\".)\" expected"; break;
+ case 40: s = "\"using\" expected"; break;
+ case 41: s = "\";\" expected"; break;
+ case 42: s = "??? expected"; break;
+ case 43: s = "this symbol not expected in Coco"; break;
+ case 44: s = "invalid Declaration"; break;
+ case 45: s = "invalid Declaration"; break;
+ case 46: s = "this symbol not expected in TokenDecl"; break;
+ case 47: s = "invalid TokenDecl"; break;
+ case 48: s = "invalid TokenDecl"; break;
+ case 49: s = "invalid SimSet"; break;
+ case 50: s = "invalid Sym"; break;
+ case 51: s = "invalid Term"; break;
+ case 52: s = "invalid ResolveExpr"; break;
+ case 53: s = "invalid Factor"; break;
+ case 54: s = "invalid TokenFactor"; break;
+
+ default: s = "error " + n; break;
+ }
+ Console.WriteLine(errMsgFormat, line, col, s);
+ }
+
+ static bool[,] set = {
+ {T,T,x,T, x,T,x,T, T,T,x,T, T,T,T,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x},
+ {x,T,T,T, T,T,T,x, T,T,T,x, x,x,x,T, T,T,x,x, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,x},
+ {x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {T,T,x,T, x,T,x,T, T,T,x,T, T,T,T,x, x,x,T,T, x,x,x,T, x,x,T,T, T,x,T,x, T,x,T,T, x,x,T,x, x,x,x,x},
+ {T,T,x,T, x,T,x,T, T,T,T,T, T,T,T,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x},
+ {x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,T,x},
+ {x,x,x,x, x,x,x,T, x,x,x,T, T,T,T,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,x},
+ {x,T,T,T, x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,x},
+ {x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,x, T,T,T,x},
+ {x,T,T,T, x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,x,x, T,T,T,x},
+ {x,T,x,T, x,T,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,T,T, T,T,T,T, T,T,T,T, x,x,T,x, x,x,x,x},
+ {x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x},
+ {T,T,x,T, x,T,x,T, T,T,x,T, T,T,T,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x},
+ {x,T,x,T, x,T,x,T, x,x,x,T, T,T,T,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x},
+ {x,T,x,T, x,T,x,T, x,x,x,T, T,T,T,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,T,x, T,x,x,x, x,x,x,x, x,x,x,x},
+ {x,x,x,x, x,x,x,T, x,T,x,T, T,T,T,x, T,T,T,T, x,x,x,x, x,x,x,x, x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x},
+ {x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,T, T,x,T,x, T,x,T,T, x,x,T,x, x,x,x,x},
+ {x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,T, T,x,T,x, T,x,T,x, x,x,T,x, x,x,x,x},
+ {x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x},
+ {x,T,T,T, T,T,T,T, x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, x,T,T,T, T,T,T,T, x,T,T,T, T,T,T,x},
+ {x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,T,T, T,T,T,T, T,T,T,T, T,T,T,x}
+
+ };
+} // end Parser
+
+}
Modified: trunk/MonoDevelop/src/Tools/SharpCoco/src/Parser.frame
===================================================================
--- trunk/MonoDevelop/src/Tools/SharpCoco/src/Parser.frame 2004-04-09 12:41:44 UTC (rev 1420)
+++ trunk/MonoDevelop/src/Tools/SharpCoco/src/Parser.frame 2004-04-09 17:17:47 UTC (rev 1421)
@@ -1,120 +1,120 @@
-using System;
-using System.Reflection;
-
--->namespace
-
--->tokens
-
-public class Parser
-{
--->constants
- const bool T = true;
- const bool x = false;
- const int minErrDist = 2;
- const string errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text
- int errDist = minErrDist;
- Errors errors;
- Lexer lexer;
-
- public Errors Errors {
- get {
- return errors;
- }
- }
-
--->declarations
-
-/*
--->pragmas
-*/
- void SynErr(int n)
- {
- if (errDist >= minErrDist) {
- errors.SynErr(lexer.LookAhead.line, lexer.LookAhead.col, n);
- }
- errDist = 0;
- }
-
- public void SemErr(string msg)
- {
- if (errDist >= minErrDist) {
- errors.Error(lexer.Token.line, lexer.Token.col, msg);
- }
- errDist = 0;
- }
-
- void Expect(int n)
- {
- if (lexer.LookAhead.kind == n) {
- lexer.NextToken();
- } else {
- SynErr(n);
- }
- }
-
- bool StartOf(int s)
- {
- return set[s, lexer.LookAhead.kind];
- }
-
- void ExpectWeak(int n, int follow)
- {
- if (lexer.LookAhead.kind == n) {
- lexer.NextToken();
- } else {
- SynErr(n);
- while (!StartOf(follow)) {
- lexer.NextToken();
- }
- }
- }
-
- bool WeakSeparator(int n, int syFol, int repFol)
- {
- bool[] s = new bool[maxT + 1];
-
- if (lexer.LookAhead.kind == n) {
- lexer.NextToken();
- return true;
- } else if (StartOf(repFol)) {
- return false;
- } else {
- for (int i = 0; i <= maxT; i++) {
- s[i] = set[syFol, i] || set[repFol, i] || set[0, i];
- }
- SynErr(n);
- while (!s[lexer.LookAhead.kind]) {
- lexer.NextToken();
- }
- return StartOf(syFol);
- }
- }
-
--->productions
-
- public void Parse(Lexer lexer)
- {
- this.errors = lexer.Errors;
- this.lexer = lexer;
- errors.SynErr = new ErrorCodeProc(SynErr);
- lexer.NextToken();
--->parseRoot
- }
-
- void SynErr(int line, int col, int errorNumber)
- {
- errors.count++;
- string s;
- switch (errorNumber) {
--->errors
- default: s = "error " + errorNumber; break;
- }
- errors.Error(line, col, s);
- }
-
- static bool[,] set = {
--->initialization
- };
-} // end Parser
-
-$$$
+using System;
+using System.Reflection;
+
+-->namespace
+
+-->tokens
+
+public class Parser
+{
+-->constants
+ const bool T = true;
+ const bool x = false;
+ const int minErrDist = 2;
+ const string errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text
+ int errDist = minErrDist;
+ Errors errors;
+ Lexer lexer;
+
+ public Errors Errors {
+ get {
+ return errors;
+ }
+ }
+
+-->declarations
+
+/*
+-->pragmas
+*/
+ void SynErr(int n)
+ {
+ if (errDist >= minErrDist) {
+ errors.SynErr(lexer.LookAhead.line, lexer.LookAhead.col, n);
+ }
+ errDist = 0;
+ }
+
+ public void SemErr(string msg)
+ {
+ if (errDist >= minErrDist) {
+ errors.Error(lexer.Token.line, lexer.Token.col, msg);
+ }
+ errDist = 0;
+ }
+
+ void Expect(int n)
+ {
+ if (lexer.LookAhead.kind == n) {
+ lexer.NextToken();
+ } else {
+ SynErr(n);
+ }
+ }
+
+ bool StartOf(int s)
+ {
+ return set[s, lexer.LookAhead.kind];
+ }
+
+ void ExpectWeak(int n, int follow)
+ {
+ if (lexer.LookAhead.kind == n) {
+ lexer.NextToken();
+ } else {
+ SynErr(n);
+ while (!StartOf(follow)) {
+ lexer.NextToken();
+ }
+ }
+ }
+
+ bool WeakSeparator(int n, int syFol, int repFol)
+ {
+ bool[] s = new bool[maxT + 1];
+
+ if (lexer.LookAhead.kind == n) {
+ lexer.NextToken();
+ return true;
+ } else if (StartOf(repFol)) {
+ return false;
+ } else {
+ for (int i = 0; i <= maxT; i++) {
+ s[i] = set[syFol, i] || set[repFol, i] || set[0, i];
+ }
+ SynErr(n);
+ while (!s[lexer.LookAhead.kind]) {
+ lexer.NextToken();
+ }
+ return StartOf(syFol);
+ }
+ }
+
+-->productions
+
+ public void Parse(Lexer lexer)
+ {
+ this.errors = lexer.Errors;
+ this.lexer = lexer;
+ errors.SynErr = new ErrorCodeProc(SynErr);
+ lexer.NextToken();
+-->parseRoot
+ }
+
+ void SynErr(int line, int col, int errorNumber)
+ {
+ errors.count++;
+ string s;
+ switch (errorNumber) {
+-->errors
+ default: s = "error " + errorNumber; break;
+ }
+ errors.Error(line, col, s);
+ }
+
+ static bool[,] set = {
+-->initialization
+ };
+} // end Parser
+
+$$$
Modified: trunk/MonoDevelop/src/Tools/SharpCoco/src/ParserGen.cs
===================================================================
--- trunk/MonoDevelop/src/Tools/SharpCoco/src/ParserGen.cs 2004-04-09 12:41:44 UTC (rev 1420)
+++ trunk/MonoDevelop/src/Tools/SharpCoco/src/ParserGen.cs 2004-04-09 17:17:47 UTC (rev 1421)
@@ -1,430 +1,430 @@
-// ParserGen.cs Parser generator of Coco/R H.Moessenboeck, Univ. of Linz
-//----------------------------------------------------------------------------
-using System;
-using System.IO;
-using System.Collections;
-using System.Text;
-
-namespace at.jku.ssw.Coco {
-
-public class ParserGen {
-
- const int maxTerm = 3; // sets of size < maxTerm are enumerated
- const char CR = '\r';
- const char LF = '\n';
- const char TAB = '\t';
- const int EOF = -1;
-
- const int tErr = 0; // error codes
- const int altErr = 1;
- const int syncErr = 2;
-
- public static Position usingPos; // "using" definitions from the attributed grammar
-
- static int errorNr; // highest parser error number
- static Symbol curSy; // symbol whose production is currently generated
- static FileStream fram; // parser frame file
- static StreamWriter gen; // generated parser source file
- static StringWriter err; // generated parser error messages
- static string srcName; // name of attributed grammar file
- static string srcDir; // directory of attributed grammar file
- static ArrayList symSet = new ArrayList();
-
- static void Indent (int n) {
- for (int i = 1; i <= n; i++) gen.Write('\t');
- }
-
- /* AW: this replaces the method int Alternatives (Node p) */
- static bool UseSwitch (Node p) {
- if (p.typ != Node.alt) return false;
- int nAlts = 0;
- while (p != null) {
- ++nAlts;
- // must not optimize with switch-statement, if alt uses a resolver expression
- if (p.sub.typ == Node.rslv) return false;
- p = p.down;
- }
- return nAlts > 5;
- }
-
- static void CopyFramePart (string stop) {
- char startCh = stop[0];
- int endOfStopString = stop.Length-1;
- int ch = fram.ReadByte();
- while (ch != EOF)
- if (ch == startCh) {
- int i = 0;
- do {
- if (i == endOfStopString) return; // stop[0..i] found
- ch = fram.ReadByte(); i++;
- } while (ch == stop[i]);
- // stop[0..i-1] found; continue with last read character
- gen.Write(stop.Substring(0, i));
- } else {
- gen.Write((char)ch); ch = fram.ReadByte();
- }
- Errors.Exception(" -- incomplete or corrupt parser frame file");
- }
-
- static void CopySourcePart (Position pos, int indent) {
- // Copy text described by pos from atg to gen
- int ch, nChars, i;
- if (pos != null) {
- Buffer.Pos = pos.beg; ch = Buffer.Read(); nChars = pos.len - 1;
-// CHANGES BY M.KRUEGER (#line pragma generation)
- gen.WriteLine();
- gen.WriteLine(String.Format("#line {0} \"{1}\" ", Buffer.CountLines(pos.beg) + 1, Buffer.fileName));
-// EOC
- Indent(indent);
- while (nChars >= 0) {
- while (ch == CR || ch == LF) { // eol is either CR or CRLF or LF
- gen.WriteLine(); Indent(indent);
- if (ch == CR) { ch = Buffer.Read(); nChars--; } // skip CR
- if (ch == LF) { ch = Buffer.Read(); nChars--; } // skip LF
- for (i = 1; i <= pos.col && ch <= ' '; i++) {
- // skip blanks at beginning of line
- ch = Buffer.Read(); nChars--;
- }
- if (i <= pos.col) pos.col = i - 1; // heading TABs => not enough blanks
- if (nChars < 0) goto done;
- }
- gen.Write((char)ch);
- ch = Buffer.Read(); nChars--;
- }
- done:
- if (indent > 0) gen.WriteLine();
- }
- }
-
- static void GenErrorMsg (int errTyp, Symbol sym) {
- errorNr++;
- err.Write("\t\t\tcase " + errorNr + ": s = \"");
- switch (errTyp) {
- case tErr:
- if (sym.name[0] == '"') err.Write(DFA.Escape(sym.name) + " expected");
- else err.Write(sym.name + " expected");
- break;
- case altErr: err.Write("invalid " + sym.name); break;
- case syncErr: err.Write("this symbol not expected in " + sym.name); break;
- }
- err.WriteLine("\"; break;");
- }
-
- static int NewCondSet (BitArray s) {
- for (int i = 1; i < symSet.Count; i++) // skip symSet[0] (reserved for union of SYNC sets)
- if (Sets.Equals(s, (BitArray)symSet[i])) return i;
- symSet.Add(s.Clone());
- return symSet.Count - 1;
- }
-
- static void GenCond (BitArray s, Node p) {
- if (p.typ == Node.rslv) CopySourcePart(p.pos, 0);
- else {
- GenCond(s);
- if (p.typ == Node.alt) {
- // for { ... | IF ... | ... } or [ ... | IF ... | ... ]
- // generate conditions: StartOf(...) || IF
- Node q = p;
- while (q != null) {
- if (q.sub.typ == Node.rslv) {
- gen.Write(" || ");
- CopySourcePart(q.sub.pos, 0);
- }
- q = q.down;
- }
- }
- }
- }
-
- static void GenCond (BitArray s) {
- int n = Sets.Elements(s);
- if (n == 0) gen.Write("false"); // should never happen
- else if (n <= maxTerm)
- foreach (Symbol sym in Symbol.terminals) {
- if (s[sym.n]) {
- gen.Write("la.kind == {0}", sym.n);
- --n;
- if (n > 0) gen.Write(" || ");
- }
- }
- else gen.Write("StartOf({0})", NewCondSet(s));
- }
-
- static void PutCaseLabels (BitArray s) {
- foreach (Symbol sym in Symbol.terminals)
- if (s[sym.n]) gen.Write("case {0}: ", sym.n);
- }
-
- static void GenCode (Node p, int indent, BitArray isChecked) {
- Node p2;
- BitArray s1, s2;
- while (p != null) {
- switch (p.typ) {
- case Node.nt: {
- Indent(indent);
- gen.Write(p.sym.name + "(");
- CopySourcePart(p.pos, 0);
- gen.WriteLine(");");
- break;
- }
- case Node.t: {
- Indent(indent);
- // M.Krueger: changed Get() to lexer.NextToken();
- if (isChecked[p.sym.n]) gen.WriteLine("lexer.NextToken();");
- else gen.WriteLine("Expect({0});", p.sym.n);
- break;
- }
- case Node.wt: {
- Indent(indent);
- s1 = Tab.Expected(p.next, curSy);
- s1.Or(Tab.allSyncSets);
- gen.WriteLine("ExpectWeak({0}, {1});", p.sym.n, NewCondSet(s1));
- break;
- }
- case Node.any: {
- Indent(indent);
- // M.Krueger: changed Get() to lexer.NextToken();
- gen.WriteLine("lexer.NextToken();");
- break;
- }
- case Node.eps: break; // nothing
- case Node.sem: {
- CopySourcePart(p.pos, indent);
- break;
- }
- case Node.sync: {
- Indent(indent);
- GenErrorMsg(syncErr, curSy);
- s1 = (BitArray)p.set.Clone();
- gen.Write("while (!("); GenCond(s1); gen.Write(")) {");
- // M.Krueger: changed Get() to lexer.NextToken();
- gen.Write("SynErr({0}); lexer.NextToken(); ", errorNr); gen.WriteLine("}");
- break;
- }
- case Node.alt: {
- s1 = Tab.First(p);
- bool equal = Sets.Equals(s1, isChecked);
- bool useSwitch = UseSwitch(p);
- if (useSwitch) { Indent(indent); gen.WriteLine("switch (la.kind) {"); }
- p2 = p;
- while (p2 != null) {
- s1 = Tab.Expected(p2.sub, curSy, 1);
- Indent(indent);
- if (useSwitch) { PutCaseLabels(s1); gen.WriteLine("{"); }
- else if (p2 == p) {
- gen.Write("if ("); GenCond(s1, p2.sub); gen.WriteLine(") {");
- } else if (p2.down == null && equal) { gen.WriteLine("} else {");
- } else {
- gen.Write("} else if ("); GenCond(s1, p2.sub); gen.WriteLine(") {");
- }
- s1.Or(isChecked);
- if (p2.sub.typ != Node.rslv) GenCode(p2.sub, indent + 1, s1);
- else GenCode(p2.sub.next, indent + 1, s1);
- if (useSwitch) {
- Indent(indent); gen.WriteLine("\tbreak;");
- Indent(indent); gen.WriteLine("}");
- }
- p2 = p2.down;
- }
- Indent(indent);
- if (equal) {
- gen.WriteLine("}");
- } else {
- GenErrorMsg(altErr, curSy);
- if (useSwitch) {
- gen.WriteLine("default: SynErr({0}); break;", errorNr);
- Indent(indent); gen.WriteLine("}");
- } else {
- gen.Write("} "); gen.WriteLine("else SynErr({0});", errorNr);
- }
- }
- break;
- }
- case Node.iter: {
- Indent(indent);
- p2 = p.sub;
- gen.Write("while (");
- if (p2.typ == Node.wt) {
- s1 = Tab.Expected(p2.next, curSy);
- s2 = Tab.Expected(p.next, curSy);
- gen.Write("WeakSeparator({0},{1},{2}) ", p2.sym.n, NewCondSet(s1), NewCondSet(s2));
- s1 = new BitArray(Symbol.terminals.Count); // for inner structure
- if (p2.up || p2.next == null) p2 = null; else p2 = p2.next;
- } else {
- s1 = Tab.First(p2);
- GenCond(s1, p2);
- }
- gen.WriteLine(") {");
- GenCode(p2, indent + 1, s1);
- Indent(indent);
- gen.WriteLine("}");
- break;
- }
- case Node.opt:
- if (p.sub.typ != Node.rslv) s1 = Tab.First(p.sub);
- else s1 = Tab.First(p.sub.next);
- if (!Sets.Equals(isChecked, s1)) {
- Indent(indent);
- gen.Write("if ("); GenCond(s1, p.sub); gen.WriteLine(") {");
- if (p.sub.typ != Node.rslv) GenCode(p.sub, indent + 1, s1);
- else GenCode(p.sub.next, indent + 1, s1);
- Indent(indent); gen.WriteLine("}");
- } else GenCode(p.sub, indent, isChecked);
- break;
- }
- if (p.typ != Node.eps && p.typ != Node.sem && p.typ != Node.sync)
- isChecked.SetAll(false); // = new BitArray(Symbol.terminals.Count);
- if (p.up) break;
- p = p.next;
- }
- }
-
- /* ML 2002-09-07 Generates the class "Tokens" *
- * which maps the token number to meaningfully named integer constants, *
- * as specified in the NAMES section. */
- static void GenTokens() {
- if (Symbol.tokenNames != null && Symbol.tokenNames.Count > 0) {
-
- gen.WriteLine("public class Tokens {");
-
- foreach (DictionaryEntry entry in Symbol.tokenNames) {
- string token = entry.Key as string;
- string name = entry.Value as string;
- if (IsCSharpKW(name)) {
- Parser.SemErr(name + " is a C# keyword." +
- "Use another name for the token " + token);
- continue;
- }
-
- Symbol sym = Symbol.Find(token);
- if (sym != null && (sym.typ == Node.t || sym.typ == Node.wt))
- gen.WriteLine("\tpublic const int {0} = {1};", name, sym.n);
- }
-
- gen.WriteLine("}");
- }
- }
-
- /* AW 03-01-20 to generate token name: *
- * a C# keyword must not be used as an identifier */
- static bool IsCSharpKW (string name) {
- return Array.BinarySearch(csKeywords, name) >= 0;
- }
-
- static string[] csKeywords = new string[] {
- "abstract", "as", "base", "bool", "break", "byte",
- "case", "catch", "char", "checked", "class", "const",
- "continue", "decimal", "default", "delegate", "do", "double",
- "else", "enum", "event", "explicit", "extern", "false",
- "finally", "fixed", "float", "for", "foreach", "goto",
- "if", "implicit", "in", "int", "interface", "internal",
- "is", "lock", "long", "namespace", "new", "null",
- "object", "operator", "out", "override", "params", "private",
- "protected", "public", "readonly", "ref", "return", "sbyte",
- "sealed", "short", "sizeof", "stackalloc", "static", "string",
- "struct", "switch", "this", "throw", "true", "try",
- "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort",
- "using", "virtual", "void", "volatile", "while"
- };
-
- static void GenCodePragmas() {
- foreach (Symbol sym in Symbol.pragmas) {
- gen.WriteLine("\t\t\t\tif (la.kind == {0}) {{", sym.n);
- CopySourcePart(sym.semPos, 4);
- gen.WriteLine("\t\t\t\t}");
- }
- }
-
- static void GenProductions() {
- foreach (Symbol sym in Symbol.nonterminals) {
- curSy = sym;
- gen.Write("\tvoid {0}(", sym.name);
- CopySourcePart(sym.attrPos, 0);
- gen.WriteLine(") {");
- CopySourcePart(sym.semPos, 2);
- GenCode(sym.graph, 2, new BitArray(Symbol.terminals.Count));
- gen.WriteLine("\t}"); gen.WriteLine();
- }
- }
-
- static void InitSets() {
- for (int i = 0; i < symSet.Count; i++) {
- BitArray s = (BitArray)symSet[i];
- gen.Write("\t{");
- int j = 0;
- foreach (Symbol sym in Symbol.terminals) {
- if (s[sym.n]) gen.Write("T,"); else gen.Write("x,");
- ++j;
- if (j%4 == 0) gen.Write(" ");
- }
- if (i == symSet.Count-1) gen.WriteLine("x}"); else gen.WriteLine("x},");
- }
- }
-
- public static void WriteParser () {
- FileStream s;
- symSet.Add(Tab.allSyncSets);
- string fr = srcDir + "Parser.frame";
- if (!File.Exists(fr)) {
- string frameDir = Environment.GetEnvironmentVariable("crframes");
- if (frameDir != null) fr = frameDir.Trim() + "\\Parser.frame";
- if (!File.Exists(fr)) Errors.Exception("-- Cannot find Parser.frame");
- }
- try {
- fram = new FileStream(fr, FileMode.Open, FileAccess.Read, FileShare.Read);
- } catch (IOException) {
- Errors.Exception("-- Cannot open Parser.frame.");
- }
- try {
- string fn = srcDir + "Parser.cs";
- if (File.Exists(fn)) File.Copy(fn, fn.Replace(".cs", ".old.cs"), true);
- s = new FileStream(fn, FileMode.Create);
- gen = new StreamWriter(s);
- } catch (IOException) {
- Errors.Exception("-- Cannot generate parser file");
- }
- err = new StringWriter();
- foreach (Symbol sym in Symbol.terminals) GenErrorMsg(tErr, sym);
- if (usingPos != null) CopySourcePart(usingPos, 0);
- gen.WriteLine();
- CopyFramePart("-->namespace");
- /* AW open namespace, if it exists */
- if (Tab.nsName != null && Tab.nsName.Length > 0) {
- gen.Write("namespace ");
- gen.Write(Tab.nsName);
- gen.Write(" {");
- }
- CopyFramePart("-->tokens"); GenTokens(); /* ML 2002/09/07 write the tokenkinds */
- CopyFramePart("-->constants");
- gen.WriteLine("\tconst int maxT = {0};", Symbol.terminals.Count-1);
- CopyFramePart("-->declarations"); CopySourcePart(Tab.semDeclPos, 0);
- CopyFramePart("-->pragmas"); GenCodePragmas();
- CopyFramePart("-->productions"); GenProductions();
- CopyFramePart("-->parseRoot"); gen.WriteLine("\t\t{0}();", Tab.gramSy.name);
- CopyFramePart("-->errors"); gen.Write(err.ToString());
- CopyFramePart("-->initialization"); InitSets();
- CopyFramePart("$$$");
- /* AW 2002-12-20 close namespace, if it exists */
- if (Tab.nsName != null && Tab.nsName.Length > 0) gen.Write("}");
- gen.Close();
- }
-
- public static void WriteStatistics () {
- Trace.WriteLine();
- Trace.WriteLine("{0} terminals", Symbol.terminals.Count);
- Trace.WriteLine("{0} symbols", Symbol.terminals.Count + Symbol.pragmas.Count +
- Symbol.nonterminals.Count);
- Trace.WriteLine("{0} nodes", Node.nodes.Count);
- Trace.WriteLine("{0} sets", symSet.Count);
- }
-
- public static void Init (string file, string dir) {
- srcName = file;
- srcDir = dir;
- errorNr = -1;
- usingPos = null;
- }
-
-} // end ParserGen
-
-} // end namespace
+// ParserGen.cs Parser generator of Coco/R H.Moessenboeck, Univ. of Linz
+//----------------------------------------------------------------------------
+using System;
+using System.IO;
+using System.Collections;
+using System.Text;
+
+namespace at.jku.ssw.Coco {
+
+public class ParserGen {
+
+ const int maxTerm = 3; // sets of size < maxTerm are enumerated
+ const char CR = '\r';
+ const char LF = '\n';
+ const char TAB = '\t';
+ const int EOF = -1;
+
+ const int tErr = 0; // error codes
+ const int altErr = 1;
+ const int syncErr = 2;
+
+ public static Position usingPos; // "using" definitions from the attributed grammar
+
+ static int errorNr; // highest parser error number
+ static Symbol curSy; // symbol whose production is currently generated
+ static FileStream fram; // parser frame file
+ static StreamWriter gen; // generated parser source file
+ static StringWriter err; // generated parser error messages
+ static string srcName; // name of attributed grammar file
+ static string srcDir; // directory of attributed grammar file
+ static ArrayList symSet = new ArrayList();
+
+ static void Indent (int n) {
+ for (int i = 1; i <= n; i++) gen.Write('\t');
+ }
+
+ /* AW: this replaces the method int Alternatives (Node p) */
+ static bool UseSwitch (Node p) {
+ if (p.typ != Node.alt) return false;
+ int nAlts = 0;
+ while (p != null) {
+ ++nAlts;
+ // must not optimize with switch-statement, if alt uses a resolver expression
+ if (p.sub.typ == Node.rslv) return false;
+ p = p.down;
+ }
+ return nAlts > 5;
+ }
+
+ static void CopyFramePart (string stop) {
+ char startCh = stop[0];
+ int endOfStopString = stop.Length-1;
+ int ch = fram.ReadByte();
+ while (ch != EOF)
+ if (ch == startCh) {
+ int i = 0;
+ do {
+ if (i == endOfStopString) return; // stop[0..i] found
+ ch = fram.ReadByte(); i++;
+ } while (ch == stop[i]);
+ // stop[0..i-1] found; continue with last read character
+ gen.Write(stop.Substring(0, i));
+ } else {
+ gen.Write((char)ch); ch = fram.ReadByte();
+ }
+ Errors.Exception(" -- incomplete or corrupt parser frame file");
+ }
+
+ static void CopySourcePart (Position pos, int indent) {
+ // Copy text described by pos from atg to gen
+ int ch, nChars, i;
+ if (pos != null) {
+ Buffer.Pos = pos.beg; ch = Buffer.Read(); nChars = pos.len - 1;
+// CHANGES BY M.KRUEGER (#line pragma generation)
+ gen.WriteLine();
+ gen.WriteLine(String.Format("#line {0} \"{1}\" ", Buffer.CountLines(pos.beg) + 1, Buffer.fileName));
+// EOC
+ Indent(indent);
+ while (nChars >= 0) {
+ while (ch == CR || ch == LF) { // eol is either CR or CRLF or LF
+ gen.WriteLine(); Indent(indent);
+ if (ch == CR) { ch = Buffer.Read(); nChars--; } // skip CR
+ if (ch == LF) { ch = Buffer.Read(); nChars--; } // skip LF
+ for (i = 1; i <= pos.col && ch <= ' '; i++) {
+ // skip blanks at beginning of line
+ ch = Buffer.Read(); nChars--;
+ }
+ if (i <= pos.col) pos.col = i - 1; // heading TABs => not enough blanks
+ if (nChars < 0) goto done;
+ }
+ gen.Write((char)ch);
+ ch = Buffer.Read(); nChars--;
+ }
+ done:
+ if (indent > 0) gen.WriteLine();
+ }
+ }
+
+ static void GenErrorMsg (int errTyp, Symbol sym) {
+ errorNr++;
+ err.Write("\t\t\tcase " + errorNr + ": s = \"");
+ switch (errTyp) {
+ case tErr:
+ if (sym.name[0] == '"') err.Write(DFA.Escape(sym.name) + " expected");
+ else err.Write(sym.name + " expected");
+ break;
+ case altErr: err.Write("invalid " + sym.name); break;
+ case syncErr: err.Write("this symbol not expected in " + sym.name); break;
+ }
+ err.WriteLine("\"; break;");
+ }
+
+ static int NewCondSet (BitArray s) {
+ for (int i = 1; i < symSet.Count; i++) // skip symSet[0] (reserved for union of SYNC sets)
+ if (Sets.Equals(s, (BitArray)symSet[i])) return i;
+ symSet.Add(s.Clone());
+ return symSet.Count - 1;
+ }
+
+ static void GenCond (BitArray s, Node p) {
+ if (p.typ == Node.rslv) CopySourcePart(p.pos, 0);
+ else {
+ GenCond(s);
+ if (p.typ == Node.alt) {
+ // for { ... | IF ... | ... } or [ ... | IF ... | ... ]
+ // generate conditions: StartOf(...) || IF
+ Node q = p;
+ while (q != null) {
+ if (q.sub.typ == Node.rslv) {
+ gen.Write(" || ");
+ CopySourcePart(q.sub.pos, 0);
+ }
+ q = q.down;
+ }
+ }
+ }
+ }
+
+ static void GenCond (BitArray s) {
+ int n = Sets.Elements(s);
+ if (n == 0) gen.Write("false"); // should never happen
+ else if (n <= maxTerm)
+ foreach (Symbol sym in Symbol.terminals) {
+ if (s[sym.n]) {
+ gen.Write("la.kind == {0}", sym.n);
+ --n;
+ if (n > 0) gen.Write(" || ");
+ }
+ }
+ else gen.Write("StartOf({0})", NewCondSet(s));
+ }
+
+ static void PutCaseLabels (BitArray s) {
+ foreach (Symbol sym in Symbol.terminals)
+ if (s[sym.n]) gen.Write("case {0}: ", sym.n);
+ }
+
+ static void GenCode (Node p, int indent, BitArray isChecked) {
+ Node p2;
+ BitArray s1, s2;
+ while (p != null) {
+ switch (p.typ) {
+ case Node.nt: {
+ Indent(indent);
+ gen.Write(p.sym.name + "(");
+ CopySourcePart(p.pos, 0);
+ gen.WriteLine(");");
+ break;
+ }
+ case Node.t: {
+ Indent(indent);
+ // M.Krueger: changed Get() to lexer.NextToken();
+ if (isChecked[p.sym.n]) gen.WriteLine("lexer.NextToken();");
+ else gen.WriteLine("Expect({0});", p.sym.n);
+ break;
+ }
+ case Node.wt: {
+ Indent(indent);
+ s1 = Tab.Expected(p.next, curSy);
+ s1.Or(Tab.allSyncSets);
+ gen.WriteLine("ExpectWeak({0}, {1});", p.sym.n, NewCondSet(s1));
+ break;
+ }
+ case Node.any: {
+ Indent(indent);
+ // M.Krueger: changed Get() to lexer.NextToken();
+ gen.WriteLine("lexer.NextToken();");
+ break;
+ }
+ case Node.eps: break; // nothing
+ case Node.sem: {
+ CopySourcePart(p.pos, indent);
+ break;
+ }
+ case Node.sync: {
+ Indent(indent);
+ GenErrorMsg(syncErr, curSy);
+ s1 = (BitArray)p.set.Clone();
+ gen.Write("while (!("); GenCond(s1); gen.Write(")) {");
+ // M.Krueger: changed Get() to lexer.NextToken();
+ gen.Write("SynErr({0}); lexer.NextToken(); ", errorNr); gen.WriteLine("}");
+ break;
+ }
+ case Node.alt: {
+ s1 = Tab.First(p);
+ bool equal = Sets.Equals(s1, isChecked);
+ bool useSwitch = UseSwitch(p);
+ if (useSwitch) { Indent(indent); gen.WriteLine("switch (la.kind) {"); }
+ p2 = p;
+ while (p2 != null) {
+ s1 = Tab.Expected(p2.sub, curSy, 1);
+ Indent(indent);
+ if (useSwitch) { PutCaseLabels(s1); gen.WriteLine("{"); }
+ else if (p2 == p) {
+ gen.Write("if ("); GenCond(s1, p2.sub); gen.WriteLine(") {");
+ } else if (p2.down == null && equal) { gen.WriteLine("} else {");
+ } else {
+ gen.Write("} else if ("); GenCond(s1, p2.sub); gen.WriteLine(") {");
+ }
+ s1.Or(isChecked);
+ if (p2.sub.typ != Node.rslv) GenCode(p2.sub, indent + 1, s1);
+ else GenCode(p2.sub.next, indent + 1, s1);
+ if (useSwitch) {
+ Indent(indent); gen.WriteLine("\tbreak;");
+ Indent(indent); gen.WriteLine("}");
+ }
+ p2 = p2.down;
+ }
+ Indent(indent);
+ if (equal) {
+ gen.WriteLine("}");
+ } else {
+ GenErrorMsg(altErr, curSy);
+ if (useSwitch) {
+ gen.WriteLine("default: SynErr({0}); break;", errorNr);
+ Indent(indent); gen.WriteLine("}");
+ } else {
+ gen.Write("} "); gen.WriteLine("else SynErr({0});", errorNr);
+ }
+ }
+ break;
+ }
+ case Node.iter: {
+ Indent(indent);
+ p2 = p.sub;
+ gen.Write("while (");
+ if (p2.typ == Node.wt) {
+ s1 = Tab.Expected(p2.next, curSy);
+ s2 = Tab.Expected(p.next, curSy);
+ gen.Write("WeakSeparator({0},{1},{2}) ", p2.sym.n, NewCondSet(s1), NewCondSet(s2));
+ s1 = new BitArray(Symbol.terminals.Count); // for inner structure
+ if (p2.up || p2.next == null) p2 = null; else p2 = p2.next;
+ } else {
+ s1 = Tab.First(p2);
+ GenCond(s1, p2);
+ }
+ gen.WriteLine(") {");
+ GenCode(p2, indent + 1, s1);
+ Indent(indent);
+ gen.WriteLine("}");
+ break;
+ }
+ case Node.opt:
+ if (p.sub.typ != Node.rslv) s1 = Tab.First(p.sub);
+ else s1 = Tab.First(p.sub.next);
+ if (!Sets.Equals(isChecked, s1)) {
+ Indent(indent);
+ gen.Write("if ("); GenCond(s1, p.sub); gen.WriteLine(") {");
+ if (p.sub.typ != Node.rslv) GenCode(p.sub, indent + 1, s1);
+ else GenCode(p.sub.next, indent + 1, s1);
+ Indent(indent); gen.WriteLine("}");
+ } else GenCode(p.sub, indent, isChecked);
+ break;
+ }
+ if (p.typ != Node.eps && p.typ != Node.sem && p.typ != Node.sync)
+ isChecked.SetAll(false); // = new BitArray(Symbol.terminals.Count);
+ if (p.up) break;
+ p = p.next;
+ }
+ }
+
+ /* ML 2002-09-07 Generates the class "Tokens" *
+ * which maps the token number to meaningfully named integer constants, *
+ * as specified in the NAMES section. */
+ static void GenTokens() {
+ if (Symbol.tokenNames != null && Symbol.tokenNames.Count > 0) {
+
+ gen.WriteLine("public class Tokens {");
+
+ foreach (DictionaryEntry entry in Symbol.tokenNames) {
+ string token = entry.Key as string;
+ string name = entry.Value as string;
+ if (IsCSharpKW(name)) {
+ Parser.SemErr(name + " is a C# keyword." +
+ "Use another name for the token " + token);
+ continue;
+ }
+
+ Symbol sym = Symbol.Find(token);
+ if (sym != null && (sym.typ == Node.t || sym.typ == Node.wt))
+ gen.WriteLine("\tpublic const int {0} = {1};", name, sym.n);
+ }
+
+ gen.WriteLine("}");
+ }
+ }
+
+ /* AW 03-01-20 to generate token name: *
+ * a C# keyword must not be used as an identifier */
+ static bool IsCSharpKW (string name) {
+ return Array.BinarySearch(csKeywords, name) >= 0;
+ }
+
+ static string[] csKeywords = new string[] {
+ "abstract", "as", "base", "bool", "break", "byte",
+ "case", "catch", "char", "checked", "class", "const",
+ "continue", "decimal", "default", "delegate", "do", "double",
+ "else", "enum", "event", "explicit", "extern", "false",
+ "finally", "fixed", "float", "for", "foreach", "goto",
+ "if", "implicit", "in", "int", "interface", "internal",
+ "is", "lock", "long", "namespace", "new", "null",
+ "object", "operator", "out", "override", "params", "private",
+ "protected", "public", "readonly", "ref", "return", "sbyte",
+ "sealed", "short", "sizeof", "stackalloc", "static", "string",
+ "struct", "switch", "this", "throw", "true", "try",
+ "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort",
+ "using", "virtual", "void", "volatile", "while"
+ };
+
+ static void GenCodePragmas() {
+ foreach (Symbol sym in Symbol.pragmas) {
+ gen.WriteLine("\t\t\t\tif (la.kind == {0}) {{", sym.n);
+ CopySourcePart(sym.semPos, 4);
+ gen.WriteLine("\t\t\t\t}");
+ }
+ }
+
+ static void GenProductions() {
+ foreach (Symbol sym in Symbol.nonterminals) {
+ curSy = sym;
+ gen.Write("\tvoid {0}(", sym.name);
+ CopySourcePart(sym.attrPos, 0);
+ gen.WriteLine(") {");
+ CopySourcePart(sym.semPos, 2);
+ GenCode(sym.graph, 2, new BitArray(Symbol.terminals.Count));
+ gen.WriteLine("\t}"); gen.WriteLine();
+ }
+ }
+
+ static void InitSets() {
+ for (int i = 0; i < symSet.Count; i++) {
+ BitArray s = (BitArray)symSet[i];
+ gen.Write("\t{");
+ int j = 0;
+ foreach (Symbol sym in Symbol.terminals) {
+ if (s[sym.n]) gen.Write("T,"); else gen.Write("x,");
+ ++j;
+ if (j%4 == 0) gen.Write(" ");
+ }
+ if (i == symSet.Count-1) gen.WriteLine("x}"); else gen.WriteLine("x},");
+ }
+ }
+
+ public static void WriteParser () {
+ FileStream s;
+ symSet.Add(Tab.allSyncSets);
+ string fr = srcDir + "Parser.frame";
+ if (!File.Exists(fr)) {
+ string frameDir = Environment.GetEnvironmentVariable("crframes");
+ if (frameDir != null) fr = frameDir.Trim() + "\\Parser.frame";
+ if (!File.Exists(fr)) Errors.Exception("-- Cannot find Parser.frame");
+ }
+ try {
+ fram = new FileStream(fr, FileMode.Open, FileAccess.Read, FileShare.Read);
+ } catch (IOException) {
+ Errors.Exception("-- Cannot open Parser.frame.");
+ }
+ try {
+ string fn = srcDir + "Parser.cs";
+ if (File.Exists(fn)) File.Copy(fn, fn.Replace(".cs", ".old.cs"), true);
+ s = new FileStream(fn, FileMode.Create);
+ gen = new StreamWriter(s);
+ } catch (IOException) {
+ Errors.Exception("-- Cannot generate parser file");
+ }
+ err = new StringWriter();
+ foreach (Symbol sym in Symbol.terminals) GenErrorMsg(tErr, sym);
+ if (usingPos != null) CopySourcePart(usingPos, 0);
+ gen.WriteLine();
+ CopyFramePart("-->namespace");
+ /* AW open namespace, if it exists */
+ if (Tab.nsName != null && Tab.nsName.Length > 0) {
+ gen.Write("namespace ");
+ gen.Write(Tab.nsName);
+ gen.Write(" {");
+ }
+ CopyFramePart("-->tokens"); GenTokens(); /* ML 2002/09/07 write the tokenkinds */
+ CopyFramePart("-->constants");
+ gen.WriteLine("\tconst int maxT = {0};", Symbol.terminals.Count-1);
+ CopyFramePart("-->declarations"); CopySourcePart(Tab.semDeclPos, 0);
+ CopyFramePart("-->pragmas"); GenCodePragmas();
+ CopyFramePart("-->productions"); GenProductions();
+ CopyFramePart("-->parseRoot"); gen.WriteLine("\t\t{0}();", Tab.gramSy.name);
+ CopyFramePart("-->errors"); gen.Write(err.ToString());
+ CopyFramePart("-->initialization"); InitSets();
+ CopyFramePart("$$$");
+ /* AW 2002-12-20 close namespace, if it exists */
+ if (Tab.nsName != null && Tab.nsName.Length > 0) gen.Write("}");
+ gen.Close();
+ }
+
+ public static void WriteStatistics () {
+ Trace.WriteLine();
+ Trace.WriteLine("{0} terminals", Symbol.terminals.Count);
+ Trace.WriteLine("{0} symbols", Symbol.terminals.Count + Symbol.pragmas.Count +
+ Symbol.nonterminals.Count);
+ Trace.WriteLine("{0} nodes", Node.nodes.Count);
+ Trace.WriteLine("{0} sets", symSet.Count);
+ }
+
+ public static void Init (string file, string dir) {
+ srcName = file;
+ srcDir = dir;
+ errorNr = -1;
+ usingPos = null;
+ }
+
+} // end ParserGen
+
+} // end namespace
Modified: trunk/MonoDevelop/src/Tools/SharpCoco/src/Scanner.cs
===================================================================
--- trunk/MonoDevelop/src/Tools/SharpCoco/src/Scanner.cs 2004-04-09 12:41:44 UTC (rev 1420)
+++ trunk/MonoDevelop/src/Tools/SharpCoco/src/Scanner.cs 2004-04-09 17:17:47 UTC (rev 1421)
@@ -1,688 +1,688 @@
-using System;
-
-using System.IO;
-
-using System.Collections;
-
-using System.Text;
-
-
-
-namespace at.jku.ssw.Coco {
-
-
-
-public class Token {
-
- public int kind; // token kind
-
- public int pos; // token position in the source text (starting at 0)
-
- public int col; // token column (starting at 0)
-
- public int line; // token line (starting at 1)
-
- public string val; // token value
-
- public Token next; // AW 2003-03-07 Tokens are kept in linked list
-
-
-
- public Token () { }
-
- public Token (int kind) { this.kind = kind; }
-
-}
-
-
-
-public class Buffer {
-
- public const int eof = '\uffff';
-
- static byte[] buf;
- static int bufLen;
- static int pos;
- public static string fileName;
-
- public static int CountLines(int offset)
- {
- int line = 0;
- for (int i = 0; i <= offset; ++i) {
- if (buf[i] == '\n') {
- ++line;
- }
- }
- return line;
- }
-
- public static void Fill (string fileName) {
- Buffer.fileName = fileName;
- FileStream s = null;
- try {
- s = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
- bufLen = (int) s.Length;
- buf = new byte[bufLen];
- s.Read(buf, 0, bufLen);
- pos = 0;
-
- } catch (IOException) {
-
- Console.WriteLine("--- Cannot open file {0}", fileName);
-
- System.Environment.Exit(0);
-
- } finally {
-
- if (s != null) s.Close();
-
- }
-
- }
-
-
-
- public static int Read () {
-
- if (pos < bufLen) return buf[pos++];
-
- else return 0;
-
- }
-
-
-
- public static int Peek () {
-
- if (pos < bufLen) return buf[pos];
-
- else return 0;
-
- }
-
-
-
- /* AW 2003-03-10 moved this from ParserGen.cs */
-
- public static string GetString (int beg, int end) {
-
- StringBuilder s = new StringBuilder(64);
-
- int oldPos = Buffer.Pos;
-
- Buffer.Pos = beg;
-
- while (beg < end) { s.Append((char)Buffer.Read()); beg++; }
-
- Buffer.Pos = oldPos;
-
- return s.ToString();
-
- }
-
-
-
- public static int Pos {
-
- get { return pos; }
-
- set {
-
- if (value < 0) pos = 0;
-
- else if (value >= bufLen) pos = bufLen;
-
- else pos = value;
-
- }
-
- }
-
-}
-
-
-
-public class Scanner {
-
- const char EOF = '\0';
-
- const char EOL = '\n';
-
- const int maxT = 42;
-
-
-
-
-
- const int noSym = 42;
-
- static short[] start = {
-
- 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
- 0, 27, 11, 0, 10, 0, 0, 5, 21, 22, 0, 15, 0, 16, 14, 0,
-
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 31, 18, 13, 19, 0,
-
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23, 0, 24, 0, 0,
-
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 25, 20, 26, 0, 0,
-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
- 0};
-
-
-
-
-
- static Token t; // current token
-
- static char ch; // current input character
-
- static int pos; // column number of current character
-
- static int line; // line number of current character
-
- static int lineStart; // start position of current line
-
- static int oldEols; // EOLs that appeared in a comment;
-
- static BitArray ignore; // set of characters to be ignored by the scanner
-
-
-
- /* ML ----- begin */
-
- static Token tokens; // the complete input token stream
-
- static Token pt; // current peek token
-
-
-
- static int peekCount = 0;
-
-
-
- public static int PeekCount { get { return peekCount; } }
-
-
-
- public static void Init (String fileName) {
-
- Buffer.Fill(fileName);
-
- pos = -1; line = 1; lineStart = 0;
-
- oldEols = 0;
-
- NextCh();
-
- ignore = new BitArray(256);
-
- ignore[9] = true; ignore[10] = true; ignore[13] = true; ignore[32] = true;
-
-
-
-
-
- /* AW 2003-03-07 fill token list */
-
- tokens = new Token(); // first token is a dummy
-
- Token node = tokens;
-
- do {
-
- node.next = NextToken();
-
- node = node.next;
-
- } while (node.kind != 0); /* AW: 0 => EOF */
-
- t = pt = tokens;
-
- }
-
-
-
- static void NextCh() {
-
- if (oldEols > 0) { ch = EOL; oldEols--; }
-
- else {
-
- ch = (char)Buffer.Read(); pos++;
-
- // replace isolated '\r' by '\n' in order to make
-
- // eol handling uniform across Windows, Unix and Mac
-
- if (ch == '\r' && Buffer.Peek() != '\n') ch = EOL;
-
- else if (ch > '\u007f') ch = '?';
-
- if (ch == EOL) { line++; lineStart = pos + 1; }
-
- }
-
- }
-
-
-
-
- static bool Comment0() {
-
- int level = 1, line0 = line, lineStart0 = lineStart;
-
- NextCh();
-
- if (ch == '*') {
-
- NextCh();
-
- for(;;) {
-
- if (ch == '*') {
-
- NextCh();
-
- if (ch == '/') {
-
- level--;
-
- if (level == 0) { oldEols = line - line0; NextCh(); return true; }
-
- NextCh();
-
- }
-
- } else if (ch == '/') {
-
- NextCh();
-
- if (ch == '*') {
-
- level++; NextCh();
-
- }
-
- } else if (ch == EOF) return false;
-
- else NextCh();
-
- }
-
- } else {
-
- if (ch==EOL) {line--; lineStart = lineStart0;}
-
- pos = pos - 2; Buffer.Pos = pos+1; NextCh();
-
- }
-
- return false;
-
- }
-
-
-
-
-
- static void CheckLiteral() {
-
- switch (t.val) {
-
- case "COMPILER": t.kind = 6; break;
-
- case "PRODUCTIONS": t.kind = 7; break;
-
- case "END": t.kind = 10; break;
-
- case "CHARACTERS": t.kind = 11; break;
-
- case "TOKENS": t.kind = 12; break;
-
- case "PRAGMAS": t.kind = 13; break;
-
- case "COMMENTS": t.kind = 14; break;
-
- case "FROM": t.kind = 15; break;
-
- case "TO": t.kind = 16; break;
-
- case "NESTED": t.kind = 17; break;
-
- case "IGNORE": t.kind = 18; break;
-
- case "TOKENNAMES": t.kind = 19; break;
-
- case "ANY": t.kind = 23; break;
-
- case "WEAK": t.kind = 27; break;
-
- case "SYNC": t.kind = 34; break;
-
- case "IF": t.kind = 35; break;
-
- case "CONTEXT": t.kind = 37; break;
-
- case "using": t.kind = 40; break;
-
- default: break;
-
-
-
- }
-
- }
-
-
-
- /* AW Scan() renamed to NextToken() */
-
- static Token NextToken() {
-
- while (ignore[ch]) NextCh();
-
- if (ch == '/' && Comment0()) return NextToken();
-
- t = new Token();
-
- t.pos = pos; t.col = pos - lineStart + 1; t.line = line;
-
- int state = start[ch];
-
- StringBuilder buf = new StringBuilder(16);
-
- buf.Append(ch); NextCh();
-
-
-
- switch (state) {
-
- case 0: { t.kind = noSym; goto done; } // NextCh already done
-
- case 1:
-
- if ((ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')) {buf.Append(ch); NextCh(); goto case 1;}
-
- else {t.kind = 1; t.val = buf.ToString(); CheckLiteral(); return t;}
-
- case 2:
-
- if ((ch >= '0' && ch <= '9')) {buf.Append(ch); NextCh(); goto case 2;}
-
- else {t.kind = 2; goto done;}
-
- case 3:
-
- {t.kind = 3; goto done;}
-
- case 4:
-
- {t.kind = 4; goto done;}
-
- case 5:
-
- if ((ch >= 1 && ch <= 9 || ch >= 11 && ch <= 12 || ch >= 14 && ch <= '&' || ch >= '(' && ch <= '[' || ch >= ']')) {buf.Append(ch); NextCh(); goto case 6;}
-
- else if (ch == 92) {buf.Append(ch); NextCh(); goto case 7;}
-
- else {t.kind = noSym; goto done;}
-
- case 6:
-
- if (ch == 39) {buf.Append(ch); NextCh(); goto case 9;}
-
- else {t.kind = noSym; goto done;}
-
- case 7:
-
- if ((ch >= ' ' && ch <= '~')) {buf.Append(ch); NextCh(); goto case 8;}
-
- else {t.kind = noSym; goto done;}
-
- case 8:
-
- if ((ch >= '0' && ch <= '9' || ch >= 'a' && ch <= 'f')) {buf.Append(ch); NextCh(); goto case 8;}
-
- else if (ch == 39) {buf.Append(ch); NextCh(); goto case 9;}
-
- else {t.kind = noSym; goto done;}
-
- case 9:
-
- {t.kind = 5; goto done;}
-
- case 10:
-
- if ((ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')) {buf.Append(ch); NextCh(); goto case 10;}
-
- else {t.kind = 43; goto done;}
-
- case 11:
-
- if ((ch >= 1 && ch <= 9 || ch >= 11 && ch <= 12 || ch >= 14 && ch <= '!' || ch >= '#' && ch <= '[' || ch >= ']')) {buf.Append(ch); NextCh(); goto case 11;}
-
- else if ((ch == 10 || ch == 13)) {buf.Append(ch); NextCh(); goto case 4;}
-
- else if (ch == '"') {buf.Append(ch); NextCh(); goto case 3;}
-
- else if (ch == 92) {buf.Append(ch); NextCh(); goto case 12;}
-
- else {t.kind = noSym; goto done;}
-
- case 12:
-
- if ((ch >= ' ' && ch <= '~')) {buf.Append(ch); NextCh(); goto case 11;}
-
- else {t.kind = noSym; goto done;}
-
- case 13:
-
- {t.kind = 8; goto done;}
-
- case 14:
-
- if (ch == '.') {buf.Append(ch); NextCh(); goto case 17;}
-
- else if (ch == ')') {buf.Append(ch); NextCh(); goto case 30;}
-
- else {t.kind = 9; goto done;}
-
- case 15:
-
- {t.kind = 20; goto done;}
-
- case 16:
-
- {t.kind = 21; goto done;}
-
- case 17:
-
- {t.kind = 22; goto done;}
-
- case 18:
-
- {t.kind = 24; goto done;}
-
- case 19:
-
- {t.kind = 25; goto done;}
-
- case 20:
-
- {t.kind = 26; goto done;}
-
- case 21:
-
- if (ch == '.') {buf.Append(ch); NextCh(); goto case 29;}
-
- else {t.kind = 28; goto done;}
-
- case 22:
-
- {t.kind = 29; goto done;}
-
- case 23:
-
- {t.kind = 30; goto done;}
-
- case 24:
-
- {t.kind = 31; goto done;}
-
- case 25:
-
- {t.kind = 32; goto done;}
-
- case 26:
-
- {t.kind = 33; goto done;}
-
- case 27:
-
- if (ch == '=') {buf.Append(ch); NextCh(); goto case 28;}
-
- else {t.kind = noSym; goto done;}
-
- case 28:
-
- {t.kind = 36; goto done;}
-
- case 29:
-
- {t.kind = 38; goto done;}
-
- case 30:
-
- {t.kind = 39; goto done;}
-
- case 31:
-
- {t.kind = 41; goto done;}
-
- case 32: {t.kind = 0; goto done;}
-
- }
-
- done:
-
- t.val = buf.ToString();
-
- return t;
-
- }
-
-
-
- /* AW 2003-03-07 get the next token, move on and synch peek token with current */
-
- public static Token Scan () {
-
- t = pt = t.next;
-
- return t;
-
- }
-
-
-
- /* AW 2003-03-07 get the next token, ignore pragmas */
-
- public static Token Peek () {
-
- do { // skip pragmas while peeking
-
- pt = pt.next;
-
- } while (pt != null && pt.kind > maxT);
-
- return pt;
-
- }
-
-
-
- /* AW 2003-03-11 to make sure peek start at current scan position */
-
- public static void StartPeek () { pt = t; }
-
-} // end Scanner
-
-
-
-
-
-public delegate void ErrorCodeProc (int line, int col, int n);
-
-public delegate void ErrorMsgProc (int line, int col, string msg);
-
-
-
-public class Errors {
-
- public static int count = 0; // number of errors detected
-
- public static ErrorCodeProc SynErr = new ErrorCodeProc(DefaultCodeError); // syntactic errors
-
- public static ErrorCodeProc SemErr = new ErrorCodeProc(DefaultCodeError); // semantic errors
-
- public static ErrorMsgProc Error = new ErrorMsgProc(DefaultMsgError); // user defined string based errors
-
-
-
- public static void Exception (string s) {
-
- Console.WriteLine(s);
-
- System.Environment.Exit(0);
-
- }
-
-
-
- static void DefaultCodeError (int line, int col, int n) {
-
- Console.WriteLine("-- line {0} col {1}: error {2}", line, col, n);
-
- count++;
-
- }
-
-
-
- static void DefaultMsgError (int line, int col, string s) {
-
- Console.WriteLine("-- line {0} col {1}: {2}", line, col, s);
-
- count++;
-
- }
-
-} // Errors
-
-
-
-}
+using System;
+
+using System.IO;
+
+using System.Collections;
+
+using System.Text;
+
+
+
+namespace at.jku.ssw.Coco {
+
+
+
+public class Token {
+
+ public int kind; // token kind
+
+ public int pos; // token position in the source text (starting at 0)
+
+ public int col; // token column (starting at 0)
+
+ public int line; // token line (starting at 1)
+
+ public string val; // token value
+
+ public Token next; // AW 2003-03-07 Tokens are kept in linked list
+
+
+
+ public Token () { }
+
+ public Token (int kind) { this.kind = kind; }
+
+}
+
+
+
+public class Buffer {
+
+ public const int eof = '\uffff';
+
+ static byte[] buf;
+ static int bufLen;
+ static int pos;
+ public static string fileName;
+
+ public static int CountLines(int offset)
+ {
+ int line = 0;
+ for (int i = 0; i <= offset; ++i) {
+ if (buf[i] == '\n') {
+ ++line;
+ }
+ }
+ return line;
+ }
+
+ public static void Fill (string fileName) {
+ Buffer.fileName = fileName;
+ FileStream s = null;
+ try {
+ s = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
+ bufLen = (int) s.Length;
+ buf = new byte[bufLen];
+ s.Read(buf, 0, bufLen);
+ pos = 0;
+
+ } catch (IOException) {
+
+ Console.WriteLine("--- Cannot open file {0}", fileName);
+
+ System.Environment.Exit(0);
+
+ } finally {
+
+ if (s != null) s.Close();
+
+ }
+
+ }
+
+
+
+ public static int Read () {
+
+ if (pos < bufLen) return buf[pos++];
+
+ else return 0;
+
+ }
+
+
+
+ public static int Peek () {
+
+ if (pos < bufLen) return buf[pos];
+
+ else return 0;
+
+ }
+
+
+
+ /* AW 2003-03-10 moved this from ParserGen.cs */
+
+ public static string GetString (int beg, int end) {
+
+ StringBuilder s = new StringBuilder(64);
+
+ int oldPos = Buffer.Pos;
+
+ Buffer.Pos = beg;
+
+ while (beg < end) { s.Append((char)Buffer.Read()); beg++; }
+
+ Buffer.Pos = oldPos;
+
+ return s.ToString();
+
+ }
+
+
+
+ public static int Pos {
+
+ get { return pos; }
+
+ set {
+
+ if (value < 0) pos = 0;
+
+ else if (value >= bufLen) pos = bufLen;
+
+ else pos = value;
+
+ }
+
+ }
+
+}
+
+
+
+public class Scanner {
+
+ const char EOF = '\0';
+
+ const char EOL = '\n';
+
+ const int maxT = 42;
+
+
+
+
+
+ const int noSym = 42;
+
+ static short[] start = {
+
+ 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 27, 11, 0, 10, 0, 0, 5, 21, 22, 0, 15, 0, 16, 14, 0,
+
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 31, 18, 13, 19, 0,
+
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23, 0, 24, 0, 0,
+
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 25, 20, 26, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0};
+
+
+
+
+
+ static Token t; // current token
+
+ static char ch; // current input character
+
+ static int pos; // column number of current character
+
+ static int line; // line number of current character
+
+ static int lineStart; // start position of current line
+
+ static int oldEols; // EOLs that appeared in a comment;
+
+ static BitArray ignore; // set of characters to be ignored by the scanner
+
+
+
+ /* ML ----- begin */
+
+ static Token tokens; // the complete input token stream
+
+ static Token pt; // current peek token
+
+
+
+ static int peekCount = 0;
+
+
+
+ public static int PeekCount { get { return peekCount; } }
+
+
+
+ public static void Init (String fileName) {
+
+ Buffer.Fill(fileName);
+
+ pos = -1; line = 1; lineStart = 0;
+
+ oldEols = 0;
+
+ NextCh();
+
+ ignore = new BitArray(256);
+
+ ignore[9] = true; ignore[10] = true; ignore[13] = true; ignore[32] = true;
+
+
+
+
+
+ /* AW 2003-03-07 fill token list */
+
+ tokens = new Token(); // first token is a dummy
+
+ Token node = tokens;
+
+ do {
+
+ node.next = NextToken();
+
+ node = node.next;
+
+ } while (node.kind != 0); /* AW: 0 => EOF */
+
+ t = pt = tokens;
+
+ }
+
+
+
+ static void NextCh() {
+
+ if (oldEols > 0) { ch = EOL; oldEols--; }
+
+ else {
+
+ ch = (char)Buffer.Read(); pos++;
+
+ // replace isolated '\r' by '\n' in order to make
+
+ // eol handling uniform across Windows, Unix and Mac
+
+ if (ch == '\r' && Buffer.Peek() != '\n') ch = EOL;
+
+ else if (ch > '\u007f') ch = '?';
+
+ if (ch == EOL) { line++; lineStart = pos + 1; }
+
+ }
+
+ }
+
+
+
+
+ static bool Comment0() {
+
+ int level = 1, line0 = line, lineStart0 = lineStart;
+
+ NextCh();
+
+ if (ch == '*') {
+
+ NextCh();
+
+ for(;;) {
+
+ if (ch == '*') {
+
+ NextCh();
+
+ if (ch == '/') {
+
+ level--;
+
+ if (level == 0) { oldEols = line - line0; NextCh(); return true; }
+
+ NextCh();
+
+ }
+
+ } else if (ch == '/') {
+
+ NextCh();
+
+ if (ch == '*') {
+
+ level++; NextCh();
+
+ }
+
+ } else if (ch == EOF) return false;
+
+ else NextCh();
+
+ }
+
+ } else {
+
+ if (ch==EOL) {line--; lineStart = lineStart0;}
+
+ pos = pos - 2; Buffer.Pos = pos+1; NextCh();
+
+ }
+
+ return false;
+
+ }
+
+
+
+
+
+ static void CheckLiteral() {
+
+ switch (t.val) {
+
+ case "COMPILER": t.kind = 6; break;
+
+ case "PRODUCTIONS": t.kind = 7; break;
+
+ case "END": t.kind = 10; break;
+
+ case "CHARACTERS": t.kind = 11; break;
+
+ case "TOKENS": t.kind = 12; break;
+
+ case "PRAGMAS": t.kind = 13; break;
+
+ case "COMMENTS": t.kind = 14; break;
+
+ case "FROM": t.kind = 15; break;
+
+ case "TO": t.kind = 16; break;
+
+ case "NESTED": t.kind = 17; break;
+
+ case "IGNORE": t.kind = 18; break;
+
+ case "TOKENNAMES": t.kind = 19; break;
+
+ case "ANY": t.kind = 23; break;
+
+ case "WEAK": t.kind = 27; break;
+
+ case "SYNC": t.kind = 34; break;
+
+ case "IF": t.kind = 35; break;
+
+ case "CONTEXT": t.kind = 37; break;
+
+ case "using": t.kind = 40; break;
+
+ default: break;
+
+
+
+ }
+
+ }
+
+
+
+ /* AW Scan() renamed to NextToken() */
+
+ static Token NextToken() {
+
+ while (ignore[ch]) NextCh();
+
+ if (ch == '/' && Comment0()) return NextToken();
+
+ t = new Token();
+
+ t.pos = pos; t.col = pos - lineStart + 1; t.line = line;
+
+ int state = start[ch];
+
+ StringBuilder buf = new StringBuilder(16);
+
+ buf.Append(ch); NextCh();
+
+
+
+ switch (state) {
+
+ case 0: { t.kind = noSym; goto done; } // NextCh already done
+
+ case 1:
+
+ if ((ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')) {buf.Append(ch); NextCh(); goto case 1;}
+
+ else {t.kind = 1; t.val = buf.ToString(); CheckLiteral(); return t;}
+
+ case 2:
+
+ if ((ch >= '0' && ch <= '9')) {buf.Append(ch); NextCh(); goto case 2;}
+
+ else {t.kind = 2; goto done;}
+
+ case 3:
+
+ {t.kind = 3; goto done;}
+
+ case 4:
+
+ {t.kind = 4; goto done;}
+
+ case 5:
+
+ if ((ch >= 1 && ch <= 9 || ch >= 11 && ch <= 12 || ch >= 14 && ch <= '&' || ch >= '(' && ch <= '[' || ch >= ']')) {buf.Append(ch); NextCh(); goto case 6;}
+
+ else if (ch == 92) {buf.Append(ch); NextCh(); goto case 7;}
+
+ else {t.kind = noSym; goto done;}
+
+ case 6:
+
+ if (ch == 39) {buf.Append(ch); NextCh(); goto case 9;}
+
+ else {t.kind = noSym; goto done;}
+
+ case 7:
+
+ if ((ch >= ' ' && ch <= '~')) {buf.Append(ch); NextCh(); goto case 8;}
+
+ else {t.kind = noSym; goto done;}
+
+ case 8:
+
+ if ((ch >= '0' && ch <= '9' || ch >= 'a' && ch <= 'f')) {buf.Append(ch); NextCh(); goto case 8;}
+
+ else if (ch == 39) {buf.Append(ch); NextCh(); goto case 9;}
+
+ else {t.kind = noSym; goto done;}
+
+ case 9:
+
+ {t.kind = 5; goto done;}
+
+ case 10:
+
+ if ((ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')) {buf.Append(ch); NextCh(); goto case 10;}
+
+ else {t.kind = 43; goto done;}
+
+ case 11:
+
+ if ((ch >= 1 && ch <= 9 || ch >= 11 && ch <= 12 || ch >= 14 && ch <= '!' || ch >= '#' && ch <= '[' || ch >= ']')) {buf.Append(ch); NextCh(); goto case 11;}
+
+ else if ((ch == 10 || ch == 13)) {buf.Append(ch); NextCh(); goto case 4;}
+
+ else if (ch == '"') {buf.Append(ch); NextCh(); goto case 3;}
+
+ else if (ch == 92) {buf.Append(ch); NextCh(); goto case 12;}
+
+ else {t.kind = noSym; goto done;}
+
+ case 12:
+
+ if ((ch >= ' ' && ch <= '~')) {buf.Append(ch); NextCh(); goto case 11;}
+
+ else {t.kind = noSym; goto done;}
+
+ case 13:
+
+ {t.kind = 8; goto done;}
+
+ case 14:
+
+ if (ch == '.') {buf.Append(ch); NextCh(); goto case 17;}
+
+ else if (ch == ')') {buf.Append(ch); NextCh(); goto case 30;}
+
+ else {t.kind = 9; goto done;}
+
+ case 15:
+
+ {t.kind = 20; goto done;}
+
+ case 16:
+
+ {t.kind = 21; goto done;}
+
+ case 17:
+
+ {t.kind = 22; goto done;}
+
+ case 18:
+
+ {t.kind = 24; goto done;}
+
+ case 19:
+
+ {t.kind = 25; goto done;}
+
+ case 20:
+
+ {t.kind = 26; goto done;}
+
+ case 21:
+
+ if (ch == '.') {buf.Append(ch); NextCh(); goto case 29;}
+
+ else {t.kind = 28; goto done;}
+
+ case 22:
+
+ {t.kind = 29; goto done;}
+
+ case 23:
+
+ {t.kind = 30; goto done;}
+
+ case 24:
+
+ {t.kind = 31; goto done;}
+
+ case 25:
+
+ {t.kind = 32; goto done;}
+
+ case 26:
+
+ {t.kind = 33; goto done;}
+
+ case 27:
+
+ if (ch == '=') {buf.Append(ch); NextCh(); goto case 28;}
+
+ else {t.kind = noSym; goto done;}
+
+ case 28:
+
+ {t.kind = 36; goto done;}
+
+ case 29:
+
+ {t.kind = 38; goto done;}
+
+ case 30:
+
+ {t.kind = 39; goto done;}
+
+ case 31:
+
+ {t.kind = 41; goto done;}
+
+ case 32: {t.kind = 0; goto done;}
+
+ }
+
+ done:
+
+ t.val = buf.ToString();
+
+ return t;
+
+ }
+
+
+
+ /* AW 2003-03-07 get the next token, move on and synch peek token with current */
+
+ public static Token Scan () {
+
+ t = pt = t.next;
+
+ return t;
+
+ }
+
+
+
+ /* AW 2003-03-07 get the next token, ignore pragmas */
+
+ public static Token Peek () {
+
+ do { // skip pragmas while peeking
+
+ pt = pt.next;
+
+ } while (pt != null && pt.kind > maxT);
+
+ return pt;
+
+ }
+
+
+
+ /* AW 2003-03-11 to make sure peek start at current scan position */
+
+ public static void StartPeek () { pt = t; }
+
+} // end Scanner
+
+
+
+
+
+public delegate void ErrorCodeProc (int line, int col, int n);
+
+public delegate void ErrorMsgProc (int line, int col, string msg);
+
+
+
+public class Errors {
+
+ public static int count = 0; // number of errors detected
+
+ public static ErrorCodeProc SynErr = new ErrorCodeProc(DefaultCodeError); // syntactic errors
+
+ public static ErrorCodeProc SemErr = new ErrorCodeProc(DefaultCodeError); // semantic errors
+
+ public static ErrorMsgProc Error = new ErrorMsgProc(DefaultMsgError); // user defined string based errors
+
+
+
+ public static void Exception (string s) {
+
+ Console.WriteLine(s);
+
+ System.Environment.Exit(0);
+
+ }
+
+
+
+ static void DefaultCodeError (int line, int col, int n) {
+
+ Console.WriteLine("-- line {0} col {1}: error {2}", line, col, n);
+
+ count++;
+
+ }
+
+
+
+ static void DefaultMsgError (int line, int col, string s) {
+
+ Console.WriteLine("-- line {0} col {1}: {2}", line, col, s);
+
+ count++;
+
+ }
+
+} // Errors
+
+
+
+}
Modified: trunk/MonoDevelop/src/Tools/SharpCoco/src/Scanner.frame
===================================================================
--- trunk/MonoDevelop/src/Tools/SharpCoco/src/Scanner.frame 2004-04-09 12:41:44 UTC (rev 1420)
+++ trunk/MonoDevelop/src/Tools/SharpCoco/src/Scanner.frame 2004-04-09 17:17:47 UTC (rev 1421)
@@ -1,222 +1,222 @@
-using System;
-using System.Drawing;
-using System.IO;
-using System.Collections;
-using System.Text;
-
--->namespace
-
-public class Token {
- public int kind; // token kind
- public int pos; // token position in the source text (starting at 0)
- public int col; // token column (starting at 0)
- public int line; // token line (starting at 1)
- public string val; // token value
- public Token next; // AW 2003-03-07 Tokens are kept in linked list
-
- public Point Location {
- get {
- return new Point(line, col);
- }
- }
-
- public Token () { }
- public Token (int kind) { this.kind = kind; }
-}
-
-public class Buffer {
- public const int eof = '\uffff';
-
- static byte[] buf;
- static int bufLen;
- static int pos;
-
- public static void Fill (string fileName) {
- FileStream s = null;
- try {
- s = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
- Fill(s);
- } catch (IOException) {
- Console.WriteLine("--- Cannot open file {0}", fileName);
- System.Environment.Exit(0);
- } finally {
- if (s != null) s.Close();
- }
- }
-
- public static void Fill (Stream s) {
- bufLen = (int) s.Length;
- buf = new byte[bufLen];
- s.Read(buf, 0, bufLen);
- pos = 0;
- }
-
- public static int Read () {
- if (pos < bufLen) return buf[pos++];
- else return 0;
- }
-
- public static int Peek () {
- if (pos < bufLen) return buf[pos];
- else return 0;
- }
-
- /* AW 2003-03-10 moved this from ParserGen.cs */
- public static string GetString (int beg, int end) {
- StringBuilder s = new StringBuilder(64);
- int oldPos = Buffer.Pos;
- Buffer.Pos = beg;
- while (beg < end) { s.Append((char)Buffer.Read()); beg++; }
- Buffer.Pos = oldPos;
- return s.ToString();
- }
-
- public static int Pos {
- get { return pos; }
- set {
- if (value < 0) pos = 0;
- else if (value >= bufLen) pos = bufLen;
- else pos = value;
- }
- }
-}
-
-public class Scanner {
- const char EOF = '\0';
- const char EOL = '\n';
- const char CR = '\n';
-
--->constants
-
--->declarations
-
- static Token t; // current token
- static char ch; // current input character
- static int pos; // column number of current character
- static int line; // line number of current character
- static int lineStart; // start position of current line
- static int oldEols; // EOLs that appeared in a comment;
- static BitArray ignore; // set of characters to be ignored by the scanner
-
- /* ML ----- begin */
- static Token tokens; // the complete input token stream
- static Token pt; // current peek token
-
- static int peekCount = 0;
-
- public static int PeekCount { get { return peekCount; } }
-
- static void Init()
- {
- pos = -1; line = 1; lineStart = 0;
- oldEols = 0;
- NextCh();
--->initialization
-
- /* AW 2003-03-07 fill token list */
- tokens = new Token(); // first token is a dummy
- Token node = tokens;
- do {
- node.next = NextToken();
- node = node.next;
- } while (node.kind != 0); /* AW: 0 => EOF */
- t = pt = tokens;
- }
-
- public static void Init(String fileName) {
- Buffer.Fill(fileName);
- Init();
- }
-
- public static void Init(Stream s) {
- Buffer.Fill(s);
- Init();
- }
-
- static void NextCh() {
- if (oldEols > 0) { ch = EOL; oldEols--; }
- else {
- ch = (char)Buffer.Read(); pos++;
- // replace isolated '\r' by '\n' in order to make
- // eol handling uniform across Windows, Unix and Mac
- if (ch == '\r' && Buffer.Peek() != '\n') ch = EOL;
- else if (ch > '\u007f') ch = '?';
- if (ch == EOL) { line++; lineStart = pos + 1; }
- }
- }
-
--->comment
-
- static void CheckLiteral() {
- switch (t.val) {
--->literals
- }
- }
-
- /* AW Scan() renamed to NextToken() */
- static Token NextToken() {
- while (ignore[ch]) NextCh();
--->scan1
- t = new Token();
- t.pos = pos; t.col = pos - lineStart + 1; t.line = line;
- int state = start[ch];
- StringBuilder buf = new StringBuilder(16);
- buf.Append(ch); NextCh();
-
- switch (state) {
- case 0: { t.kind = noSym; goto done; } // NextCh already done
--->scan2
- }
- done:
- t.val = buf.ToString();
- return t;
- }
-
- /* AW 2003-03-07 get the next token, move on and synch peek token with current */
- public static Token Scan () {
- t = pt = t.next;
- return t;
- }
-
- /* AW 2003-03-07 get the next token, ignore pragmas */
- public static Token Peek () {
- do { // skip pragmas while peeking
- pt = pt.next;
- } while (pt != null && pt.kind > maxT);
- return pt;
- }
-
- /* AW 2003-03-11 to make sure peek start at current scan position */
- public static void StartPeek () { pt = t; }
-} // end Scanner
-
-
-public delegate void ErrorCodeProc (int line, int col, int n);
-public delegate void ErrorMsgProc (int line, int col, string msg);
-
-public class Errors {
- public static int count = 0; // number of errors detected
- public static ErrorCodeProc SynErr = new ErrorCodeProc(DefaultCodeError); // syntactic errors
- public static ErrorCodeProc SemErr = new ErrorCodeProc(DefaultCodeError); // semantic errors
- public static ErrorMsgProc Error = new ErrorMsgProc(DefaultMsgError); // user defined string based errors
- public static StringBuilder errorText = new StringBuilder();
-
- public static void Exception (string s) {
- Console.WriteLine(s);
- System.Environment.Exit(0);
- }
-
- static void DefaultCodeError (int line, int col, int n) {
- errorText.Append(String.Format("-- line {0} col {1}: error {2}", line, col, n));
- errorText.Append("\n");
- count++;
- }
-
- static void DefaultMsgError (int line, int col, string s) {
- errorText.Append(String.Format("-- line {0} col {1}: {2}", line, col, s));
- errorText.Append("\n");
- count++;
- }
-} // Errors
-
-$$$
+using System;
+using System.Drawing;
+using System.IO;
+using System.Collections;
+using System.Text;
+
+-->namespace
+
+public class Token {
+ public int kind; // token kind
+ public int pos; // token position in the source text (starting at 0)
+ public int col; // token column (starting at 0)
+ public int line; // token line (starting at 1)
+ public string val; // token value
+ public Token next; // AW 2003-03-07 Tokens are kept in linked list
+
+ public Point Location {
+ get {
+ return new Point(line, col);
+ }
+ }
+
+ public Token () { }
+ public Token (int kind) { this.kind = kind; }
+}
+
+public class Buffer {
+ public const int eof = '\uffff';
+
+ static byte[] buf;
+ static int bufLen;
+ static int pos;
+
+ public static void Fill (string fileName) {
+ FileStream s = null;
+ try {
+ s = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
+ Fill(s);
+ } catch (IOException) {
+ Console.WriteLine("--- Cannot open file {0}", fileName);
+ System.Environment.Exit(0);
+ } finally {
+ if (s != null) s.Close();
+ }
+ }
+
+ public static void Fill (Stream s) {
+ bufLen = (int) s.Length;
+ buf = new byte[bufLen];
+ s.Read(buf, 0, bufLen);
+ pos = 0;
+ }
+
+ public static int Read () {
+ if (pos < bufLen) return buf[pos++];
+ else return 0;
+ }
+
+ public static int Peek () {
+ if (pos < bufLen) return buf[pos];
+ else return 0;
+ }
+
+ /* AW 2003-03-10 moved this from ParserGen.cs */
+ public static string GetString (int beg, int end) {
+ StringBuilder s = new StringBuilder(64);
+ int oldPos = Buffer.Pos;
+ Buffer.Pos = beg;
+ while (beg < end) { s.Append((char)Buffer.Read()); beg++; }
+ Buffer.Pos = oldPos;
+ return s.ToString();
+ }
+
+ public static int Pos {
+ get { return pos; }
+ set {
+ if (value < 0) pos = 0;
+ else if (value >= bufLen) pos = bufLen;
+ else pos = value;
+ }
+ }
+}
+
+public class Scanner {
+ const char EOF = '\0';
+ const char EOL = '\n';
+ const char CR = '\n';
+
+-->constants
+
+-->declarations
+
+ static Token t; // current token
+ static char ch; // current input character
+ static int pos; // column number of current character
+ static int line; // line number of current character
+ static int lineStart; // start position of current line
+ static int oldEols; // EOLs that appeared in a comment;
+ static BitArray ignore; // set of characters to be ignored by the scanner
+
+ /* ML ----- begin */
+ static Token tokens; // the complete input token stream
+ static Token pt; // current peek token
+
+ static int peekCount = 0;
+
+ public static int PeekCount { get { return peekCount; } }
+
+ static void Init()
+ {
+ pos = -1; line = 1; lineStart = 0;
+ oldEols = 0;
+ NextCh();
+-->initialization
+
+ /* AW 2003-03-07 fill token list */
+ tokens = new Token(); // first token is a dummy
+ Token node = tokens;
+ do {
+ node.next = NextToken();
+ node = node.next;
+ } while (node.kind != 0); /* AW: 0 => EOF */
+ t = pt = tokens;
+ }
+
+ public static void Init(String fileName) {
+ Buffer.Fill(fileName);
+ Init();
+ }
+
+ public static void Init(Stream s) {
+ Buffer.Fill(s);
+ Init();
+ }
+
+ static void NextCh() {
+ if (oldEols > 0) { ch = EOL; oldEols--; }
+ else {
+ ch = (char)Buffer.Read(); pos++;
+ // replace isolated '\r' by '\n' in order to make
+ // eol handling uniform across Windows, Unix and Mac
+ if (ch == '\r' && Buffer.Peek() != '\n') ch = EOL;
+ else if (ch > '\u007f') ch = '?';
+ if (ch == EOL) { line++; lineStart = pos + 1; }
+ }
+ }
+
+-->comment
+
+ static void CheckLiteral() {
+ switch (t.val) {
+-->literals
+ }
+ }
+
+ /* AW Scan() renamed to NextToken() */
+ static Token NextToken() {
+ while (ignore[ch]) NextCh();
+-->scan1
+ t = new Token();
+ t.pos = pos; t.col = pos - lineStart + 1; t.line = line;
+ int state = start[ch];
+ StringBuilder buf = new StringBuilder(16);
+ buf.Append(ch); NextCh();
+
+ switch (state) {
+ case 0: { t.kind = noSym; goto done; } // NextCh already done
+-->scan2
+ }
+ done:
+ t.val = buf.ToString();
+ return t;
+ }
+
+ /* AW 2003-03-07 get the next token, move on and synch peek token with current */
+ public static Token Scan () {
+ t = pt = t.next;
+ return t;
+ }
+
+ /* AW 2003-03-07 get the next token, ignore pragmas */
+ public static Token Peek () {
+ do { // skip pragmas while peeking
+ pt = pt.next;
+ } while (pt != null && pt.kind > maxT);
+ return pt;
+ }
+
+ /* AW 2003-03-11 to make sure peek start at current scan position */
+ public static void StartPeek () { pt = t; }
+} // end Scanner
+
+
+public delegate void ErrorCodeProc (int line, int col, int n);
+public delegate void ErrorMsgProc (int line, int col, string msg);
+
+public class Errors {
+ public static int count = 0; // number of errors detected
+ public static ErrorCodeProc SynErr = new ErrorCodeProc(DefaultCodeError); // syntactic errors
+ public static ErrorCodeProc SemErr = new ErrorCodeProc(DefaultCodeError); // semantic errors
+ public static ErrorMsgProc Error = new ErrorMsgProc(DefaultMsgError); // user defined string based errors
+ public static StringBuilder errorText = new StringBuilder();
+
+ public static void Exception (string s) {
+ Console.WriteLine(s);
+ System.Environment.Exit(0);
+ }
+
+ static void DefaultCodeError (int line, int col, int n) {
+ errorText.Append(String.Format("-- line {0} col {1}: error {2}", line, col, n));
+ errorText.Append("\n");
+ count++;
+ }
+
+ static void DefaultMsgError (int line, int col, string s) {
+ errorText.Append(String.Format("-- line {0} col {1}: {2}", line, col, s));
+ errorText.Append("\n");
+ count++;
+ }
+} // Errors
+
+$$$
Modified: trunk/MonoDevelop/src/Tools/SharpCoco/src/Tab.cs
===================================================================
--- trunk/MonoDevelop/src/Tools/SharpCoco/src/Tab.cs 2004-04-09 12:41:44 UTC (rev 1420)
+++ trunk/MonoDevelop/src/Tools/SharpCoco/src/Tab.cs 2004-04-09 17:17:47 UTC (rev 1421)
@@ -1,1068 +1,1068 @@
-/* ------------------------------------------------------------------------
- * Tab.cs
- * Symbol table management of Coco/R
- * by H.Moessenboeck, Univ. of Linz
- * ------------------------------------------------------------------------*/
-using System;
-using System.IO;
-using System.Collections;
-
-namespace at.jku.ssw.Coco {
-
-public class Position { // position of source code stretch (e.g. semantic action, resolver expressions)
- public int beg; // start relative to the beginning of the file
- public int len; // length of stretch
- public int col; // column number of start position
-
- public Position(int beg, int len, int col) {
- this.beg = beg; this.len = len; this.col = col;
- }
-}
-
-
-//---------------------------------------------------------------------
-// Symbols
-//---------------------------------------------------------------------
-
-public class Symbol : IComparable {
- public static ArrayList terminals = new ArrayList();
- public static ArrayList pragmas = new ArrayList();
- public static ArrayList nonterminals = new ArrayList();
- public static Hashtable tokenNames = null; /* AW 2003-03-25 */
-
- public const int classToken = 0; // token kinds
- public const int litToken = 1;
- public const int classLitToken = 2;
-
- public int n; // symbol number
- public int typ; // t, nt, pr, unknown, rslv /* ML 29_11_2002 slv added */ /* AW slv --> rslv */
- public string name; // symbol name
- public Node graph; // nt: to first node of syntax graph
- public int tokenKind; // t: token kind (literal, class, ...)
- public bool deletable; // nt: true if nonterminal is deletable
- public bool firstReady; // nt: true if terminal start symbols have already been computed
- public BitArray first; // nt: terminal start symbols
- public BitArray follow; // nt: terminal followers
- public BitArray nts; // nt: nonterminals whose followers have to be added to this sym
- public int line; // source text line number of item in this node
- public Position attrPos; // nt: position of attributes in source text (or null)
- public Position semPos; // pr: pos of semantic action in source text (or null)
- // nt: pos of local declarations in source text (or null)
- public override string ToString()
- {
- return String.Format("[Symbol:Name={0}, n={1}]", name, n);
- }
- public Symbol(int typ, string name, int line) {
- if (name.Length == 2 && name[0] == '"') {
- Parser.SemErr("empty token not allowed"); name = "???";
- }
- if (name.IndexOf(' ') >= 0) Parser.SemErr("tokens must not contain blanks");
- this.typ = typ; this.name = name; this.line = line;
- switch (typ) {
- case Node.t: n = terminals.Count; terminals.Add(this); break;
- case Node.pr: pragmas.Add(this); break;
- case Node.nt: n = nonterminals.Count; nonterminals.Add(this); break;
- }
- }
-
- public static Symbol Find(string name) {
- foreach (Symbol s in terminals)
- if (s.name == name) return s;
- foreach (Symbol s in nonterminals)
- if (s.name == name) return s;
- return null;
- }
-
- public int CompareTo(object x) {
- return name.CompareTo(((Symbol)x).name);
- }
-
-}
-
-
-//---------------------------------------------------------------------
-// Syntax graph (class Node, class Graph)
-//---------------------------------------------------------------------
-
-public class Node {
- public static ArrayList nodes = new ArrayList();
- public static string[] nTyp =
- {" ", "t ", "pr ", "nt ", "clas", "chr ", "wt ", "any ", "eps ", /* AW 03-01-14 nTyp[0]: " " --> " " */
- "sync", "sem ", "alt ", "iter", "opt ", "rslv"};
-
- // constants for node kinds
- public const int t = 1; // terminal symbol
- public const int pr = 2; // pragma
- public const int nt = 3; // nonterminal symbol
- public const int clas = 4; // character class
- public const int chr = 5; // character
- public const int wt = 6; // weak terminal symbol
- public const int any = 7; //
- public const int eps = 8; // empty
- public const int sync = 9; // synchronization symbol
- public const int sem = 10; // semantic action: (. .)
- public const int alt = 11; // alternative: |
- public const int iter = 12; // iteration: { }
- public const int opt = 13; // option: [ ]
- public const int rslv = 14; // resolver expr /* ML */ /* AW 03-01-13 renamed slv --> rslv */
-
- public const int normalTrans = 0; // transition codes
- public const int contextTrans = 1;
-
- public int n; // node number
- public int typ; // t, nt, wt, chr, clas, any, eps, sem, sync, alt, iter, opt, rslv
- public Node next; // to successor node
- public Node down; // alt: to next alternative
- public Node sub; // alt, iter, opt: to first node of substructure
- public bool up; // true: "next" leads to successor in enclosing structure
- public Symbol sym; // nt, t, wt: symbol represented by this node
- public int val; // chr: ordinal character value
- // clas: index of character class
- public int code; // chr, clas: transition code
- public BitArray set; // any, sync: the set represented by this node
- public Position pos; // nt, t, wt: pos of actual attributes
- // sem: pos of semantic action in source text
- public int line; // source text line number of item in this node
- public State state; // DFA state corresponding to this node
- // (only used in DFA.ConvertToStates)
-
- public Node(int typ, Symbol sym, int line) {
- this.typ = typ; this.sym = sym; this.line = line;
- n = nodes.Count;
- nodes.Add(this);
- }
-
- public Node(int typ, Node sub): this(typ, null, 0) {
- this.sub = sub;
- }
-
- public Node(int typ, int val, int line): this(typ, null, line) {
- this.val = val;
- }
-
- public static bool DelGraph(Node p) {
- return p == null || DelNode(p) && DelGraph(p.next);
- }
-
- public static bool DelAlt(Node p) {
- return p == null || DelNode(p) && (p.up || DelAlt(p.next));
- }
-
- public static bool DelNode(Node p) {
- if (p.typ == nt) return p.sym.deletable;
- else if (p.typ == alt) return DelAlt(p.sub) || p.down != null && DelAlt(p.down);
- else return p.typ == eps || p.typ == iter || p.typ == opt || p.typ == sem || p.typ == sync;
- }
-
- //----------------- for printing ----------------------
-
- static int Ptr(Node p, bool up) {
- if (p == null) return 0;
- else if (up) return -p.n;
- else return p.n;
- }
-
- static string Pos(Position pos) {
- if (pos == null) return " "; else return String.Format("{0,5}", pos.beg);
- }
-
- public static string Name(string name) {
- return (name + " ").Substring(0, 12);
- /* isn't this better (less string allocations, easier to understand): *
- * return (name.Length > 12) ? name.Substring(0,12) : name; */
- }
-
- public static void PrintNodes() {
- Trace.WriteLine("Graph nodes:");
- Trace.WriteLine("----------------------------------------------------");
- Trace.WriteLine(" n type name next down sub pos line");
- Trace.WriteLine(" val code");
- Trace.WriteLine("----------------------------------------------------");
- foreach (Node p in nodes) {
- Trace.Write("{0,4} {1} ", p.n, nTyp[p.typ]);
- if (p.sym != null)
- Trace.Write("{0,12} ", Name(p.sym.name));
- else if (p.typ == Node.clas) {
- CharClass c = (CharClass)CharClass.classes[p.val];
- Trace.Write("{0,12} ", Name(c.name));
- } else Trace.Write(" ");
- Trace.Write("{0,5} ", Ptr(p.next, p.up));
- switch (p.typ) {
- case t: case nt: case wt:
- Trace.Write(" {0,5}", Pos(p.pos)); break;
- case chr:
- Trace.Write("{0,5} {1,5} ", p.val, p.code); break;
- case clas:
- Trace.Write(" {0,5} ", p.code); break;
- case alt: case iter: case opt:
- Trace.Write("{0,5} {1,5} ", Ptr(p.down, false), Ptr(p.sub, false)); break;
- case sem:
- Trace.Write(" {0,5}", Pos(p.pos)); break;
- case eps: case any: case sync:
- Trace.Write(" "); break;
- }
- Trace.WriteLine("{0,5}", p.line);
- }
- Trace.WriteLine();
- }
-
-}
-
-
-public class Graph {
- static Node dummyNode = new Node(Node.eps, null, 0);
-
- public Node l; // left end of graph = head
- public Node r; // right end of graph = list of nodes to be linked to successor graph
-
- public Graph() {
- l = null; r = null;
- }
-
- public Graph(Node left, Node right) {
- l = left; r = right;
- }
-
- public Graph(Node p) {
- l = p; r = p;
- }
-
- public static void MakeFirstAlt(Graph g) {
- g.l = new Node(Node.alt, g.l); g.l.line = g.l.sub.line; /* AW 2002-03-07 make line available for error handling */
- g.l.next = g.r;
- g.r = g.l;
- }
-
- public static void MakeAlternative(Graph g1, Graph g2) {
- g2.l = new Node(Node.alt, g2.l); g2.l.line = g2.l.sub.line;
- Node p = g1.l; while (p.down != null) p = p.down;
- p.down = g2.l;
- p = g1.r; while (p.next != null) p = p.next;
- p.next = g2.r;
- }
-
- public static void MakeSequence(Graph g1, Graph g2) {
- Node p = g1.r.next; g1.r.next = g2.l; // link head node
- while (p != null) { // link substructure
- Node q = p.next; p.next = g2.l; p.up = true;
- p = q;
- }
- g1.r = g2.r;
- }
-
- public static void MakeIteration(Graph g) {
- g.l = new Node(Node.iter, g.l);
- Node p = g.r;
- g.r = g.l;
- while (p != null) {
- Node q = p.next; p.next = g.l; p.up = true;
- p = q;
- }
- }
-
- public static void MakeOption(Graph g) {
- g.l = new Node(Node.opt, g.l);
- g.l.next = g.r;
- g.r = g.l;
- }
-
- public static void Finish(Graph g) {
- Node p = g.r;
- while (p != null) {
- Node q = p.next; p.next = null; p = q;
- }
- }
-
- public static void SetContextTrans(Node p) { // set transition code in the graph rooted at p
- DFA.hasCtxMoves = true;
- while (p != null) {
- if (p.typ == Node.chr || p.typ == Node.clas) {
- p.code = Node.contextTrans;
- } else if (p.typ == Node.opt || p.typ == Node.iter) {
- SetContextTrans(p.sub);
- } else if (p.typ == Node.alt) {
- SetContextTrans(p.sub); SetContextTrans(p.down);
- }
- if (p.up) break;
- p = p.next;
- }
- }
-
- public static void DeleteNodes() {
- Node.nodes = new ArrayList();
- dummyNode = new Node(Node.eps, null, 0);
- }
-
- public static Graph StrToGraph(string str) {
- string s = DFA.Unescape(str.Substring(1, str.Length-2));
- if (s.IndexOf('\0') >= 0) Parser.SemErr("\\0 not allowed here. Used as eof character");
- if (s.Length == 0) Parser.SemErr("empty token not allowed");
- Graph g = new Graph();
- g.r = dummyNode;
- for (int i = 0; i < s.Length; i++) {
- Node p = new Node(Node.chr, (int)s[i], 0);
- g.r.next = p; g.r = p;
- }
- g.l = dummyNode.next; dummyNode.next = null;
- return g;
- }
-
-}
-
-
-//----------------------------------------------------------------
-// Bit sets
-//----------------------------------------------------------------
-
-public class Sets {
-
- public static int First(BitArray s) {
- int max = s.Count;
- for (int i=0; i<max; i++)
- if (s[i]) return i;
- return -1;
- }
-
- public static int Elements(BitArray s) {
- int max = s.Count;
- int n = 0;
- for (int i=0; i<max; i++)
- if (s[i]) n++;
- return n;
- }
-
- public static bool Equals(BitArray a, BitArray b) {
- int max = a.Count;
- for (int i=0; i<max; i++)
- if (a[i] != b[i]) return false;
- return true;
- }
-
- public static bool Includes(BitArray a, BitArray b) { // a > b ?
- int max = a.Count;
- for (int i=0; i<max; i++)
- if (b[i] && ! a[i]) return false;
- return true;
- }
-
- public static bool Intersect(BitArray a, BitArray b) { // a * b != {}
- int max = a.Count;
- for (int i=0; i<max; i++)
- if (a[i] && b[i]) return true;
- return false;
- }
-
- public static void Subtract(BitArray a, BitArray b) { // a = a - b
- BitArray c = (BitArray) b.Clone();
- a.And(c.Not());
- }
-
- public static void PrintSet(BitArray s, int indent) {
- int col, len;
- col = indent;
- foreach (Symbol sym in Symbol.terminals) {
- if (s[sym.n]) {
- len = sym.name.Length;
- if (col + len >= 80) {
- Trace.WriteLine();
- for (col = 1; col < indent; col++) Trace.Write(" ");
- }
- Trace.Write("{0} ", sym.name);
- col += len + 1;
- }
- }
- if (col == indent) Trace.Write("-- empty set --");
- Trace.WriteLine();
- }
-
-}
-
-
-//---------------------------------------------------------------------
-// Character class management
-//---------------------------------------------------------------------
-
-public class CharClass {
- public static ArrayList classes = new ArrayList();
- public static int dummyName = 'A';
-
- public const int charSetSize = 256; // must be a multiple of 16
-
- public int n; // class number
- public string name; // class name
- public BitArray set; // set representing the class
-
- public CharClass(string name, BitArray s) {
- if (name == "#") name = "#" + (char)dummyName++;
- this.n = classes.Count; this.name = name; this.set = s;
- classes.Add(this);
- }
-
- public static CharClass Find(string name) {
- foreach (CharClass c in classes)
- if (c.name == name) return c;
- return null;
- }
-
- public static CharClass Find(BitArray s) {
- foreach (CharClass c in classes)
- if (Sets.Equals(s, c.set)) return c;
- return null;
- }
-
- public static BitArray Set(int i) {
- return ((CharClass)classes[i]).set;
- }
-
- static string Ch(int ch) {
- if (ch < ' ' || ch >= 127 || ch == '\'' || ch == '\\') return ch.ToString();
- else return String.Format("'{0}'", (char)ch);
- }
-
- static void WriteCharSet(BitArray s) {
- int i = 0, len = s.Count;
- while (i < len) {
- while (i < len && !s[i]) i++;
- if (i == len) break;
- int j = i;
- while (i < len && s[i]) i++;
- if (j < i-1) Trace.Write("{0}..{1} ", Ch(j), Ch(i-1));
- else Trace.Write("{0} ", Ch(j));
- }
- }
-
- public static void WriteClasses () {
- foreach (CharClass c in classes) {
- Trace.Write("{0,-10}: ", c.name);
- WriteCharSet(c.set);
- Trace.WriteLine();
- }
- Trace.WriteLine();
- }
-}
-
-
-//-----------------------------------------------------------
-// Symbol table management routines
-//-----------------------------------------------------------
-
-public class Tab {
- public static Position semDeclPos; // position of global semantic declarations
- public static BitArray ignored; // characters ignored by the scanner
- public static bool[] ddt = new bool[10]; // debug and test switches
- public static Symbol gramSy; // root nonterminal; filled by ATG
- public static Symbol eofSy; // end of file symbol
- public static Symbol noSym; // used in case of an error
- public static BitArray allSyncSets; // union of all synchronisation sets
- public static string nsName; // namespace for generated files
-
- static BitArray visited; // mark list for graph traversals
- static Symbol curSy; // current symbol in computation of sets
-
- //---------------------------------------------------------------------
- // Symbol set computations
- //---------------------------------------------------------------------
-
- /* Computes the first set for the given Node. */
- static BitArray First0(Node p, BitArray mark) {
- BitArray fs = new BitArray(Symbol.terminals.Count);
- while (p != null && !mark[p.n]) {
- mark[p.n] = true;
- switch (p.typ) {
- case Node.nt: {
- if (p.sym.firstReady) fs.Or(p.sym.first);
- else fs.Or(First0(p.sym.graph, mark));
- break;
- }
- case Node.t: case Node.wt: {
- fs[p.sym.n] = true; break;
- }
- case Node.any: {
- fs.Or(p.set); break;
- }
- case Node.alt: {
- fs.Or(First0(p.sub, mark));
- fs.Or(First0(p.down, mark));
- break;
- }
- case Node.iter: case Node.opt: {
- fs.Or(First0(p.sub, mark));
- break;
- }
- }
- if (!Node.DelNode(p)) break;
- p = p.next;
- }
- return fs;
- }
-
- /// <returns>
- /// BitArray which contains the first tokens.
- /// </returns>
- public static BitArray First(Node p) {
- BitArray fs = First0(p, new BitArray(Node.nodes.Count));
- if (ddt[3]) {
- Trace.WriteLine();
- if (p != null) Trace.WriteLine("First: node = {0}", p.n);
- else Trace.WriteLine("First: node = null");
- Sets.PrintSet(fs, 0);
- }
- return fs;
- }
-
-
- static void CompFirstSets() {
- foreach (Symbol sym in Symbol.nonterminals) {
- sym.first = new BitArray(Symbol.terminals.Count);
- sym.firstReady = false;
- }
- foreach (Symbol sym in Symbol.nonterminals) {
- sym.first = First(sym.graph);
- sym.firstReady = true;
- }
- }
-
- static void CompFollow(Node p) {
- while (p != null && !visited[p.n]) {
- visited[p.n] = true;
- if (p.typ == Node.nt) {
- BitArray s = First(p.next);
- p.sym.follow.Or(s);
- if (Node.DelGraph(p.next))
- p.sym.nts[curSy.n] = true;
- } else if (p.typ == Node.opt || p.typ == Node.iter) {
- CompFollow(p.sub);
- } else if (p.typ == Node.alt) {
- CompFollow(p.sub); CompFollow(p.down);
- }
- p = p.next;
- }
- }
-
- static void Complete(Symbol sym) {
- if (!visited[sym.n]) {
- visited[sym.n] = true;
- foreach (Symbol s in Symbol.nonterminals) {
- if (sym.nts[s.n]) {
- Complete(s);
- sym.follow.Or(s.follow);
- if (sym == curSy) sym.nts[s.n] = false;
- }
- }
- }
- }
-
- static void CompFollowSets() {
- foreach (Symbol sym in Symbol.nonterminals) {
- sym.follow = new BitArray(Symbol.terminals.Count);
- sym.nts = new BitArray(Symbol.nonterminals.Count);
- }
- visited = new BitArray(Node.nodes.Count);
- foreach (Symbol sym in Symbol.nonterminals) { // get direct successors of nonterminals
- curSy = sym;
- CompFollow(sym.graph);
- }
- foreach (Symbol sym in Symbol.nonterminals) { // add indirect successors to followers
- visited = new BitArray(Symbol.nonterminals.Count);
- curSy = sym;
- Complete(sym);
- }
- }
-
- static Node LeadingAny(Node p) {
- if (p == null) return null;
- Node a = null;
- if (p.typ == Node.any) a = p;
- else if (p.typ == Node.alt) {
- a = LeadingAny(p.sub);
- if (a == null) a = LeadingAny(p.down);
- }
- else if (p.typ == Node.opt || p.typ == Node.iter) a = LeadingAny(p.sub);
- else if (Node.DelNode(p) && !p.up) a = LeadingAny(p.next);
- return a;
- }
-
- static void FindAS(Node p) { // find ANY sets
- Node a;
- while (p != null) {
- if (p.typ == Node.opt || p.typ == Node.iter) {
- FindAS(p.sub);
- a = LeadingAny(p.sub);
- if (a != null) Sets.Subtract(a.set, First(p.next));
- } else if (p.typ == Node.alt) {
- BitArray s1 = new BitArray(Symbol.terminals.Count);
- Node q = p;
- while (q != null) {
- FindAS(q.sub);
- a = LeadingAny(q.sub);
- if (a != null)
- Sets.Subtract(a.set, First(q.down).Or(s1));
- else
- s1.Or(First(q.sub));
- q = q.down;
- }
- }
- if (p.up) break;
- p = p.next;
- }
- }
-
- static void CompAnySets() {
- foreach (Symbol sym in Symbol.nonterminals) FindAS(sym.graph);
- }
-
- public static BitArray Expected(Node p, Symbol curSy) {
- BitArray s = First(p);
- if (Node.DelGraph(p)) s.Or(curSy.follow);
- return s;
- }
-
- public static BitArray Expected(Node p, Symbol curSy, int outmost) {
- BitArray s = First(p);
- if (Node.DelGraph(p)) s.Or(curSy.follow);
- return s;
- }
-
- static void CompSync(Node p) {
- while (p != null && !visited[p.n]) {
- visited[p.n] = true;
- if (p.typ == Node.sync) {
- BitArray s = Expected(p.next, curSy);
- s[eofSy.n] = true;
- allSyncSets.Or(s);
- p.set = s;
- } else if (p.typ == Node.alt) {
- CompSync(p.sub); CompSync(p.down);
- } else if (p.typ == Node.opt || p.typ == Node.iter)
- CompSync(p.sub);
- p = p.next;
- }
- }
-
- static void CompSyncSets() {
- allSyncSets = new BitArray(Symbol.terminals.Count);
- allSyncSets[eofSy.n] = true;
- visited = new BitArray(Node.nodes.Count);
- foreach (Symbol sym in Symbol.nonterminals) {
- curSy = sym;
- CompSync(curSy.graph);
- }
- }
-
- public static void SetupAnys() {
- foreach (Node p in Node.nodes)
- if (p.typ == Node.any) {
- p.set = new BitArray(Symbol.terminals.Count, true);
- p.set[eofSy.n] = false;
- }
- }
-
- public static void CompDeletableSymbols() {
- bool changed;
- do {
- changed = false;
- foreach (Symbol sym in Symbol.nonterminals)
- if (!sym.deletable && sym.graph != null && Node.DelGraph(sym.graph)) {
- sym.deletable = true; changed = true;
- }
- } while (changed);
- foreach (Symbol sym in Symbol.nonterminals)
- if (sym.deletable) Console.WriteLine(" {0} deletable", sym.name);
- }
-
- public static void RenumberPragmas() {
- int n = Symbol.terminals.Count;
- foreach (Symbol sym in Symbol.pragmas) sym.n = n++;
- }
-
- public static void CompSymbolSets() {
- CompDeletableSymbols();
- CompFirstSets();
- CompFollowSets();
- CompAnySets();
- CompSyncSets();
- if (ddt[1]) {
- Trace.WriteLine();
- Trace.WriteLine("First & follow symbols:");
- Trace.WriteLine("----------------------"); Trace.WriteLine();
- foreach (Symbol sym in Symbol.nonterminals) {
- Trace.WriteLine(sym.name);
- Trace.Write("first: "); Sets.PrintSet(sym.first, 10);
- Trace.Write("follow: "); Sets.PrintSet(sym.follow, 10);
- Trace.WriteLine();
- }
- }
- if (ddt[4]) {
- Trace.WriteLine();
- Trace.WriteLine("ANY and SYNC sets:");
- Trace.WriteLine("-----------------");
- foreach (Node p in Node.nodes)
- if (p.typ == Node.any || p.typ == Node.sync) {
- Trace.Write("{0,4} {1,4}: ", p.n, Node.nTyp[p.typ]);
- Sets.PrintSet(p.set, 11);
- }
- }
- }
-
- //---------------------------------------------------------------------
- // Grammar checks
- //---------------------------------------------------------------------
-
- public static bool GrammarOk() {
- bool ok = NtsComplete()
- && AllNtReached()
- && NoCircularProductions()
- && AllNtToTerm();
- if (ok) CheckLL1();
- return ok;
- }
-
- //--------------- check for circular productions ----------------------
-
- class CNode { // node of list for finding circular productions
- public Symbol left, right;
-
- public CNode (Symbol l, Symbol r) {
- left = l; right = r;
- }
- }
-
- static void GetSingles(Node p, ArrayList singles) {
- if (p == null) return; // end of graph
- if (p.typ == Node.nt) {
- if (p.up || Node.DelGraph(p.next)) singles.Add(p.sym);
- } else if (p.typ == Node.alt || p.typ == Node.iter || p.typ == Node.opt) {
- if (p.up || Node.DelGraph(p.next)) {
- GetSingles(p.sub, singles);
- if (p.typ == Node.alt) GetSingles(p.down, singles);
- }
- }
- if (!p.up && Node.DelNode(p)) GetSingles(p.next, singles);
- }
-
- public static bool NoCircularProductions() {
- bool ok, changed, onLeftSide, onRightSide;
- ArrayList list = new ArrayList();
- foreach (Symbol sym in Symbol.nonterminals) {
- ArrayList singles = new ArrayList();
- GetSingles(sym.graph, singles); // get nonterminals s such that sym-->s
- foreach (Symbol s in singles) list.Add(new CNode(sym, s));
- }
- do {
- changed = false;
- for (int i = 0; i < list.Count; i++) {
- CNode n = (CNode)list[i];
- onLeftSide = false; onRightSide = false;
- foreach (CNode m in list) {
- if (n.left == m.right) onRightSide = true;
- if (n.right == m.left) onLeftSide = true;
- }
- if (!onLeftSide || !onRightSide) {
- list.Remove(n); i--; changed = true;
- }
- }
- } while(changed);
- ok = true;
- foreach (CNode n in list) {
- ok = false; Errors.count++;
- Console.WriteLine(" {0} --> {1}", n.left.name, n.right.name);
- }
- return ok;
- }
-
- //--------------- check for LL(1) errors ----------------------
-
- static void LL1Error(int cond, Symbol sym) {
- Console.Write(" LL1 warning in {0}: ", curSy.name);
- if (sym != null) Console.Write("{0} is ", sym.name);
- switch (cond) {
- case 1: Console.WriteLine(" start of several alternatives"); break;
- case 2: Console.WriteLine(" start & successor of deletable structure"); break;
- case 3: Console.WriteLine(" an ANY node that matches no symbol"); break;
- }
- }
-
- static void CheckOverlap(BitArray s1, BitArray s2, int cond) {
- foreach (Symbol sym in Symbol.terminals) {
- if (s1[sym.n] && s2[sym.n]) LL1Error(cond, sym);
- }
- }
-
- static void CheckAlts(Node p) {
- BitArray s1, s2;
- while (p != null) {
- if (p.typ == Node.alt) {
- Node q = p;
- s1 = new BitArray(Symbol.terminals.Count);
- while (q != null) { // for all alternatives
- s2 = Expected(q.sub, curSy);
- CheckOverlap(s1, s2, 1);
- s1.Or(s2);
- CheckAlts(q.sub);
- q = q.down;
- }
- } else if (p.typ == Node.opt || p.typ == Node.iter) {
- s1 = Expected(p.sub, curSy);
- s2 = Expected(p.next, curSy);
- CheckOverlap(s1, s2, 2);
- CheckAlts(p.sub);
- } else if (p.typ == Node.any) {
- if (Sets.Elements(p.set) == 0) LL1Error(3, null);
- // e.g. {ANY} ANY or [ANY] ANY
- }
- if (p.up) break;
- p = p.next;
- }
- }
-
- static void RSlvError(string msg) {
- Console.WriteLine(msg);
- }
-
-
- static void CheckResolver(Node p) {
- while (p != null) {
- // check subnodes of current node p
- if ((p.typ == Node.alt || p.typ == Node.iter || p.typ == Node.opt) &&
- !p.sub.up)
- if (p.sub.typ == Node.rslv) CheckResolver(p.sub.next);
- else CheckResolver(p.sub);
-
- // check current node p
- switch (p.typ) {
- case Node.alt:
- BitArray uncovered = new BitArray(Symbol.terminals.Count); // first symbols of alternatives without a resolver (not "covered" by a resolver)
- ArrayList coveredList = new ArrayList(); // list of follow symbols of each resolver (these are "covered" by the resolver)
- ArrayList rslvList = new ArrayList();
-
- // build set of uncovered first symbols & check for misplaced resolvers
- // (= not at the first n-1 of n conflicting alternatives)
- Node q = p;
- while (q != null) {
- BitArray curCovered;
- if (q.sub.typ == Node.rslv) {
- // get followers of resolver (these are "covered" by it)
- if (q.sub.next == null) curCovered = curSy.follow;
- else curCovered = First0(q.sub.next, new BitArray(Node.nodes.Count));
- coveredList.Add(curCovered);
- rslvList.Add(q.sub);
- // resolver must "cover" all but the last occurrence of a conflicting symbol
- if (Sets.Intersect(uncovered, curCovered))
- RSlvError("Misplaced resolver at line " + q.sub.line + " will never be evaluated. " +
- "Place resolver at previous conflicting alternative.");
- } else uncovered.Or(First0(q.sub, new BitArray(Node.nodes.Count)));
- q = q.down;
- }
-
- // check for obsolete resolvers
- // (= alternatives starting with resolvers, when there is no conflict)
- BitArray[] covered = (BitArray[]) coveredList.ToArray(typeof(BitArray));
- Node[] rslvs = (Node[]) rslvList.ToArray(typeof(Node));
- for (int i = 0; i < rslvs.Length; ++i) {
- if (!Sets.Intersect(uncovered, covered[i]))
- RSlvError("Obsolete resolver at line " + rslvs[i].line + ". " +
- "Neither of the start symbols of the alternative occurs without a resolver.");
- /*
- if (!Sets.Includes(uncovered, covered[i]))
- RSlvError("At least one of the symbols after the resolver at line " + rslvs[i].line +
- " does not appear without a resolver. Remove the last resolver covering this symbol.");
- */
- /*
- if (Sets.Equals(, covered[i]))
- RSlvError("Resolver at line " + rslvArr[i].line + " covers more symbols than necessary.\n" +
- "Place resolvers only in front of conflicting symbols.");
- */
- }
- break;
- case Node.iter: case Node.opt:
- if (p.sub.typ == Node.rslv) {
- BitArray fs = First0(p.sub.next, new BitArray(Node.nodes.Count));
- BitArray fsNext;
- if (p.next == null) fsNext = curSy.follow;
- else fsNext = First0(p.next, new BitArray(Node.nodes.Count));
- if (!Sets.Intersect(fs, fsNext))
- RSlvError("Obsolete resolver expression (IF ...) at line " + p.sub.line);
- }
- break;
- case Node.rslv:
- RSlvError("Unexpected Resolver in line " + p.line + ". Will cause parsing error.");
- break;
- }
- if (p.up) break;
- p = p.next;
- }
- }
-
- public static void CheckLL1() {
- foreach (Symbol sym in Symbol.nonterminals) {
- curSy = sym;
- CheckAlts(curSy.graph);
- CheckResolver(curSy.graph);
- }
- }
-
- //------------- check if every nts has a production --------------------
-
- public static bool NtsComplete() {
- bool complete = true;
- foreach (Symbol sym in Symbol.nonterminals) {
- if (sym.graph == null) {
- complete = false; Errors.count++;
- Console.WriteLine(" No production for {0}", sym.name);
- }
- }
- return complete;
- }
-
- //-------------- check if every nts can be reached -----------------
-
- static void MarkReachedNts(Node p) {
- while (p != null) {
- if (p.typ == Node.nt && !visited[p.sym.n]) { // new nt reached
- visited[p.sym.n] = true;
- MarkReachedNts(p.sym.graph);
- } else if (p.typ == Node.alt || p.typ == Node.iter || p.typ == Node.opt) {
- MarkReachedNts(p.sub);
- if (p.typ == Node.alt) MarkReachedNts(p.down);
- }
- if (p.up) break;
- p = p.next;
- }
- }
-
- public static bool AllNtReached() {
- bool ok = true;
- visited = new BitArray(Symbol.nonterminals.Count);
- visited[gramSy.n] = true;
- MarkReachedNts(gramSy.graph);
- foreach (Symbol sym in Symbol.nonterminals) {
- if (!visited[sym.n]) {
- ok = false; Errors.count++;
- Console.WriteLine(" {0} cannot be reached", sym.name);
- }
- }
- return ok;
- }
-
- //--------- check if every nts can be derived to terminals ------------
-
- static bool IsTerm(Node p, BitArray mark) { // true if graph can be derived to terminals
- while (p != null) {
- if (p.typ == Node.nt && !mark[p.sym.n]) return false;
- if (p.typ == Node.alt && !IsTerm(p.sub, mark)
- && (p.down == null || !IsTerm(p.down, mark))) return false;
- if (p.up) break;
- p = p.next;
- }
- return true;
- }
-
- public static bool AllNtToTerm() {
- bool changed, ok = true;
- BitArray mark = new BitArray(Symbol.nonterminals.Count);
- // a nonterminal is marked if it can be derived to terminal symbols
- do {
- changed = false;
- foreach (Symbol sym in Symbol.nonterminals)
- if (!mark[sym.n] && IsTerm(sym.graph, mark)) {
- mark[sym.n] = true; changed = true;
- }
- } while (changed);
- foreach (Symbol sym in Symbol.nonterminals)
- if (!mark[sym.n]) {
- ok = false; Errors.count++;
- Console.WriteLine(" {0} cannot be derived to terminals", sym.name);
- }
- return ok;
- }
-
- /*---------------------------------------------------------------------
- Utility functions
- ---------------------------------------------------------------------*/
-
- static int Num(Node p) {
- if (p == null) return 0; else return p.n;
- }
-
- static void PrintSym(Symbol sym) {
- Trace.Write("{0,3} {1,-14} {2}", sym.n, Node.Name(sym.name), Node.nTyp[sym.typ]);
- if (sym.attrPos==null) Trace.Write(" false "); else Trace.Write(" true ");
- if (sym.typ == Node.nt) {
- Trace.Write("{0,5}", Num(sym.graph));
- if (sym.deletable) Trace.Write(" true "); else Trace.Write(" false ");
- } else
- Trace.Write(" ");
- Trace.WriteLine("{0,5}", sym.line);
- }
-
- public static void PrintSymbolTable() {
- Trace.WriteLine("Symbol Table:");
- Trace.WriteLine("------------"); Trace.WriteLine();
- Trace.WriteLine(" nr name typ hasAt graph del line");
- foreach (Symbol sym in Symbol.terminals) PrintSym(sym);
- foreach (Symbol sym in Symbol.pragmas) PrintSym(sym);
- foreach (Symbol sym in Symbol.nonterminals) PrintSym(sym);
- Trace.WriteLine();
- }
-
- public static void XRef() {
- SortedList tab = new SortedList();
- // collect lines where symbols have been defined
- foreach (Symbol sym in Symbol.nonterminals) {
- ArrayList list = (ArrayList)tab[sym];
- if (list == null) {list = new ArrayList(); tab[sym] = list;}
- list.Add(- sym.line);
- }
- // collect lines where symbols have been referenced
- foreach (Node n in Node.nodes) {
- if (n.typ == Node.t || n.typ == Node.wt || n.typ == Node.nt) {
- ArrayList list = (ArrayList)tab[n.sym];
- if (list == null) {list = new ArrayList(); tab[n.sym] = list;}
- list.Add(n.line);
- }
- }
- // print cross reference list
- Trace.WriteLine();
- Trace.WriteLine("Cross reference list:");
- Trace.WriteLine("--------------------"); Trace.WriteLine();
- foreach (Symbol sym in tab.Keys) {
- Trace.Write(" {0,-12}", Node.Name(sym.name));
- ArrayList list = (ArrayList)tab[sym];
- int col = 14;
- foreach (int line in list) {
- if (col + 5 > 80) {
- Trace.WriteLine();
- for (col = 1; col <= 14; col++) Trace.Write(" ");
- }
- Trace.Write("{0,5}", line); col += 5;
- }
- Trace.WriteLine();
- }
- Trace.WriteLine(); Trace.WriteLine();
- }
-
- public static void SetDDT(string s) {
- s = s.ToUpper();
- foreach (char ch in s) {
- if ('0' <= ch && ch <= '9') ddt[ch - '0'] = true;
- else switch (ch) {
- case 'A' : ddt[0] = true; break; // trace automaton
- case 'F' : ddt[1] = true; break; // list first/follow sets
- case 'G' : ddt[2] = true; break; // print syntax graph
- case 'I' : ddt[3] = true; break; // trace computation of first sets
- case 'J' : ddt[4] = true; break; // print ANY and SYNC sets
- case 'P' : ddt[8] = true; break; // print statistics
- case 'S' : ddt[6] = true; break; // list symbol table
- case 'X' : ddt[7] = true; break; // list cross reference table
- default : break;
- }
- }
- }
-
- public static void Init () {
- eofSy = new Symbol(Node.t, "EOF", 0);
- }
-
-} // end Tab
-
-} // end namespace
+/* ------------------------------------------------------------------------
+ * Tab.cs
+ * Symbol table management of Coco/R
+ * by H.Moessenboeck, Univ. of Linz
+ * ------------------------------------------------------------------------*/
+using System;
+using System.IO;
+using System.Collections;
+
+namespace at.jku.ssw.Coco {
+
+public class Position { // position of source code stretch (e.g. semantic action, resolver expressions)
+ public int beg; // start relative to the beginning of the file
+ public int len; // length of stretch
+ public int col; // column number of start position
+
+ public Position(int beg, int len, int col) {
+ this.beg = beg; this.len = len; this.col = col;
+ }
+}
+
+
+//---------------------------------------------------------------------
+// Symbols
+//---------------------------------------------------------------------
+
+public class Symbol : IComparable {
+ public static ArrayList terminals = new ArrayList();
+ public static ArrayList pragmas = new ArrayList();
+ public static ArrayList nonterminals = new ArrayList();
+ public static Hashtable tokenNames = null; /* AW 2003-03-25 */
+
+ public const int classToken = 0; // token kinds
+ public const int litToken = 1;
+ public const int classLitToken = 2;
+
+ public int n; // symbol number
+ public int typ; // t, nt, pr, unknown, rslv /* ML 29_11_2002 slv added */ /* AW slv --> rslv */
+ public string name; // symbol name
+ public Node graph; // nt: to first node of syntax graph
+ public int tokenKind; // t: token kind (literal, class, ...)
+ public bool deletable; // nt: true if nonterminal is deletable
+ public bool firstReady; // nt: true if terminal start symbols have already been computed
+ public BitArray first; // nt: terminal start symbols
+ public BitArray follow; // nt: terminal followers
+ public BitArray nts; // nt: nonterminals whose followers have to be added to this sym
+ public int line; // source text line number of item in this node
+ public Position attrPos; // nt: position of attributes in source text (or null)
+ public Position semPos; // pr: pos of semantic action in source text (or null)
+ // nt: pos of local declarations in source text (or null)
+ public override string ToString()
+ {
+ return String.Format("[Symbol:Name={0}, n={1}]", name, n);
+ }
+ public Symbol(int typ, string name, int line) {
+ if (name.Length == 2 && name[0] == '"') {
+ Parser.SemErr("empty token not allowed"); name = "???";
+ }
+ if (name.IndexOf(' ') >= 0) Parser.SemErr("tokens must not contain blanks");
+ this.typ = typ; this.name = name; this.line = line;
+ switch (typ) {
+ case Node.t: n = terminals.Count; terminals.Add(this); break;
+ case Node.pr: pragmas.Add(this); break;
+ case Node.nt: n = nonterminals.Count; nonterminals.Add(this); break;
+ }
+ }
+
+ public static Symbol Find(string name) {
+ foreach (Symbol s in terminals)
+ if (s.name == name) return s;
+ foreach (Symbol s in nonterminals)
+ if (s.name == name) return s;
+ return null;
+ }
+
+ public int CompareTo(object x) {
+ return name.CompareTo(((Symbol)x).name);
+ }
+
+}
+
+
+//---------------------------------------------------------------------
+// Syntax graph (class Node, class Graph)
+//---------------------------------------------------------------------
+
+public class Node {
+ public static ArrayList nodes = new ArrayList();
+ public static string[] nTyp =
+ {" ", "t ", "pr ", "nt ", "clas", "chr ", "wt ", "any ", "eps ", /* AW 03-01-14 nTyp[0]: " " --> " " */
+ "sync", "sem ", "alt ", "iter", "opt ", "rslv"};
+
+ // constants for node kinds
+ public const int t = 1; // terminal symbol
+ public const int pr = 2; // pragma
+ public const int nt = 3; // nonterminal symbol
+ public const int clas = 4; // character class
+ public const int chr = 5; // character
+ public const int wt = 6; // weak terminal symbol
+ public const int any = 7; //
+ public const int eps = 8; // empty
+ public const int sync = 9; // synchronization symbol
+ public const int sem = 10; // semantic action: (. .)
+ public const int alt = 11; // alternative: |
+ public const int iter = 12; // iteration: { }
+ public const int opt = 13; // option: [ ]
+ public const int rslv = 14; // resolver expr /* ML */ /* AW 03-01-13 renamed slv --> rslv */
+
+ public const int normalTrans = 0; // transition codes
+ public const int contextTrans = 1;
+
+ public int n; // node number
+ public int typ; // t, nt, wt, chr, clas, any, eps, sem, sync, alt, iter, opt, rslv
+ public Node next; // to successor node
+ public Node down; // alt: to next alternative
+ public Node sub; // alt, iter, opt: to first node of substructure
+ public bool up; // true: "next" leads to successor in enclosing structure
+ public Symbol sym; // nt, t, wt: symbol represented by this node
+ public int val; // chr: ordinal character value
+ // clas: index of character class
+ public int code; // chr, clas: transition code
+ public BitArray set; // any, sync: the set represented by this node
+ public Position pos; // nt, t, wt: pos of actual attributes
+ // sem: pos of semantic action in source text
+ public int line; // source text line number of item in this node
+ public State state; // DFA state corresponding to this node
+ // (only used in DFA.ConvertToStates)
+
+ public Node(int typ, Symbol sym, int line) {
+ this.typ = typ; this.sym = sym; this.line = line;
+ n = nodes.Count;
+ nodes.Add(this);
+ }
+
+ public Node(int typ, Node sub): this(typ, null, 0) {
+ this.sub = sub;
+ }
+
+ public Node(int typ, int val, int line): this(typ, null, line) {
+ this.val = val;
+ }
+
+ public static bool DelGraph(Node p) {
+ return p == null || DelNode(p) && DelGraph(p.next);
+ }
+
+ public static bool DelAlt(Node p) {
+ return p == null || DelNode(p) && (p.up || DelAlt(p.next));
+ }
+
+ public static bool DelNode(Node p) {
+ if (p.typ == nt) return p.sym.deletable;
+ else if (p.typ == alt) return DelAlt(p.sub) || p.down != null && DelAlt(p.down);
+ else return p.typ == eps || p.typ == iter || p.typ == opt || p.typ == sem || p.typ == sync;
+ }
+
+ //----------------- for printing ----------------------
+
+ static int Ptr(Node p, bool up) {
+ if (p == null) return 0;
+ else if (up) return -p.n;
+ else return p.n;
+ }
+
+ static string Pos(Position pos) {
+ if (pos == null) return " "; else return String.Format("{0,5}", pos.beg);
+ }
+
+ public static string Name(string name) {
+ return (name + " ").Substring(0, 12);
+ /* isn't this better (less string allocations, easier to understand): *
+ * return (name.Length > 12) ? name.Substring(0,12) : name; */
+ }
+
+ public static void PrintNodes() {
+ Trace.WriteLine("Graph nodes:");
+ Trace.WriteLine("----------------------------------------------------");
+ Trace.WriteLine(" n type name next down sub pos line");
+ Trace.WriteLine(" val code");
+ Trace.WriteLine("----------------------------------------------------");
+ foreach (Node p in nodes) {
+ Trace.Write("{0,4} {1} ", p.n, nTyp[p.typ]);
+ if (p.sym != null)
+ Trace.Write("{0,12} ", Name(p.sym.name));
+ else if (p.typ == Node.clas) {
+ CharClass c = (CharClass)CharClass.classes[p.val];
+ Trace.Write("{0,12} ", Name(c.name));
+ } else Trace.Write(" ");
+ Trace.Write("{0,5} ", Ptr(p.next, p.up));
+ switch (p.typ) {
+ case t: case nt: case wt:
+ Trace.Write(" {0,5}", Pos(p.pos)); break;
+ case chr:
+ Trace.Write("{0,5} {1,5} ", p.val, p.code); break;
+ case clas:
+ Trace.Write(" {0,5} ", p.code); break;
+ case alt: case iter: case opt:
+ Trace.Write("{0,5} {1,5} ", Ptr(p.down, false), Ptr(p.sub, false)); break;
+ case sem:
+ Trace.Write(" {0,5}", Pos(p.pos)); break;
+ case eps: case any: case sync:
+ Trace.Write(" "); break;
+ }
+ Trace.WriteLine("{0,5}", p.line);
+ }
+ Trace.WriteLine();
+ }
+
+}
+
+
+public class Graph {
+ static Node dummyNode = new Node(Node.eps, null, 0);
+
+ public Node l; // left end of graph = head
+ public Node r; // right end of graph = list of nodes to be linked to successor graph
+
+ public Graph() {
+ l = null; r = null;
+ }
+
+ public Graph(Node left, Node right) {
+ l = left; r = right;
+ }
+
+ public Graph(Node p) {
+ l = p; r = p;
+ }
+
+ public static void MakeFirstAlt(Graph g) {
+ g.l = new Node(Node.alt, g.l); g.l.line = g.l.sub.line; /* AW 2002-03-07 make line available for error handling */
+ g.l.next = g.r;
+ g.r = g.l;
+ }
+
+ public static void MakeAlternative(Graph g1, Graph g2) {
+ g2.l = new Node(Node.alt, g2.l); g2.l.line = g2.l.sub.line;
+ Node p = g1.l; while (p.down != null) p = p.down;
+ p.down = g2.l;
+ p = g1.r; while (p.next != null) p = p.next;
+ p.next = g2.r;
+ }
+
+ public static void MakeSequence(Graph g1, Graph g2) {
+ Node p = g1.r.next; g1.r.next = g2.l; // link head node
+ while (p != null) { // link substructure
+ Node q = p.next; p.next = g2.l; p.up = true;
+ p = q;
+ }
+ g1.r = g2.r;
+ }
+
+ public static void MakeIteration(Graph g) {
+ g.l = new Node(Node.iter, g.l);
+ Node p = g.r;
+ g.r = g.l;
+ while (p != null) {
+ Node q = p.next; p.next = g.l; p.up = true;
+ p = q;
+ }
+ }
+
+ public static void MakeOption(Graph g) {
+ g.l = new Node(Node.opt, g.l);
+ g.l.next = g.r;
+ g.r = g.l;
+ }
+
+ public static void Finish(Graph g) {
+ Node p = g.r;
+ while (p != null) {
+ Node q = p.next; p.next = null; p = q;
+ }
+ }
+
+ public static void SetContextTrans(Node p) { // set transition code in the graph rooted at p
+ DFA.hasCtxMoves = true;
+ while (p != null) {
+ if (p.typ == Node.chr || p.typ == Node.clas) {
+ p.code = Node.contextTrans;
+ } else if (p.typ == Node.opt || p.typ == Node.iter) {
+ SetContextTrans(p.sub);
+ } else if (p.typ == Node.alt) {
+ SetContextTrans(p.sub); SetContextTrans(p.down);
+ }
+ if (p.up) break;
+ p = p.next;
+ }
+ }
+
+ public static void DeleteNodes() {
+ Node.nodes = new ArrayList();
+ dummyNode = new Node(Node.eps, null, 0);
+ }
+
+ public static Graph StrToGraph(string str) {
+ string s = DFA.Unescape(str.Substring(1, str.Length-2));
+ if (s.IndexOf('\0') >= 0) Parser.SemErr("\\0 not allowed here. Used as eof character");
+ if (s.Length == 0) Parser.SemErr("empty token not allowed");
+ Graph g = new Graph();
+ g.r = dummyNode;
+ for (int i = 0; i < s.Length; i++) {
+ Node p = new Node(Node.chr, (int)s[i], 0);
+ g.r.next = p; g.r = p;
+ }
+ g.l = dummyNode.next; dummyNode.next = null;
+ return g;
+ }
+
+}
+
+
+//----------------------------------------------------------------
+// Bit sets
+//----------------------------------------------------------------
+
+public class Sets {
+
+ public static int First(BitArray s) {
+ int max = s.Count;
+ for (int i=0; i<max; i++)
+ if (s[i]) return i;
+ return -1;
+ }
+
+ public static int Elements(BitArray s) {
+ int max = s.Count;
+ int n = 0;
+ for (int i=0; i<max; i++)
+ if (s[i]) n++;
+ return n;
+ }
+
+ public static bool Equals(BitArray a, BitArray b) {
+ int max = a.Count;
+ for (int i=0; i<max; i++)
+ if (a[i] != b[i]) return false;
+ return true;
+ }
+
+ public static bool Includes(BitArray a, BitArray b) { // a > b ?
+ int max = a.Count;
+ for (int i=0; i<max; i++)
+ if (b[i] && ! a[i]) return false;
+ return true;
+ }
+
+ public static bool Intersect(BitArray a, BitArray b) { // a * b != {}
+ int max = a.Count;
+ for (int i=0; i<max; i++)
+ if (a[i] && b[i]) return true;
+ return false;
+ }
+
+ public static void Subtract(BitArray a, BitArray b) { // a = a - b
+ BitArray c = (BitArray) b.Clone();
+ a.And(c.Not());
+ }
+
+ public static void PrintSet(BitArray s, int indent) {
+ int col, len;
+ col = indent;
+ foreach (Symbol sym in Symbol.terminals) {
+ if (s[sym.n]) {
+ len = sym.name.Length;
+ if (col + len >= 80) {
+ Trace.WriteLine();
+ for (col = 1; col < indent; col++) Trace.Write(" ");
+ }
+ Trace.Write("{0} ", sym.name);
+ col += len + 1;
+ }
+ }
+ if (col == indent) Trace.Write("-- empty set --");
+ Trace.WriteLine();
+ }
+
+}
+
+
+//---------------------------------------------------------------------
+// Character class management
+//---------------------------------------------------------------------
+
+public class CharClass {
+ public static ArrayList classes = new ArrayList();
+ public static int dummyName = 'A';
+
+ public const int charSetSize = 256; // must be a multiple of 16
+
+ public int n; // class number
+ public string name; // class name
+ public BitArray set; // set representing the class
+
+ public CharClass(string name, BitArray s) {
+ if (name == "#") name = "#" + (char)dummyName++;
+ this.n = classes.Count; this.name = name; this.set = s;
+ classes.Add(this);
+ }
+
+ public static CharClass Find(string name) {
+ foreach (CharClass c in classes)
+ if (c.name == name) return c;
+ return null;
+ }
+
+ public static CharClass Find(BitArray s) {
+ foreach (CharClass c in classes)
+ if (Sets.Equals(s, c.set)) return c;
+ return null;
+ }
+
+ public static BitArray Set(int i) {
+ return ((CharClass)classes[i]).set;
+ }
+
+ static string Ch(int ch) {
+ if (ch < ' ' || ch >= 127 || ch == '\'' || ch == '\\') return ch.ToString();
+ else return String.Format("'{0}'", (char)ch);
+ }
+
+ static void WriteCharSet(BitArray s) {
+ int i = 0, len = s.Count;
+ while (i < len) {
+ while (i < len && !s[i]) i++;
+ if (i == len) break;
+ int j = i;
+ while (i < len && s[i]) i++;
+ if (j < i-1) Trace.Write("{0}..{1} ", Ch(j), Ch(i-1));
+ else Trace.Write("{0} ", Ch(j));
+ }
+ }
+
+ public static void WriteClasses () {
+ foreach (CharClass c in classes) {
+ Trace.Write("{0,-10}: ", c.name);
+ WriteCharSet(c.set);
+ Trace.WriteLine();
+ }
+ Trace.WriteLine();
+ }
+}
+
+
+//-----------------------------------------------------------
+// Symbol table management routines
+//-----------------------------------------------------------
+
+public class Tab {
+ public static Position semDeclPos; // position of global semantic declarations
+ public static BitArray ignored; // characters ignored by the scanner
+ public static bool[] ddt = new bool[10]; // debug and test switches
+ public static Symbol gramSy; // root nonterminal; filled by ATG
+ public static Symbol eofSy; // end of file symbol
+ public static Symbol noSym; // used in case of an error
+ public static BitArray allSyncSets; // union of all synchronisation sets
+ public static string nsName; // namespace for generated files
+
+ static BitArray visited; // mark list for graph traversals
+ static Symbol curSy; // current symbol in computation of sets
+
+ //---------------------------------------------------------------------
+ // Symbol set computations
+ //---------------------------------------------------------------------
+
+ /* Computes the first set for the given Node. */
+ static BitArray First0(Node p, BitArray mark) {
+ BitArray fs = new BitArray(Symbol.terminals.Count);
+ while (p != null && !mark[p.n]) {
+ mark[p.n] = true;
+ switch (p.typ) {
+ case Node.nt: {
+ if (p.sym.firstReady) fs.Or(p.sym.first);
+ else fs.Or(First0(p.sym.graph, mark));
+ break;
+ }
+ case Node.t: case Node.wt: {
+ fs[p.sym.n] = true; break;
+ }
+ case Node.any: {
+ fs.Or(p.set); break;
+ }
+ case Node.alt: {
+ fs.Or(First0(p.sub, mark));
+ fs.Or(First0(p.down, mark));
+ break;
+ }
+ case Node.iter: case Node.opt: {
+ fs.Or(First0(p.sub, mark));
+ break;
+ }
+ }
+ if (!Node.DelNode(p)) break;
+ p = p.next;
+ }
+ return fs;
+ }
+
+ /// <returns>
+ /// BitArray which contains the first tokens.
+ /// </returns>
+ public static BitArray First(Node p) {
+ BitArray fs = First0(p, new BitArray(Node.nodes.Count));
+ if (ddt[3]) {
+ Trace.WriteLine();
+ if (p != null) Trace.WriteLine("First: node = {0}", p.n);
+ else Trace.WriteLine("First: node = null");
+ Sets.PrintSet(fs, 0);
+ }
+ return fs;
+ }
+
+
+ static void CompFirstSets() {
+ foreach (Symbol sym in Symbol.nonterminals) {
+ sym.first = new BitArray(Symbol.terminals.Count);
+ sym.firstReady = false;
+ }
+ foreach (Symbol sym in Symbol.nonterminals) {
+ sym.first = First(sym.graph);
+ sym.firstReady = true;
+ }
+ }
+
+ static void CompFollow(Node p) {
+ while (p != null && !visited[p.n]) {
+ visited[p.n] = true;
+ if (p.typ == Node.nt) {
+ BitArray s = First(p.next);
+ p.sym.follow.Or(s);
+ if (Node.DelGraph(p.next))
+ p.sym.nts[curSy.n] = true;
+ } else if (p.typ == Node.opt || p.typ == Node.iter) {
+ CompFollow(p.sub);
+ } else if (p.typ == Node.alt) {
+ CompFollow(p.sub); CompFollow(p.down);
+ }
+ p = p.next;
+ }
+ }
+
+ static void Complete(Symbol sym) {
+ if (!visited[sym.n]) {
+ visited[sym.n] = true;
+ foreach (Symbol s in Symbol.nonterminals) {
+ if (sym.nts[s.n]) {
+ Complete(s);
+ sym.follow.Or(s.follow);
+ if (sym == curSy) sym.nts[s.n] = false;
+ }
+ }
+ }
+ }
+
+ static void CompFollowSets() {
+ foreach (Symbol sym in Symbol.nonterminals) {
+ sym.follow = new BitArray(Symbol.terminals.Count);
+ sym.nts = new BitArray(Symbol.nonterminals.Count);
+ }
+ visited = new BitArray(Node.nodes.Count);
+ foreach (Symbol sym in Symbol.nonterminals) { // get direct successors of nonterminals
+ curSy = sym;
+ CompFollow(sym.graph);
+ }
+ foreach (Symbol sym in Symbol.nonterminals) { // add indirect successors to followers
+ visited = new BitArray(Symbol.nonterminals.Count);
+ curSy = sym;
+ Complete(sym);
+ }
+ }
+
+ static Node LeadingAny(Node p) {
+ if (p == null) return null;
+ Node a = null;
+ if (p.typ == Node.any) a = p;
+ else if (p.typ == Node.alt) {
+ a = LeadingAny(p.sub);
+ if (a == null) a = LeadingAny(p.down);
+ }
+ else if (p.typ == Node.opt || p.typ == Node.iter) a = LeadingAny(p.sub);
+ else if (Node.DelNode(p) && !p.up) a = LeadingAny(p.next);
+ return a;
+ }
+
+ static void FindAS(Node p) { // find ANY sets
+ Node a;
+ while (p != null) {
+ if (p.typ == Node.opt || p.typ == Node.iter) {
+ FindAS(p.sub);
+ a = LeadingAny(p.sub);
+ if (a != null) Sets.Subtract(a.set, First(p.next));
+ } else if (p.typ == Node.alt) {
+ BitArray s1 = new BitArray(Symbol.terminals.Count);
+ Node q = p;
+ while (q != null) {
+ FindAS(q.sub);
+ a = LeadingAny(q.sub);
+ if (a != null)
+ Sets.Subtract(a.set, First(q.down).Or(s1));
+ else
+ s1.Or(First(q.sub));
+ q = q.down;
+ }
+ }
+ if (p.up) break;
+ p = p.next;
+ }
+ }
+
+ static void CompAnySets() {
+ foreach (Symbol sym in Symbol.nonterminals) FindAS(sym.graph);
+ }
+
+ public static BitArray Expected(Node p, Symbol curSy) {
+ BitArray s = First(p);
+ if (Node.DelGraph(p)) s.Or(curSy.follow);
+ return s;
+ }
+
+ public static BitArray Expected(Node p, Symbol curSy, int outmost) {
+ BitArray s = First(p);
+ if (Node.DelGraph(p)) s.Or(curSy.follow);
+ return s;
+ }
+
+ static void CompSync(Node p) {
+ while (p != null && !visited[p.n]) {
+ visited[p.n] = true;
+ if (p.typ == Node.sync) {
+ BitArray s = Expected(p.next, curSy);
+ s[eofSy.n] = true;
+ allSyncSets.Or(s);
+ p.set = s;
+ } else if (p.typ == Node.alt) {
+ CompSync(p.sub); CompSync(p.down);
+ } else if (p.typ == Node.opt || p.typ == Node.iter)
+ CompSync(p.sub);
+ p = p.next;
+ }
+ }
+
+ static void CompSyncSets() {
+ allSyncSets = new BitArray(Symbol.terminals.Count);
+ allSyncSets[eofSy.n] = true;
+ visited = new BitArray(Node.nodes.Count);
+ foreach (Symbol sym in Symbol.nonterminals) {
+ curSy = sym;
+ CompSync(curSy.graph);
+ }
+ }
+
+ public static void SetupAnys() {
+ foreach (Node p in Node.nodes)
+ if (p.typ == Node.any) {
+ p.set = new BitArray(Symbol.terminals.Count, true);
+ p.set[eofSy.n] = false;
+ }
+ }
+
+ public static void CompDeletableSymbols() {
+ bool changed;
+ do {
+ changed = false;
+ foreach (Symbol sym in Symbol.nonterminals)
+ if (!sym.deletable && sym.graph != null && Node.DelGraph(sym.graph)) {
+ sym.deletable = true; changed = true;
+ }
+ } while (changed);
+ foreach (Symbol sym in Symbol.nonterminals)
+ if (sym.deletable) Console.WriteLine(" {0} deletable", sym.name);
+ }
+
+ public static void RenumberPragmas() {
+ int n = Symbol.terminals.Count;
+ foreach (Symbol sym in Symbol.pragmas) sym.n = n++;
+ }
+
+ public static void CompSymbolSets() {
+ CompDeletableSymbols();
+ CompFirstSets();
+ CompFollowSets();
+ CompAnySets();
+ CompSyncSets();
+ if (ddt[1]) {
+ Trace.WriteLine();
+ Trace.WriteLine("First & follow symbols:");
+ Trace.WriteLine("----------------------"); Trace.WriteLine();
+ foreach (Symbol sym in Symbol.nonterminals) {
+ Trace.WriteLine(sym.name);
+ Trace.Write("first: "); Sets.PrintSet(sym.first, 10);
+ Trace.Write("follow: "); Sets.PrintSet(sym.follow, 10);
+ Trace.WriteLine();
+ }
+ }
+ if (ddt[4]) {
+ Trace.WriteLine();
+ Trace.WriteLine("ANY and SYNC sets:");
+ Trace.WriteLine("-----------------");
+ foreach (Node p in Node.nodes)
+ if (p.typ == Node.any || p.typ == Node.sync) {
+ Trace.Write("{0,4} {1,4}: ", p.n, Node.nTyp[p.typ]);
+ Sets.PrintSet(p.set, 11);
+ }
+ }
+ }
+
+ //---------------------------------------------------------------------
+ // Grammar checks
+ //---------------------------------------------------------------------
+
+ public static bool GrammarOk() {
+ bool ok = NtsComplete()
+ && AllNtReached()
+ && NoCircularProductions()
+ && AllNtToTerm();
+ if (ok) CheckLL1();
+ return ok;
+ }
+
+ //--------------- check for circular productions ----------------------
+
+ class CNode { // node of list for finding circular productions
+ public Symbol left, right;
+
+ public CNode (Symbol l, Symbol r) {
+ left = l; right = r;
+ }
+ }
+
+ static void GetSingles(Node p, ArrayList singles) {
+ if (p == null) return; // end of graph
+ if (p.typ == Node.nt) {
+ if (p.up || Node.DelGraph(p.next)) singles.Add(p.sym);
+ } else if (p.typ == Node.alt || p.typ == Node.iter || p.typ == Node.opt) {
+ if (p.up || Node.DelGraph(p.next)) {
+ GetSingles(p.sub, singles);
+ if (p.typ == Node.alt) GetSingles(p.down, singles);
+ }
+ }
+ if (!p.up && Node.DelNode(p)) GetSingles(p.next, singles);
+ }
+
+ public static bool NoCircularProductions() {
+ bool ok, changed, onLeftSide, onRightSide;
+ ArrayList list = new ArrayList();
+ foreach (Symbol sym in Symbol.nonterminals) {
+ ArrayList singles = new ArrayList();
+ GetSingles(sym.graph, singles); // get nonterminals s such that sym-->s
+ foreach (Symbol s in singles) list.Add(new CNode(sym, s));
+ }
+ do {
+ changed = false;
+ for (int i = 0; i < list.Count; i++) {
+ CNode n = (CNode)list[i];
+ onLeftSide = false; onRightSide = false;
+ foreach (CNode m in list) {
+ if (n.left == m.right) onRightSide = true;
+ if (n.right == m.left) onLeftSide = true;
+ }
+ if (!onLeftSide || !onRightSide) {
+ list.Remove(n); i--; changed = true;
+ }
+ }
+ } while(changed);
+ ok = true;
+ foreach (CNode n in list) {
+ ok = false; Errors.count++;
+ Console.WriteLine(" {0} --> {1}", n.left.name, n.right.name);
+ }
+ return ok;
+ }
+
+ //--------------- check for LL(1) errors ----------------------
+
+ static void LL1Error(int cond, Symbol sym) {
+ Console.Write(" LL1 warning in {0}: ", curSy.name);
+ if (sym != null) Console.Write("{0} is ", sym.name);
+ switch (cond) {
+ case 1: Console.WriteLine(" start of several alternatives"); break;
+ case 2: Console.WriteLine(" start & successor of deletable structure"); break;
+ case 3: Console.WriteLine(" an ANY node that matches no symbol"); break;
+ }
+ }
+
+ static void CheckOverlap(BitArray s1, BitArray s2, int cond) {
+ foreach (Symbol sym in Symbol.terminals) {
+ if (s1[sym.n] && s2[sym.n]) LL1Error(cond, sym);
+ }
+ }
+
+ static void CheckAlts(Node p) {
+ BitArray s1, s2;
+ while (p != null) {
+ if (p.typ == Node.alt) {
+ Node q = p;
+ s1 = new BitArray(Symbol.terminals.Count);
+ while (q != null) { // for all alternatives
+ s2 = Expected(q.sub, curSy);
+ CheckOverlap(s1, s2, 1);
+ s1.Or(s2);
+ CheckAlts(q.sub);
+ q = q.down;
+ }
+ } else if (p.typ == Node.opt || p.typ == Node.iter) {
+ s1 = Expected(p.sub, curSy);
+ s2 = Expected(p.next, curSy);
+ CheckOverlap(s1, s2, 2);
+ CheckAlts(p.sub);
+ } else if (p.typ == Node.any) {
+ if (Sets.Elements(p.set) == 0) LL1Error(3, null);
+ // e.g. {ANY} ANY or [ANY] ANY
+ }
+ if (p.up) break;
+ p = p.next;
+ }
+ }
+
+ static void RSlvError(string msg) {
+ Console.WriteLine(msg);
+ }
+
+
+ static void CheckResolver(Node p) {
+ while (p != null) {
+ // check subnodes of current node p
+ if ((p.typ == Node.alt || p.typ == Node.iter || p.typ == Node.opt) &&
+ !p.sub.up)
+ if (p.sub.typ == Node.rslv) CheckResolver(p.sub.next);
+ else CheckResolver(p.sub);
+
+ // check current node p
+ switch (p.typ) {
+ case Node.alt:
+ BitArray uncovered = new BitArray(Symbol.terminals.Count); // first symbols of alternatives without a resolver (not "covered" by a resolver)
+ ArrayList coveredList = new ArrayList(); // list of follow symbols of each resolver (these are "covered" by the resolver)
+ ArrayList rslvList = new ArrayList();
+
+ // build set of uncovered first symbols & check for misplaced resolvers
+ // (= not at the first n-1 of n conflicting alternatives)
+ Node q = p;
+ while (q != null) {
+ BitArray curCovered;
+ if (q.sub.typ == Node.rslv) {
+ // get followers of resolver (these are "covered" by it)
+ if (q.sub.next == null) curCovered = curSy.follow;
+ else curCovered = First0(q.sub.next, new BitArray(Node.nodes.Count));
+ coveredList.Add(curCovered);
+ rslvList.Add(q.sub);
+ // resolver must "cover" all but the last occurrence of a conflicting symbol
+ if (Sets.Intersect(uncovered, curCovered))
+ RSlvError("Misplaced resolver at line " + q.sub.line + " will never be evaluated. " +
+ "Place resolver at previous conflicting alternative.");
+ } else uncovered.Or(First0(q.sub, new BitArray(Node.nodes.Count)));
+ q = q.down;
+ }
+
+ // check for obsolete resolvers
+ // (= alternatives starting with resolvers, when there is no conflict)
+ BitArray[] covered = (BitArray[]) coveredList.ToArray(typeof(BitArray));
+ Node[] rslvs = (Node[]) rslvList.ToArray(typeof(Node));
+ for (int i = 0; i < rslvs.Length; ++i) {
+ if (!Sets.Intersect(uncovered, covered[i]))
+ RSlvError("Obsolete resolver at line " + rslvs[i].line + ". " +
+ "Neither of the start symbols of the alternative occurs without a resolver.");
+ /*
+ if (!Sets.Includes(uncovered, covered[i]))
+ RSlvError("At least one of the symbols after the resolver at line " + rslvs[i].line +
+ " does not appear without a resolver. Remove the last resolver covering this symbol.");
+ */
+ /*
+ if (Sets.Equals(, covered[i]))
+ RSlvError("Resolver at line " + rslvArr[i].line + " covers more symbols than necessary.\n" +
+ "Place resolvers only in front of conflicting symbols.");
+ */
+ }
+ break;
+ case Node.iter: case Node.opt:
+ if (p.sub.typ == Node.rslv) {
+ BitArray fs = First0(p.sub.next, new BitArray(Node.nodes.Count));
+ BitArray fsNext;
+ if (p.next == null) fsNext = curSy.follow;
+ else fsNext = First0(p.next, new BitArray(Node.nodes.Count));
+ if (!Sets.Intersect(fs, fsNext))
+ RSlvError("Obsolete resolver expression (IF ...) at line " + p.sub.line);
+ }
+ break;
+ case Node.rslv:
+ RSlvError("Unexpected Resolver in line " + p.line + ". Will cause parsing error.");
+ break;
+ }
+ if (p.up) break;
+ p = p.next;
+ }
+ }
+
+ public static void CheckLL1() {
+ foreach (Symbol sym in Symbol.nonterminals) {
+ curSy = sym;
+ CheckAlts(curSy.graph);
+ CheckResolver(curSy.graph);
+ }
+ }
+
+ //------------- check if every nts has a production --------------------
+
+ public static bool NtsComplete() {
+ bool complete = true;
+ foreach (Symbol sym in Symbol.nonterminals) {
+ if (sym.graph == null) {
+ complete = false; Errors.count++;
+ Console.WriteLine(" No production for {0}", sym.name);
+ }
+ }
+ return complete;
+ }
+
+ //-------------- check if every nts can be reached -----------------
+
+ static void MarkReachedNts(Node p) {
+ while (p != null) {
+ if (p.typ == Node.nt && !visited[p.sym.n]) { // new nt reached
+ visited[p.sym.n] = true;
+ MarkReachedNts(p.sym.graph);
+ } else if (p.typ == Node.alt || p.typ == Node.iter || p.typ == Node.opt) {
+ MarkReachedNts(p.sub);
+ if (p.typ == Node.alt) MarkReachedNts(p.down);
+ }
+ if (p.up) break;
+ p = p.next;
+ }
+ }
+
+ public static bool AllNtReached() {
+ bool ok = true;
+ visited = new BitArray(Symbol.nonterminals.Count);
+ visited[gramSy.n] = true;
+ MarkReachedNts(gramSy.graph);
+ foreach (Symbol sym in Symbol.nonterminals) {
+ if (!visited[sym.n]) {
+ ok = false; Errors.count++;
+ Console.WriteLine(" {0} cannot be reached", sym.name);
+ }
+ }
+ return ok;
+ }
+
+ //--------- check if every nts can be derived to terminals ------------
+
+ static bool IsTerm(Node p, BitArray mark) { // true if graph can be derived to terminals
+ while (p != null) {
+ if (p.typ == Node.nt && !mark[p.sym.n]) return false;
+ if (p.typ == Node.alt && !IsTerm(p.sub, mark)
+ && (p.down == null || !IsTerm(p.down, mark))) return false;
+ if (p.up) break;
+ p = p.next;
+ }
+ return true;
+ }
+
+ public static bool AllNtToTerm() {
+ bool changed, ok = true;
+ BitArray mark = new BitArray(Symbol.nonterminals.Count);
+ // a nonterminal is marked if it can be derived to terminal symbols
+ do {
+ changed = false;
+ foreach (Symbol sym in Symbol.nonterminals)
+ if (!mark[sym.n] && IsTerm(sym.graph, mark)) {
+ mark[sym.n] = true; changed = true;
+ }
+ } while (changed);
+ foreach (Symbol sym in Symbol.nonterminals)
+ if (!mark[sym.n]) {
+ ok = false; Errors.count++;
+ Console.WriteLine(" {0} cannot be derived to terminals", sym.name);
+ }
+ return ok;
+ }
+
+ /*---------------------------------------------------------------------
+ Utility functions
+ ---------------------------------------------------------------------*/
+
+ static int Num(Node p) {
+ if (p == null) return 0; else return p.n;
+ }
+
+ static void PrintSym(Symbol sym) {
+ Trace.Write("{0,3} {1,-14} {2}", sym.n, Node.Name(sym.name), Node.nTyp[sym.typ]);
+ if (sym.attrPos==null) Trace.Write(" false "); else Trace.Write(" true ");
+ if (sym.typ == Node.nt) {
+ Trace.Write("{0,5}", Num(sym.graph));
+ if (sym.deletable) Trace.Write(" true "); else Trace.Write(" false ");
+ } else
+ Trace.Write(" ");
+ Trace.WriteLine("{0,5}", sym.line);
+ }
+
+ public static void PrintSymbolTable() {
+ Trace.WriteLine("Symbol Table:");
+ Trace.WriteLine("------------"); Trace.WriteLine();
+ Trace.WriteLine(" nr name typ hasAt graph del line");
+ foreach (Symbol sym in Symbol.terminals) PrintSym(sym);
+ foreach (Symbol sym in Symbol.pragmas) PrintSym(sym);
+ foreach (Symbol sym in Symbol.nonterminals) PrintSym(sym);
+ Trace.WriteLine();
+ }
+
+ public static void XRef() {
+ SortedList tab = new SortedList();
+ // collect lines where symbols have been defined
+ foreach (Symbol sym in Symbol.nonterminals) {
+ ArrayList list = (ArrayList)tab[sym];
+ if (list == null) {list = new ArrayList(); tab[sym] = list;}
+ list.Add(- sym.line);
+ }
+ // collect lines where symbols have been referenced
+ foreach (Node n in Node.nodes) {
+ if (n.typ == Node.t || n.typ == Node.wt || n.typ == Node.nt) {
+ ArrayList list = (ArrayList)tab[n.sym];
+ if (list == null) {list = new ArrayList(); tab[n.sym] = list;}
+ list.Add(n.line);
+ }
+ }
+ // print cross reference list
+ Trace.WriteLine();
+ Trace.WriteLine("Cross reference list:");
+ Trace.WriteLine("--------------------"); Trace.WriteLine();
+ foreach (Symbol sym in tab.Keys) {
+ Trace.Write(" {0,-12}", Node.Name(sym.name));
+ ArrayList list = (ArrayList)tab[sym];
+ int col = 14;
+ foreach (int line in list) {
+ if (col + 5 > 80) {
+ Trace.WriteLine();
+ for (col = 1; col <= 14; col++) Trace.Write(" ");
+ }
+ Trace.Write("{0,5}", line); col += 5;
+ }
+ Trace.WriteLine();
+ }
+ Trace.WriteLine(); Trace.WriteLine();
+ }
+
+ public static void SetDDT(string s) {
+ s = s.ToUpper();
+ foreach (char ch in s) {
+ if ('0' <= ch && ch <= '9') ddt[ch - '0'] = true;
+ else switch (ch) {
+ case 'A' : ddt[0] = true; break; // trace automaton
+ case 'F' : ddt[1] = true; break; // list first/follow sets
+ case 'G' : ddt[2] = true; break; // print syntax graph
+ case 'I' : ddt[3] = true; break; // trace computation of first sets
+ case 'J' : ddt[4] = true; break; // print ANY and SYNC sets
+ case 'P' : ddt[8] = true; break; // print statistics
+ case 'S' : ddt[6] = true; break; // list symbol table
+ case 'X' : ddt[7] = true; break; // list cross reference table
+ default : break;
+ }
+ }
+ }
+
+ public static void Init () {
+ eofSy = new Symbol(Node.t, "EOF", 0);
+ }
+
+} // end Tab
+
+} // end namespace
Modified: trunk/MonoDevelop/src/Tools/SharpCoco/src/Trace.cs
===================================================================
--- trunk/MonoDevelop/src/Tools/SharpCoco/src/Trace.cs 2004-04-09 12:41:44 UTC (rev 1420)
+++ trunk/MonoDevelop/src/Tools/SharpCoco/src/Trace.cs 2004-04-09 17:17:47 UTC (rev 1421)
@@ -1,37 +1,37 @@
-using System;
-using System.IO;
-
-namespace at.jku.ssw.Coco {
-
-class Trace {
- const string FILENAME = "trace.txt";
- static StreamWriter trace;
-
- public static void Init (String dir) {
- FileStream s;
- try {
- s = new FileStream(dir + FILENAME, FileMode.Create); /* AW use FILENAME */
- trace = new StreamWriter(s);
- } catch (IOException) {
- Errors.Exception("-- could not open trace file");
- }
- }
-
- public static void Write (string s) { trace.Write(s); }
-
- public static void Write (string s, params object[] args) {
- trace.Write(s, args);
- }
-
- public static void WriteLine (string s) { trace.WriteLine(s); }
-
- public static void WriteLine (string s, params object[] args) {
- trace.WriteLine(s, args);
- }
-
- public static void WriteLine () { trace.WriteLine(); }
-
- public static void Close () { trace.Close(); }
-}
-
-}
+using System;
+using System.IO;
+
+namespace at.jku.ssw.Coco {
+
+class Trace {
+ const string FILENAME = "trace.txt";
+ static StreamWriter trace;
+
+ public static void Init (String dir) {
+ FileStream s;
+ try {
+ s = new FileStream(dir + FILENAME, FileMode.Create); /* AW use FILENAME */
+ trace = new StreamWriter(s);
+ } catch (IOException) {
+ Errors.Exception("-- could not open trace file");
+ }
+ }
+
+ public static void Write (string s) { trace.Write(s); }
+
+ public static void Write (string s, params object[] args) {
+ trace.Write(s, args);
+ }
+
+ public static void WriteLine (string s) { trace.WriteLine(s); }
+
+ public static void WriteLine (string s, params object[] args) {
+ trace.WriteLine(s, args);
+ }
+
+ public static void WriteLine () { trace.WriteLine(); }
+
+ public static void Close () { trace.Close(); }
+}
+
+}
More information about the Monodevelop-patches-list
mailing list