Browse Source

removed sharpcoco binary because it's not used. removed sharpcoco source code because it doesn't match the version used.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@1977 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Markus Palme 20 years ago
parent
commit
af50fcaf60
  1. BIN
      src/Libraries/NRefactory/Project/Src/Parser/Frames/OldSharpCoco.exe
  2. 55
      src/Libraries/NRefactory/Project/Src/Parser/Frames/Parser.frame.new
  3. 50
      src/Libraries/NRefactory/Project/Src/Parser/Frames/Parser.frame.old
  4. 6496
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs
  5. 22
      src/Libraries/NRefactory/Project/Src/Parser/gen.bat
  6. BIN
      src/Tools/SharpCoco/bin/Debug/SharpCoco.exe
  7. BIN
      src/Tools/SharpCoco/bin/Debug/SharpCoco.pdb
  8. 14
      src/Tools/SharpCoco/readme.txt
  9. 32
      src/Tools/SharpCoco/src/AssemblyInfo.cs
  10. 461
      src/Tools/SharpCoco/src/Coco.atg
  11. 97
      src/Tools/SharpCoco/src/Coco.cs
  12. 952
      src/Tools/SharpCoco/src/DFA.cs
  13. 785
      src/Tools/SharpCoco/src/Parser.cs
  14. 140
      src/Tools/SharpCoco/src/Parser.frame
  15. 432
      src/Tools/SharpCoco/src/ParserGen.cs
  16. 358
      src/Tools/SharpCoco/src/Scanner.cs
  17. 202
      src/Tools/SharpCoco/src/Scanner.frame
  18. 53
      src/Tools/SharpCoco/src/SharpCoco.csproj
  19. 6
      src/Tools/SharpCoco/src/SharpCoco.csproj.user
  20. 1082
      src/Tools/SharpCoco/src/Tab.cs
  21. 69
      src/Tools/SharpCoco/src/Trace.cs

BIN
src/Libraries/NRefactory/Project/Src/Parser/Frames/OldSharpCoco.exe

Binary file not shown.

55
src/Libraries/NRefactory/Project/Src/Parser/Frames/Parser.frame.new

@ -1,55 +0,0 @@
-->begin
/*
Parser.frame file for NRefactory.
*/
using System;
using System.Reflection;
-->namespace
internal class Parser : AbstractParser
{
-->constants
const bool T = true;
const bool x = false;
-->declarations
/*
-->pragmas
*/
-->productions
public Parser(ILexer lexer) : base(lexer)
{
}
public override void Parse()
{
-->parseRoot
}
private bool StartOf(int s)
{
return set[s, lexer.LookAhead.kind];
}
static bool[,] set = {
-->initialization
};
protected override void SynErr(int line, int col, int errorNumber)
{
errors.count++;
string s;
switch (errorNumber) {
-->errors
default: s = "error " + errorNumber; break;
}
this.Errors.Error(line, col, s);
}
} // end Parser
$$$

50
src/Libraries/NRefactory/Project/Src/Parser/Frames/Parser.frame.old

@ -1,50 +0,0 @@
/*
Parser.frame file for NRefactory.
*/
using System;
using System.Reflection;
-->namespace
-->tokens
partial class Parser : AbstractParser
{
-->constants
const bool T = true;
const bool x = false;
-->declarations
/*
-->pragmas
*/
-->productions
public override void Parse()
{
-->parseRoot
}
protected override void SynErr(int line, int col, int errorNumber)
{
string s;
switch (errorNumber) {
-->errors
default: s = "error " + errorNumber; break;
}
this.Errors.Error(line, col, s);
}
private bool StartOf(int s)
{
return set[s, lexer.LookAhead.kind];
}
static bool[,] set = {
-->initialization
};
} // end Parser
$$$

6496
src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs

File diff suppressed because it is too large Load Diff

22
src/Libraries/NRefactory/Project/Src/Parser/gen.bat

@ -1,10 +1,9 @@
@echo off @echo off
goto old goto new
:new :new
echo Generating with new #Coco echo Generating with #Coco
copy Frames\Parser.frame.new Frames\Parser.frame
cd CSharp cd CSharp
..\Frames\SharpCoco -namespace ICSharpCode.NRefactory.Parser.CSharp -frames ..\Frames cs.ATG ..\Frames\SharpCoco -namespace ICSharpCode.NRefactory.Parser.CSharp -frames ..\Frames cs.ATG
del Parser.cs.old >NUL del Parser.cs.old >NUL
@ -15,23 +14,6 @@ cd VBNet
del Parser.cs.old >NUL del Parser.cs.old >NUL
goto exit goto exit
:old
echo Generating with old #Coco
copy Frames\Parser.frame.old Frames\Parser.frame
cd Frames
copy ..\CSharp\cs.ATG
OldSharpCoco -namespace ICSharpCode.NRefactory.Parser.CSharp cs.ATG
move Parser.cs ..\CSharp
copy ..\VBNet\VBNET.ATG
OldSharpCoco -trace GIPXA -namespace ICSharpCode.NRefactory.Parser.VB VBNET.ATG
move Parser.cs ..\VBNet
del cs.ATG
del VBNET.ATG
:exit :exit
pause pause
cd .. cd ..

BIN
src/Tools/SharpCoco/bin/Debug/SharpCoco.exe

Binary file not shown.

BIN
src/Tools/SharpCoco/bin/Debug/SharpCoco.pdb

Binary file not shown.

14
src/Tools/SharpCoco/readme.txt

@ -1,14 +0,0 @@
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

32
src/Tools/SharpCoco/src/AssemblyInfo.cs

@ -1,32 +0,0 @@
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("2.0.0.1")]
// 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("")]

461
src/Tools/SharpCoco/src/Coco.atg

@ -1,461 +0,0 @@
/*-------------------------------------------------------------------------
Coco.ATG -- Attributed Grammar
Compiler Generator Coco/R,
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
extended by M. Loeberbauer & A. Woess, Univ. of Linz
with improvements by Pat Terry, Rhodes University
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
As an exception, it is allowed to write an extension of Coco/R that is
used as a plugin in non-free software.
If not otherwise stated, any source code generated by Coco/R (other than
Coco/R itself) does not fall under the GNU General Public License.
-------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------
compile with:
Coco Coco.ATG -namespace at.jku.ssw.Coco
-------------------------------------------------------------------------*/
using System.Collections;
COMPILER Coco
const int id = 0;
const int str = 1;
static bool genScanner;
static string tokenString; // used in declarations of literal tokens
static string noString = "-none-"; // used in declarations of literal tokens
/*-------------------------------------------------------------------------*/
CHARACTERS
letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".
digit = "0123456789".
cr = '\r'.
lf = '\n'.
tab = '\t'.
stringCh = ANY - '"' - '\\' - cr - lf.
charCh = ANY - '\'' - '\\' - cr - lf.
printable = '\u0020' .. '\u007e'.
hex = "0123456789abcdef".
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
IGNORE cr + lf + tab
/*-------------------------------------------------------------------------*/
PRODUCTIONS
Coco (. Symbol sym; Graph g, g1, g2; string gramName; .)
=
[ UsingDecl<out ParserGen.usingPos> ]
"COMPILER" (. genScanner = true; Tab.ignored = null; .)
ident (. gramName = t.val;
int beg = la.pos;
.)
{ ANY } (. Tab.semDeclPos = new Position(beg, la.pos-beg, 0); .)
[ "IGNORECASE" (. DFA.ignoreCase = true; .) ] /* pdt */
[ "CHARACTERS" { SetDecl }]
[ "TOKENS" { TokenDecl<Node.t> }]
[ "PRAGMAS" { TokenDecl<Node.pr> }]
{ "COMMENTS" (. bool nested = false; .)
"FROM" TokenExpr<out g1>
"TO" TokenExpr<out g2>
[ "NESTED" (. nested = true; .)
] (. new Comment(g1.l, g2.l, nested); .)
}
{ "IGNORE"
Set<out Tab.ignored> (. Tab.ignored[' '] = true; /* ' ' is always ignored */ .)
}
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();
if (Tab.ddt[7]) Tab.XRef();
if (Tab.GrammarOk()) {
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();
.)
'.'
.
/*------------------------------------------------------------------------------------*/
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)
if (DFA.ignoreCase) s[char.ToLower(ch)] = true;
else 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); .)
)
.
/*--------------------------------------------------------------------------------------*/
Char<out int n>
=
char (. string name = t.val; n = 0;
name = DFA.Unescape(name.Substring(1, name.Length-2));
int max = CharClass.charSetSize;
if (name.Length == 1 && name[0] <= max-1) n = name[0] % max;
else SemErr("unacceptable character value");
if (DFA.ignoreCase && (char)n >= 'A' && (char)n <= 'Z') n += 32;
.)
.
/*------------------------------------------------------------------------------------*/
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.fixedToken;
}
tokenString = null;
.)
SYNC
( '=' TokenExpr<out g> '.' (. if (kind == str) SemErr("a literal must not be declared with a structure");
Graph.Finish(g);
if (tokenString == null || tokenString.Equals(noString))
DFA.ConvertToStates(g.l, sym);
else { // TokenExpr is a single string
if (Tab.literals[tokenString] != null)
SemErr("token string declared twice");
Tab.literals[tokenString] = sym;
DFA.MatchLiteral(tokenString, sym);
}
.)
| (. if (kind == id) genScanner = false;
else DFA.MatchLiteral(sym.name, sym);
.)
)
[ SemText<out sym.semPos> (. if (typ != Node.pr) SemErr("semantic action not allowed here"); .)
]
.
/*------------------------------------------------------------------------------------*/
AttrDecl<Symbol sym>
=
'<' (. int beg = la.pos; int col = la.col; .)
{ ANY
| badString (. SemErr("bad string in attributes"); .)
}
'>' (. if (t.pos > beg)
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; Node rslv = null; g = null; .)
=
( [ (. rslv = new Node(Node.rslv, null, la.line); .)
Resolver<out rslv.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)); .)
) (. if (g == null) // invalid start of Term
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);
if (sym == null && kind == str)
sym = Tab.literals[name] as Symbol;
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.name, 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)
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);
.)
) (. if (g == null) // invalid start of Factor
g = new Graph(new Node(Node.eps, null, 0));
.)
.
/*------------------------------------------------------------------------------------*/
Resolver<out Position pos>
=
"IF" "(" (. int beg = la.pos; int col = la.col; .)
Condition (. pos = new Position(beg, t.pos - beg, col); .)
.
/*------------------------------------------------------------------------------------*/
Condition = { "(" Condition | 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 = null; .)
( 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);
tokenString = noString;
} else { // str
g = Graph.StrToGraph(name);
if (tokenString == null) tokenString = name;
else tokenString = noString;
}
.)
| '(' TokenExpr<out g> ')'
| '[' TokenExpr<out g> ']' (. Graph.MakeOption(g); .)
| '{' TokenExpr<out g> '}' (. Graph.MakeIteration(g); .)
) (. if (g == null) // invalid start of TokenFactor
g = new Graph(new Node(Node.eps, null, 0)); .)
.
/*------------------------------------------------------------------------------------*/
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;
if (DFA.ignoreCase) name = name.ToLower();
if (name.IndexOf(' ') >= 0)
SemErr("literal tokens must not contain blanks"); .)
)
.
/*------------------------------------------------------------------------------------*/
Attribs<Node p>
=
'<' (. int beg = la.pos; int col = la.col; .)
{ Attribs<p>
|ANY
| badString (. SemErr("bad string in attributes"); .)
}
'>' (. if (t.pos > beg) 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.

97
src/Tools/SharpCoco/src/Coco.cs

@ -1,97 +0,0 @@
/*-------------------------------------------------------------------------
Compiler Generator Coco/R,
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
extended by M. Loeberbauer & A. Woess, Univ. of Linz
with improvements by Pat Terry, Rhodes University
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
As an exception, it is allowed to write an extension of Coco/R that is
used as a plugin in non-free software.
If not otherwise stated, any source code generated by Coco/R (other than
Coco/R itself) does not fall under the GNU General Public License.
-------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------
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 (Jun 28, 2004)");
string ATGName = null;
for (int i = 0; i < arg.Length; i++) {
if (arg[i] == "-namespace" && i < arg.Length - 1) Tab.nsName = arg[++i];
else if (arg[i] == "-frames" && i < arg.Length - 1) Tab.frameDir = arg[++i];
else if (arg[i] == "-trace" && i < arg.Length - 1) 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(file, dir);
ParserGen.Init(file, dir);
Parser.Parse();
Trace.Close();
Console.WriteLine("{0} errors detected", Errors.count);
} else {
Console.WriteLine("Usage: Coco Grammar.ATG {{Option}}{0}" +
"Options:{0}" +
" -namespace <namespaceName>{0}" +
" -frames <frameFilesDirectory>{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}" +
" J list ANY and SYNC 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 specified in the -frames option.",
Environment.NewLine);
}
}
} // end Coco
} // end namespace

952
src/Tools/SharpCoco/src/DFA.cs

@ -1,952 +0,0 @@
/*-------------------------------------------------------------------------
DFA.cs -- Generation of the Scanner Automaton
Compiler Generator Coco/R,
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
extended by M. Loeberbauer & A. Woess, Univ. of Linz
with improvements by Pat Terry, Rhodes University
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
As an exception, it is allowed to write an extension of Coco/R that is
used as a plugin in non-free software.
If not otherwise stated, any source code generated by Coco/R (other than
Coco/R itself) does not fall under the GNU General Public License.
-------------------------------------------------------------------------*/
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 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
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 ignoreCase; // true if input should be treated case-insensitively
public static bool dirtyDFA; // DFA may become nondeterministic in MatchLiteral
public static bool hasCtxMoves; // DFA has context transitions
static string srcName; // name of the attributed grammar file
static string srcDir; // directory of attributed grammar file
//---------- 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 <= 'F') val = 16 * val + (10 + ch - 'A');
else Parser.SemErr("bad escape sequence in string or character");
}
if (val > CharClass.charSetSize) /* pdt */
Parser.SemErr("bad escape sequence in string or character");
return (char) (val % CharClass.charSetSize);
}
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) {
switch(ch) {
case '\\': buf.Append("\\\\"); break;
case '\'': buf.Append("\\'"); break;
case '\"': buf.Append("\\\""); break;
case '\t': buf.Append("\\t"); break;
case '\r': buf.Append("\\r"); break;
case '\n': buf.Append("\\n"); break;
default:
if (ch < ' ' || ch > '\u007f') buf.Append(Char2Hex(ch));
else buf.Append(ch);
break;
}
}
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);
if (typ == Node.clas) curSy.tokenKind = Symbol.classToken;
}
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));
}
// match string against current automaton; store it either as a fixedToken or as a litToken
public static void MatchLiteral(string s, Symbol sym) {
s = Unescape(s.Substring(1, s.Length-2));
int i, len = s.Length;
State state = firstState;
Action a = null;
for (i = 0; i < len; i++) { // try to match s against existing DFA
a = state.TheAction(s[i]);
if (a == null) break;
state = a.target.state;
}
// if s was not totally consumed or leads to a non-final state => make new DFA from it
if (i != len || state.endOf == null) {
state = firstState; i = 0; a = null;
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;
} else if (matchedSym.tokenKind == Symbol.fixedToken || (a != null && a.tc == Node.contextTrans)) {
// s matched a token with a fixed definition or a token with an appendix that will be cut off
Parser.SemErr("tokens " + sym.name + " and " + matchedSym.name + " cannot be distinguished");
} else { // matchedSym == classToken || classLitToken
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();
Trace.WriteLine("---------- 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();
Trace.WriteLine("---------- 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 == Buffer.EOF) return false;");
gen.WriteLine( "\t\t\t\telse NextCh();");
gen.WriteLine( "\t\t\t}");
}
static void GenComment(Comment com, int i) {
gen.WriteLine();
gen.Write ("\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 string SymName(Symbol sym) {
if (Char.IsLetter(sym.name[0])) { // real name value is stored in Tab.literals
foreach (DictionaryEntry e in Tab.literals)
if ((Symbol)e.Value == sym) return (string)e.Key;
}
return sym.name;
}
static void GenLiterals () {
if (ignoreCase) {
gen.WriteLine("\t\tswitch (t.val.ToLower()) {");
} else {
gen.WriteLine("\t\tswitch (t.val) {");
}
foreach (Symbol sym in Symbol.terminals) {
if (sym.tokenKind == Symbol.litToken) {
string name = SymName(sym);
if (ignoreCase) name = name.ToLower();
// sym.name stores literals with quotes, e.g. "\"Literal\""
gen.WriteLine("\t\t\tcase {0}: t.kind = {1}; break;", name, sym.n);
}
}
gen.WriteLine("\t\t\tdefault: break;");
gen.Write("\t\t}");
}
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; ");
if (ignoreCase) gen.Write("buf.Append(valCh); "); else gen.Write("buf.Append(ch); ");
gen.Write("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) {
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;
}
}
}
static void OpenGen(bool backUp) { /* pdt */
try {
string fn = srcDir + "Scanner.cs"; /* pdt */
if (File.Exists(fn) && backUp) File.Copy(fn, fn + ".old", true);
gen = new StreamWriter(new FileStream(fn, FileMode.Create)); /* pdt */
} catch (IOException) {
Errors.Exception("-- Cannot generate scanner file");
}
}
public static void WriteScanner() {
int i, j;
int[] startTab = new int[CharClass.charSetSize];
string fr = srcDir + "Scanner.frame"; /* pdt */
if (!File.Exists(fr)) {
if (Tab.frameDir != null) fr = Tab.frameDir.Trim() + Path.DirectorySeparatorChar + "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.");
}
OpenGen(true); /* pdt */
if (dirtyDFA) MakeDeterministic();
FillStartTab(startTab);
CopyFramePart("-->begin");
if (!srcName.ToLower().EndsWith("coco.atg")) {
gen.Close(); OpenGen(false); /* pdt */
}
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("-->declarations");
gen.WriteLine("\tconst int charSetSize = {0};", CharClass.charSetSize);
gen.WriteLine("\tconst int maxT = {0};", Symbol.terminals.Count - 1);
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 -1};"); /* pdt */
if (ignoreCase)
gen.Write("\tstatic char valCh; // current input character (for token.val)");
CopyFramePart("-->initialization");
gen.WriteLine("\t\tignore = new BitArray(charSetSize+1);"); /* pdt */
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("-->casing");
if (ignoreCase) {
gen.WriteLine("\t\tvalCh = ch;");
gen.Write ("\t\tif (ch != Buffer.EOF) ch = char.ToLower(ch);");
}
CopyFramePart("-->comments");
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(); gen.Write("\t\tint apx = 0;"); } /* pdt */
CopyFramePart("-->scan2");
if (ignoreCase) gen.Write("\t\tbuf.Append(valCh); NextCh();");
else gen.Write("\t\tbuf.Append(ch); NextCh();");
CopyFramePart("-->scan3");
for (State state = firstState.next; state != null; state = state.next)
WriteState(state);
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 file, string dir) {
srcName = file;
srcDir = dir;
firstState = null; lastState = null; State.lastNr = -1;
firstState = NewState();
Melted.first = null; Comment.first = null;
ignoreCase = false;
dirtyDFA = false;
hasCtxMoves = false;
}
} // end DFA
} // end namespace

785
src/Tools/SharpCoco/src/Parser.cs

@ -1,785 +0,0 @@
/*----------------------------------------------------------------------
Compiler Generator Coco/R,
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
extended by M. Loeberbauer & A. Woess, Univ. of Linz
with improvements by Pat Terry, Rhodes University
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
As an exception, it is allowed to write an extension of Coco/R that is
used as a plugin in non-free software.
If not otherwise stated, any source code generated by Coco/R (other than
Coco/R itself) does not fall under the GNU General Public License.
----------------------------------------------------------------------*/
using System.Collections;
using System;
namespace at.jku.ssw.Coco {
public class Parser {
const int _EOF = 0;
const int _ident = 1;
const int _number = 2;
const int _string = 3;
const int _badString = 4;
const int _char = 5;
const int maxT = 41;
const bool T = true;
const bool x = false;
const int minErrDist = 2;
public static Token t; // last recognized token
public static Token la; // lookahead token
static int errDist = minErrDist;
const int id = 0;
const int str = 1;
static bool genScanner;
static string tokenString; // used in declarations of literal tokens
static string noString = "-none-"; // used in declarations of literal tokens
/*-------------------------------------------------------------------------*/
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; }
if (la.kind == 42) {
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, g1, g2; string gramName;
if (la.kind == 39) {
UsingDecl(out ParserGen.usingPos);
}
Expect(6);
genScanner = 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);
if (la.kind == 7) {
Get();
DFA.ignoreCase = true;
}
if (la.kind == 8) {
Get();
while (la.kind == 1) {
SetDecl();
}
}
if (la.kind == 9) {
Get();
while (la.kind == 1 || la.kind == 3 || la.kind == 5) {
TokenDecl(Node.t);
}
}
if (la.kind == 10) {
Get();
while (la.kind == 1 || la.kind == 3 || la.kind == 5) {
TokenDecl(Node.pr);
}
}
while (la.kind == 11) {
Get();
bool nested = false;
Expect(12);
TokenExpr(out g1);
Expect(13);
TokenExpr(out g2);
if (la.kind == 14) {
Get();
nested = true;
}
new Comment(g1.l, g2.l, nested);
}
while (la.kind == 15) {
Get();
Set(out Tab.ignored);
Tab.ignored[' '] = true; /* ' ' is always ignored */
}
while (!(la.kind == 0 || la.kind == 16)) {SynErr(42); Get();}
Expect(16);
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 == 37) {
SemText(out sym.semPos);
}
ExpectWeak(17, 2);
Expression(out g);
sym.graph = g.l;
Graph.Finish(g);
ExpectWeak(18, 3);
}
Expect(19);
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();
if (Tab.ddt[7]) Tab.XRef();
if (Tab.GrammarOk()) {
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(18);
}
static void UsingDecl(out Position pos) {
Expect(39);
int beg = t.pos;
while (StartOf(4)) {
Get();
}
Expect(40);
int end = t.pos;
while (la.kind == 39) {
Get();
while (StartOf(4)) {
Get();
}
Expect(40);
end = t.pos;
}
pos = new Position(beg, end - beg + 1, 0);
}
static void SetDecl() {
BitArray s;
Expect(1);
string name = t.val;
CharClass c = CharClass.Find(name);
if (c != null) SemErr("name declared twice");
Expect(17);
Set(out s);
if (Sets.Elements(s) == 0) SemErr("character set must not be empty");
c = new CharClass(name, s);
Expect(18);
}
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.fixedToken;
}
tokenString = null;
while (!(StartOf(5))) {SynErr(43); Get();}
if (la.kind == 17) {
Get();
TokenExpr(out g);
Expect(18);
if (kind == str) SemErr("a literal must not be declared with a structure");
Graph.Finish(g);
if (tokenString == null || tokenString.Equals(noString))
DFA.ConvertToStates(g.l, sym);
else { // TokenExpr is a single string
if (Tab.literals[tokenString] != null)
SemErr("token string declared twice");
Tab.literals[tokenString] = sym;
DFA.MatchLiteral(tokenString, sym);
}
} else if (StartOf(6)) {
if (kind == id) genScanner = false;
else DFA.MatchLiteral(sym.name, sym);
} else SynErr(44);
if (la.kind == 37) {
SemText(out sym.semPos);
if (typ != Node.pr) SemErr("semantic action not allowed here");
}
}
static void TokenExpr(out Graph g) {
Graph g2;
TokenTerm(out g);
bool first = true;
while (WeakSeparator(26,7,8) ) {
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 AttrDecl(Symbol sym) {
Expect(24);
int beg = la.pos; int col = la.col;
while (StartOf(9)) {
// CHANGES BY M.KRUEGER
if (la.kind == 24) {
AttrDecl(sym);
} else
// EOC
if (StartOf(10)) {
Get();
} else {
Get();
SemErr("bad string in attributes");
}
}
Expect(25);
if (t.pos > beg)
sym.attrPos = new Position(beg, t.pos - beg, col);
}
static void SemText(out Position pos) {
Expect(37);
int beg = la.pos; int col = la.col;
while (StartOf(11)) {
if (StartOf(12)) {
Get();
} else if (la.kind == 4) {
Get();
SemErr("bad string in semantic action");
} else {
Get();
SemErr("missing end of previous semantic action");
}
}
Expect(38);
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,13,14) ) {
Term(out g2);
if (first) { Graph.MakeFirstAlt(g); first = false; }
Graph.MakeAlternative(g, g2);
}
}
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)
if (DFA.ignoreCase) s[char.ToLower(ch)] = true;
else 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);
} else SynErr(45);
}
static void Char(out int n) {
Expect(5);
string name = t.val; n = 0;
name = DFA.Unescape(name.Substring(1, name.Length-2));
int max = CharClass.charSetSize;
if (name.Length == 1 && name[0] <= max-1) n = name[0] % max;
else SemErr("unacceptable character value");
if (DFA.ignoreCase && (char)n >= 'A' && (char)n <= 'Z') n += 32;
}
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;
if (DFA.ignoreCase) name = name.ToLower();
if (name.IndexOf(' ') >= 0)
SemErr("literal tokens must not contain blanks");
} else SynErr(46);
}
static void Term(out Graph g) {
Graph g2; Node rslv = null; g = null;
if (StartOf(15)) {
if (la.kind == 35) {
rslv = new Node(Node.rslv, null, la.line);
Resolver(out rslv.pos);
g = new Graph(rslv);
}
Factor(out g2);
if (rslv != null) Graph.MakeSequence(g, g2);
else g = g2;
while (StartOf(16)) {
Factor(out g2);
Graph.MakeSequence(g, g2);
}
} else if (StartOf(17)) {
g = new Graph(new Node(Node.eps, null, 0));
} else SynErr(47);
if (g == null) // invalid start of Term
g = new Graph(new Node(Node.eps, null, 0));
}
static void Resolver(out Position pos) {
Expect(35);
Expect(28);
int beg = la.pos; int col = la.col;
Condition();
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);
if (sym == null && kind == str)
sym = Tab.literals[name] as Symbol;
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.name, 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)
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 37: {
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(48); break;
}
if (g == null) // invalid start of Factor
g = new Graph(new Node(Node.eps, null, 0));
}
static void Attribs(Node p) {
Expect(24);
int beg = la.pos; int col = la.col;
while (StartOf(9)) {
// CHANGES BY M.KRUEGER
if (la.kind == 24) {
Attribs(p);
} else
// EOC
if (StartOf(10)) {
Get();
} else {
Get();
SemErr("bad string in attributes");
}
}
Expect(25);
if (t.pos > beg) p.pos = new Position(beg, t.pos - beg, col);
}
static void Condition() {
while (StartOf(18)) {
if (la.kind == 28) {
Get();
Condition();
} else {
Get();
}
}
Expect(29);
}
static void TokenTerm(out Graph g) {
Graph g2;
TokenFactor(out g);
while (StartOf(7)) {
TokenFactor(out g2);
Graph.MakeSequence(g, g2);
}
if (la.kind == 36) {
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 = null;
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);
tokenString = noString;
} else { // str
g = Graph.StrToGraph(name);
if (tokenString == null) tokenString = name;
else tokenString = noString;
}
} 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(49);
if (g == null) // invalid start of TokenFactor
g = new Graph(new Node(Node.eps, null, 0));
}
public static void Parse() {
la = new Token();
la.val = "";
Get();
Coco();
Expect(0);
}
static bool[,] set = {
{T,T,x,T, x,T,x,x, x,x,T,T, x,x,x,T, T,T,x,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, 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, T,T,x},
{T,T,x,T, x,T,x,x, x,x,T,T, x,x,x,T, T,T,T,x, x,x,x,T, x,x,T,T, T,x,T,x, T,x,T,T, x,T,x,x, x,x,x},
{T,T,x,T, x,T,x,x, x,x,T,T, x,x,x,T, T,T,x,T, 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, x,T,x},
{T,T,x,T, x,T,x,x, x,x,T,T, x,x,x,T, T,T,x,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,x, x,x,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,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,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,T, x,T,T,T, T,x,T,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,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,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,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,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,x,x,T, T,T,x},
{x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,T, x,x,T,T, T,T,T,T, T,T,T,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,x,T,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,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,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,T,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, x,x,x,x, x,x,T,x, x,T,x,T, x,T,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,T,T,T, T,x,T,T, T,T,T,T, T,T,T,T, T,T,x}
};
} // end Parser
public class Errors {
public static int count = 0; // number of errors detected
public static string errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text
public static void SynErr (int line, int col, int n) {
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 = "\"IGNORECASE\" expected"; break;
case 8: s = "\"CHARACTERS\" expected"; break;
case 9: s = "\"TOKENS\" expected"; break;
case 10: s = "\"PRAGMAS\" expected"; break;
case 11: s = "\"COMMENTS\" expected"; break;
case 12: s = "\"FROM\" expected"; break;
case 13: s = "\"TO\" expected"; break;
case 14: s = "\"NESTED\" expected"; break;
case 15: s = "\"IGNORE\" expected"; break;
case 16: s = "\"PRODUCTIONS\" expected"; break;
case 17: s = "\"=\" expected"; break;
case 18: s = "\".\" expected"; break;
case 19: s = "\"END\" 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 = "\"CONTEXT\" expected"; break;
case 37: s = "\"(.\" expected"; break;
case 38: s = "\".)\" expected"; break;
case 39: s = "\"using\" expected"; break;
case 40: s = "\";\" expected"; break;
case 41: s = "??? expected"; break;
case 42: s = "this symbol not expected in Coco"; break;
case 43: s = "this symbol not expected in TokenDecl"; break;
case 44: s = "invalid TokenDecl"; break;
case 45: s = "invalid SimSet"; break;
case 46: s = "invalid Sym"; break;
case 47: s = "invalid Term"; break;
case 48: s = "invalid Factor"; break;
case 49: s = "invalid TokenFactor"; break;
default: s = "error " + n; break;
}
Console.WriteLine(Errors.errMsgFormat, line, col, s);
count++;
}
public static void SemErr (int line, int col, int n) {
Console.WriteLine(errMsgFormat, line, col, ("error " + n));
count++;
}
public static void Error (int line, int col, string s) {
Console.WriteLine(errMsgFormat, line, col, s);
count++;
}
public static void Exception (string s) {
Console.WriteLine(s);
System.Environment.Exit(1);
}
} // Errors
}

140
src/Tools/SharpCoco/src/Parser.frame

@ -1,140 +0,0 @@
/*----------------------------------------------------------------------
Compiler Generator Coco/R,
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
extended by M. Loeberbauer & A. Woess, Univ. of Linz
with improvements by Pat Terry, Rhodes University
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
As an exception, it is allowed to write an extension of Coco/R that is
used as a plugin in non-free software.
If not otherwise stated, any source code generated by Coco/R (other than
Coco/R itself) does not fall under the GNU General Public License.
----------------------------------------------------------------------*/
-->begin
using System;
-->namespace
public class Parser {
-->constants
const bool T = true;
const bool x = false;
const int minErrDist = 2;
public static Token t; // last recognized token
public static Token la; // lookahead token
static int errDist = minErrDist;
-->declarations
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; }
-->pragmas
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);
}
}
-->productions
public static void Parse() {
la = new Token();
la.val = "";
Get();
-->parseRoot
Expect(0);
}
static bool[,] set = {
-->initialization
};
} // end Parser
public class Errors {
public static int count = 0; // number of errors detected
public static string errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text
public static void SynErr (int line, int col, int n) {
string s;
switch (n) {
-->errors
default: s = "error " + n; break;
}
Console.WriteLine(Errors.errMsgFormat, line, col, s);
count++;
}
public static void SemErr (int line, int col, int n) {
Console.WriteLine(errMsgFormat, line, col, ("error " + n));
count++;
}
public static void Error (int line, int col, string s) {
Console.WriteLine(errMsgFormat, line, col, s);
count++;
}
public static void Exception (string s) {
Console.WriteLine(s);
System.Environment.Exit(1);
}
} // Errors
$$$

432
src/Tools/SharpCoco/src/ParserGen.cs

@ -1,432 +0,0 @@
/*-------------------------------------------------------------------------
ParserGen.cs -- Generation of the Recursive Descent Parser
Compiler Generator Coco/R,
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
extended by M. Loeberbauer & A. Woess, Univ. of Linz
with improvements by Pat Terry, Rhodes University
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
As an exception, it is allowed to write an extension of Coco/R that is
used as a plugin in non-free software.
If not otherwise stated, any source code generated by Coco/R (other than
Coco/R itself) does not fall under the GNU General Public License.
-------------------------------------------------------------------------*/
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 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
// CHANGES BY M.KRUEGER
public static string productionModifiers = String.Empty;
//EOC
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: use a switch if more than 5 alternatives and none starts with a resolver
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, Scanner.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 == ' ' || ch == '\t'); 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 {
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));
/*
if (p.typ == Node.alt) {
// for { ... | IF ... | ... } or [ ... | IF ... | ... ]
// check resolvers in addition to terminal start symbols of alternatives
Node q = p;
while (q != null) {
if (q.sub.typ == Node.rslv) {
gen.Write(" || ");
CopySourcePart(q.sub.pos, 0);
}
q = q.down;
}
}
*/
}
}
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);
// CHANGES BY M.KRUEGER
//if (isChecked[p.sym.n]) gen.WriteLine("Get();");
if (isChecked[p.sym.n]) gen.WriteLine("lexer.NextToken();");
//EOC
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);
// CHANGES BY M.KRUEGER
//gen.WriteLine("Get();");
gen.WriteLine("lexer.NextToken();");
//EOC
break;
}
case Node.eps: break; // nothing
case Node.rslv: 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, p); gen.Write(")) {");
// CHANGES BY M.KRUEGER
//gen.Write("SynErr({0}); Get();", errorNr);
gen.Write("SynErr({0}); lexer.NextToken(); ", errorNr);
//EOC
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);
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.next, indent + 1, s1);
//else GenCode(p2.sub, indent + 1, s1);
GenCode(p2.sub, 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.next);
//else s1 = Tab.First(p.sub);
s1 = Tab.First(p.sub);
Indent(indent);
gen.Write("if ("); GenCond(s1, p.sub); gen.WriteLine(") {");
//if (p.sub.typ == Node.rslv) GenCode(p.sub.next, indent + 1, s1);
//else GenCode(p.sub, indent + 1, s1);
GenCode(p.sub, indent + 1, s1);
Indent(indent); gen.WriteLine("}");
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;
}
}
static void GenTokens() {
foreach (Symbol sym in Symbol.terminals) {
if (Char.IsLetter(sym.name[0]))
gen.WriteLine("\tconst int _{0} = {1};", sym.name, sym.n);
}
}
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;
// CHANGES BY M.KRUEGER
gen.Write("\t" + productionModifiers + " void {0}(", sym.name);
// OLD VERSION: gen.Write("\tstatic void {0}(", sym.name);
//EOC
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\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},");
}
}
static void OpenGen(bool backUp) { /* pdt */
try {
string fn = srcDir + "Parser.cs"; /* pdt */
if (File.Exists(fn) && backUp) File.Copy(fn, fn + ".old", true);
gen = new StreamWriter(new FileStream(fn, FileMode.Create)); /* pdt */
} catch (IOException) {
Errors.Exception("-- Cannot generate parser file");
}
}
public static void WriteParser () {
symSet.Add(Tab.allSyncSets);
string fr = srcDir + "Parser.frame";
if (!File.Exists(fr)) {
if (Tab.frameDir != null) fr = Tab.frameDir.Trim() + Path.DirectorySeparatorChar + "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.");
}
OpenGen(true); /* pdt */
err = new StringWriter();
foreach (Symbol sym in Symbol.terminals) GenErrorMsg(tErr, sym);
CopyFramePart("-->begin");
if (!srcName.ToLower().EndsWith("coco.atg")) {
gen.Close(); OpenGen(false); /* pdt */
}
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.WriteLine("namespace {0} {{", Tab.nsName);
gen.WriteLine();
}
CopyFramePart("-->constants");
GenTokens(); /* ML 2002/09/07 write the token kinds */
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("-->initialization"); InitSets();
CopyFramePart("-->errors"); gen.Write(err.ToString());
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

358
src/Tools/SharpCoco/src/Scanner.cs

@ -1,358 +0,0 @@
/*----------------------------------------------------------------------
Compiler Generator Coco/R,
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
extended by M. Loeberbauer & A. Woess, Univ. of Linz
with improvements by Pat Terry, Rhodes University
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
As an exception, it is allowed to write an extension of Coco/R that is
used as a plugin in non-free software.
If not otherwise stated, any source code generated by Coco/R (other than
Coco/R itself) does not fall under the GNU General Public License.
-----------------------------------------------------------------------*/
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 class Buffer {
public const char EOF = (char)256;
static byte[] buf;
static int bufLen;
static int pos;
// CHANGES by M.KRUEGER
public static int CountLines(int offset)
{
int line = 0;
for (int i = 0; i <= offset; ++i) {
if (buf[i] == '\n') {
++line;
}
}
return line;
}
//EOC
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 EOF; /* pdt */
}
public static int Peek () {
if (pos < bufLen) return buf[pos];
else return EOF; /* pdt */
}
/* 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 EOL = '\n';
const int eofSym = 0; /* pdt */
const int charSetSize = 256;
const int maxT = 41;
const int noSym = 41;
static short[] start = {
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, 11, 0, 10, 0, 0, 5, 29, 20, 0, 14, 0, 15, 28, 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 27, 17, 13, 18, 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, 21, 0, 22, 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, 23, 19, 24, 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,
-1};
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
static Token tokens; // the complete input token stream
static Token pt; // current peek token
// CHANGES by M.KRUEGER
public static string fileName;
// EOC
public static void Init (string fileName) {
// CHANGES by M.KRUEGER
Scanner.fileName = fileName;
// EOC
FileStream s = null;
try {
s = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
Init(s);
} catch (IOException) {
Console.WriteLine("--- Cannot open file {0}", fileName);
System.Environment.Exit(1);
} finally {
if (s != null) s.Close();
}
}
public static void Init (Stream s) {
Buffer.Fill(s);
pos = -1; line = 1; lineStart = 0;
oldEols = 0;
NextCh();
ignore = new BitArray(charSetSize+1);
ignore[9] = true; ignore[10] = true; ignore[13] = true; ignore[32] = true;
//--- AW: fill token list
tokens = new Token(); // first token is a dummy
Token node = tokens;
do {
node.next = NextToken();
node = node.next;
} while (node.kind != eofSym);
node.next = node;
node.val = "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;
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 == Buffer.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 "IGNORECASE": t.kind = 7; break;
case "CHARACTERS": t.kind = 8; break;
case "TOKENS": t.kind = 9; break;
case "PRAGMAS": t.kind = 10; break;
case "COMMENTS": t.kind = 11; break;
case "FROM": t.kind = 12; break;
case "TO": t.kind = 13; break;
case "NESTED": t.kind = 14; break;
case "IGNORE": t.kind = 15; break;
case "PRODUCTIONS": t.kind = 16; break;
case "END": 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 = 36; break;
case "using": t.kind = 39; 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 -1: { t.kind = eofSym; goto done; } // NextCh already done /* pdt */
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 <= 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 = 42; goto done;}
case 11:
if ((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 = 17; goto done;}
case 14:
{t.kind = 20; goto done;}
case 15:
{t.kind = 21; goto done;}
case 16:
{t.kind = 22; goto done;}
case 17:
{t.kind = 24; goto done;}
case 18:
{t.kind = 25; goto done;}
case 19:
{t.kind = 26; goto done;}
case 20:
{t.kind = 29; goto done;}
case 21:
{t.kind = 30; goto done;}
case 22:
{t.kind = 31; goto done;}
case 23:
{t.kind = 32; goto done;}
case 24:
{t.kind = 33; goto done;}
case 25:
{t.kind = 37; goto done;}
case 26:
{t.kind = 38; goto done;}
case 27:
{t.kind = 40; goto done;}
case 28:
if (ch == '.') {buf.Append(ch); NextCh(); goto case 16;}
else if (ch == ')') {buf.Append(ch); NextCh(); goto case 26;}
else {t.kind = 18; goto done;}
case 29:
if (ch == '.') {buf.Append(ch); NextCh(); goto case 25;}
else {t.kind = 28; 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.kind > maxT);
return pt;
}
/* AW 2003-03-11 to make sure peek start at current scan position */
public static void ResetPeek () { pt = t; }
} // end Scanner
}

202
src/Tools/SharpCoco/src/Scanner.frame

@ -1,202 +0,0 @@
/*----------------------------------------------------------------------
Compiler Generator Coco/R,
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
extended by M. Loeberbauer & A. Woess, Univ. of Linz
with improvements by Pat Terry, Rhodes University
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
As an exception, it is allowed to write an extension of Coco/R that is
used as a plugin in non-free software.
If not otherwise stated, any source code generated by Coco/R (other than
Coco/R itself) does not fall under the GNU General Public License.
-----------------------------------------------------------------------*/
-->begin
using System;
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 class Buffer {
public const char EOF = (char)256;
static byte[] buf;
static int bufLen;
static int pos;
// CHANGES by M.KRUEGER
public static int CountLines(int offset)
{
int line = 0;
for (int i = 0; i <= offset; ++i) {
if (buf[i] == '\n') {
++line;
}
}
return line;
}
//EOC
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 EOF; /* pdt */
}
public static int Peek () {
if (pos < bufLen) return buf[pos];
else return EOF; /* pdt */
}
/* 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 EOL = '\n';
const int eofSym = 0; /* pdt */
-->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
static Token tokens; // the complete input token stream
static Token pt; // current peek token
public static void Init (string fileName) {
FileStream s = null;
try {
s = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
Init(s);
} catch (IOException) {
Console.WriteLine("--- Cannot open file {0}", fileName);
System.Environment.Exit(1);
} finally {
if (s != null) s.Close();
}
}
public static void Init (Stream s) {
Buffer.Fill(s);
pos = -1; line = 1; lineStart = 0;
oldEols = 0;
NextCh();
-->initialization
//--- AW: fill token list
tokens = new Token(); // first token is a dummy
Token node = tokens;
do {
node.next = NextToken();
node = node.next;
} while (node.kind != eofSym);
node.next = node;
node.val = "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;
if (ch == EOL) { line++; lineStart = pos + 1; }
}
-->casing
}
-->comments
static void CheckLiteral() {
-->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);
-->scan2
switch (state) {
case -1: { t.kind = eofSym; goto done; } // NextCh already done /* pdt */
case 0: { t.kind = noSym; goto done; } // NextCh already done
-->scan3
}
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.kind > maxT);
return pt;
}
/* AW 2003-03-11 to make sure peek start at current scan position */
public static void ResetPeek () { pt = t; }
} // end Scanner
$$$

53
src/Tools/SharpCoco/src/SharpCoco.csproj

@ -1,53 +0,0 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.40607</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{b87ee2f4-80bd-476a-8d49-a0bb415b6021}</ProjectGuid>
<RootNamespace>NewProject</RootNamespace>
<AssemblyName>SharpCoco</AssemblyName>
<OutputTarget>Exe</OutputTarget>
<WarningLevel>4</WarningLevel>
<NoStdLib>False</NoStdLib>
<NoConfig>False</NoConfig>
<RunPostBuildEvent>OnSuccessfulBuild</RunPostBuildEvent>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>True</DebugSymbols>
<Optimize>True</Optimize>
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<OutputPath>..\bin\Debug\</OutputPath>
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugSymbols>True</DebugSymbols>
<Optimize>True</Optimize>
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<OutputPath>..\bin\Release\</OutputPath>
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Coco.cs" />
<Compile Include="AssemblyInfo.cs" />
<Compile Include="DFA.cs" />
<Compile Include="Parser.cs" />
<Compile Include="Scanner.cs" />
<Compile Include="Tab.cs" />
<Compile Include="Trace.cs" />
<Compile Include="ParserGen.cs" />
<None Include="Parser.frame" />
<None Include="Scanner.frame" />
<None Include="Coco.atg" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
</Project>

6
src/Tools/SharpCoco/src/SharpCoco.csproj.user

@ -1,6 +0,0 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<StartArguments>CS.ATG</StartArguments>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
</Project>

1082
src/Tools/SharpCoco/src/Tab.cs

File diff suppressed because it is too large Load Diff

69
src/Tools/SharpCoco/src/Trace.cs

@ -1,69 +0,0 @@
/*-------------------------------------------------------------------------
Trace.cs -- Trace Output Class
Compiler Generator Coco/R,
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
extended by M. Loeberbauer & A. Woess, Univ. of Linz
with improvements by Pat Terry, Rhodes University
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
As an exception, it is allowed to write an extension of Coco/R that is
used as a plugin in non-free software.
If not otherwise stated, any source code generated by Coco/R (other than
Coco/R itself) does not fall under the GNU General Public License.
-------------------------------------------------------------------------*/
using System;
using System.IO;
namespace at.jku.ssw.Coco {
class Trace {
static string fileName; /* pdt */
static StreamWriter trace;
public static void Init (String dir) {
fileName = dir + "trace.txt"; /* pdt */
try {
trace = new StreamWriter(new FileStream(fileName, FileMode.Create));
} catch (IOException) {
Errors.Exception("-- could not open " + fileName);
}
}
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 () { /* pdt */
trace.Close();
FileInfo f = new FileInfo(fileName);
if (f.Length == 0) f.Delete();
else Console.WriteLine("trace output is in " + fileName);
}
}
}
Loading…
Cancel
Save