15 changed files with 0 additions and 4847 deletions
@ -1,16 +0,0 @@ |
|||||||
Microsoft Visual Studio Solution File, Format Version 9.00 |
|
||||||
# SharpDevelop 2.1.0.1913 |
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpCoco", "src\SharpCoco.csproj", "{47D8A4A2-BBD9-4E24-85DC-A287383F7C42}" |
|
||||||
EndProject |
|
||||||
Global |
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
|
||||||
Debug|Any CPU = Debug|Any CPU |
|
||||||
Release|Any CPU = Release|Any CPU |
|
||||||
EndGlobalSection |
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
|
||||||
{47D8A4A2-BBD9-4E24-85DC-A287383F7C42}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||||
{47D8A4A2-BBD9-4E24-85DC-A287383F7C42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||||
{47D8A4A2-BBD9-4E24-85DC-A287383F7C42}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||||
{47D8A4A2-BBD9-4E24-85DC-A287383F7C42}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||||
EndGlobalSection |
|
||||||
EndGlobal |
|
@ -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 |
|
@ -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("1.0.*")] |
|
||||||
|
|
||||||
// The following attributes specify the key for the sign of your assembly. See the
|
|
||||||
// .NET Framework documentation for more information about signing.
|
|
||||||
// This is not required, if you don't want signing let these attributes like they're.
|
|
||||||
[assembly: AssemblyDelaySign(false)] |
|
||||||
[assembly: AssemblyKeyFile("")] |
|
@ -1,432 +0,0 @@ |
|||||||
/* ------------------------------------------------------------------------ |
|
||||||
* Coco.ATG |
|
||||||
* Attributed grammer of Coco/R |
|
||||||
* by H. Moessenboeck, Univ. of Linz |
|
||||||
* extended by |
|
||||||
* M. Loeberbauer & A. Woess, Univ. of Linz |
|
||||||
* ------------------------------------------------------------------------*/ |
|
||||||
|
|
||||||
using System.Collections; |
|
||||||
using System.Text; |
|
||||||
|
|
||||||
COMPILER Coco |
|
||||||
|
|
||||||
const int id = 0; |
|
||||||
const int str = 1; |
|
||||||
|
|
||||||
static bool genScanner; |
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/ |
|
||||||
|
|
||||||
CHARACTERS |
|
||||||
letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz". |
|
||||||
digit = "0123456789". |
|
||||||
cr = '\r'. |
|
||||||
lf = '\n'. |
|
||||||
tab = '\t'. |
|
||||||
stringCh = ANY - '"' - '\\' - cr - lf. |
|
||||||
charCh = ANY - '\'' - '\\' - cr - lf. |
|
||||||
printable = '\u0020' .. '\u007e'. |
|
||||||
hex = "0123456789abcdef". |
|
||||||
|
|
||||||
IGNORE cr + lf + tab |
|
||||||
|
|
||||||
TOKENS |
|
||||||
ident = letter { letter | digit }. |
|
||||||
number = digit { digit }. |
|
||||||
string = '"' { stringCh | '\\' printable } '"'. |
|
||||||
badString = '"' { stringCh | '\\' printable } (cr | lf). |
|
||||||
char = '\'' ( charCh | '\\' printable { hex } ) '\''. |
|
||||||
|
|
||||||
PRAGMAS |
|
||||||
ddtSym = '$' { digit | letter }. (. Tab.SetDDT(la.val); .) |
|
||||||
|
|
||||||
COMMENTS FROM "/*" TO "*/" NESTED |
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/ |
|
||||||
|
|
||||||
PRODUCTIONS |
|
||||||
|
|
||||||
Coco (. Symbol sym; Graph g; string gramName; .) |
|
||||||
= |
|
||||||
[ UsingDecl<out ParserGen.usingPos> ] |
|
||||||
|
|
||||||
"COMPILER" (. int gramLine = t.line; |
|
||||||
genScanner = true; |
|
||||||
bool ok = true; |
|
||||||
Tab.ignored = null; |
|
||||||
.) |
|
||||||
ident (. gramName = t.val; |
|
||||||
int beg = la.pos; |
|
||||||
.) |
|
||||||
{ ANY } (. Tab.semDeclPos = new Position(beg, la.pos-beg, 0); .) |
|
||||||
{ Declaration } |
|
||||||
SYNC |
|
||||||
"PRODUCTIONS" (. if (genScanner) DFA.MakeDeterministic(); |
|
||||||
Graph.DeleteNodes(); |
|
||||||
.) |
|
||||||
{ ident (. sym = Symbol.Find(t.val); |
|
||||||
bool undef = sym == null; |
|
||||||
if (undef) sym = new Symbol(Node.nt, t.val, t.line); |
|
||||||
else { |
|
||||||
if (sym.typ == Node.nt) { |
|
||||||
if (sym.graph != null) SemErr("name declared twice"); |
|
||||||
} else SemErr("this symbol kind not allowed on left side of production"); |
|
||||||
sym.line = t.line; |
|
||||||
} |
|
||||||
bool noAttrs = sym.attrPos == null; |
|
||||||
sym.attrPos = null; |
|
||||||
.) |
|
||||||
[ AttrDecl<sym> ] (. if (!undef) |
|
||||||
if (noAttrs != (sym.attrPos == null)) |
|
||||||
SemErr("attribute mismatch between declaration and use of this symbol"); |
|
||||||
.) |
|
||||||
[ SemText<out sym.semPos> ] WEAK |
|
||||||
'=' |
|
||||||
Expression<out g> (. sym.graph = g.l; |
|
||||||
Graph.Finish(g); |
|
||||||
.) |
|
||||||
WEAK |
|
||||||
'.' |
|
||||||
} |
|
||||||
"END" ident (. if (gramName != t.val) |
|
||||||
SemErr("name does not match grammar name"); |
|
||||||
Tab.gramSy = Symbol.Find(gramName); |
|
||||||
if (Tab.gramSy == null) |
|
||||||
SemErr("missing production for grammar name"); |
|
||||||
else { |
|
||||||
sym = Tab.gramSy; |
|
||||||
if (sym.attrPos != null) |
|
||||||
SemErr("grammar symbol must not have attributes"); |
|
||||||
} |
|
||||||
Tab.noSym = new Symbol(Node.t, "???", 0); // noSym gets highest number |
|
||||||
Tab.SetupAnys(); |
|
||||||
Tab.RenumberPragmas(); |
|
||||||
if (Tab.ddt[2]) Node.PrintNodes(); |
|
||||||
if (Errors.count == 0) { |
|
||||||
Console.WriteLine("checking"); |
|
||||||
Tab.CompSymbolSets(); |
|
||||||
ok = ok && Tab.GrammarOk(); |
|
||||||
if (Tab.ddt[7]) Tab.XRef(); |
|
||||||
if (ok) { |
|
||||||
Console.Write("parser"); |
|
||||||
ParserGen.WriteParser(); |
|
||||||
if (genScanner) { |
|
||||||
Console.Write(" + scanner"); |
|
||||||
DFA.WriteScanner(); |
|
||||||
if (Tab.ddt[0]) DFA.PrintStates(); |
|
||||||
} |
|
||||||
Console.WriteLine(" generated"); |
|
||||||
if (Tab.ddt[8]) ParserGen.WriteStatistics(); |
|
||||||
} |
|
||||||
} |
|
||||||
if (Tab.ddt[6]) Tab.PrintSymbolTable(); |
|
||||||
.) |
|
||||||
'.' |
|
||||||
. |
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------------*/ |
|
||||||
|
|
||||||
Declaration (. Graph g1, g2; bool nested = false; .) |
|
||||||
= |
|
||||||
"CHARACTERS" { SetDecl } |
|
||||||
| "TOKENS" { TokenDecl<Node.t> } |
|
||||||
| "PRAGMAS" { TokenDecl<Node.pr> } |
|
||||||
| "COMMENTS" |
|
||||||
"FROM" TokenExpr<out g1> |
|
||||||
"TO" TokenExpr<out g2> |
|
||||||
( "NESTED" (. nested = true; .) |
|
||||||
| (. nested = false; .) |
|
||||||
) (. new Comment(g1.l, g2.l, nested); .) |
|
||||||
| "IGNORE" Set<out Tab.ignored> (. Tab.ignored[' '] = true; /* ' ' is always ignored */ |
|
||||||
if (Tab.ignored[0]) SemErr("may not ignore \'\\0\'"); .) |
|
||||||
| "TOKENNAMES" (. Symbol.tokenNames = new Hashtable(); .) |
|
||||||
{ ( string | ident ) (. string key = t.val; .) |
|
||||||
"=" ident (. string val = t.val; Symbol.tokenNames.Add(key, val); .) |
|
||||||
} |
|
||||||
. |
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------------*/ |
|
||||||
|
|
||||||
SetDecl (. BitArray s; .) |
|
||||||
= |
|
||||||
ident (. string name = t.val; |
|
||||||
CharClass c = CharClass.Find(name); |
|
||||||
if (c != null) SemErr("name declared twice"); |
|
||||||
.) |
|
||||||
'=' Set<out s> (. if (Sets.Elements(s) == 0) SemErr("character set must not be empty"); |
|
||||||
c = new CharClass(name, s); |
|
||||||
.) |
|
||||||
'.' |
|
||||||
. |
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------------*/ |
|
||||||
|
|
||||||
Set<out BitArray s> (. BitArray s2; .) |
|
||||||
= |
|
||||||
SimSet<out s> |
|
||||||
{ '+' SimSet<out s2> (. s.Or(s2); .) |
|
||||||
| '-' SimSet<out s2> (. Sets.Subtract(s, s2); .) |
|
||||||
} |
|
||||||
. |
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------------*/ |
|
||||||
|
|
||||||
SimSet<out BitArray s> (. int n1, n2; .) |
|
||||||
= (. s = new BitArray(CharClass.charSetSize); .) |
|
||||||
( ident (. CharClass c = CharClass.Find(t.val); |
|
||||||
if (c == null) SemErr("undefined name"); else s.Or(c.set); |
|
||||||
.) |
|
||||||
| string (. string name = t.val; |
|
||||||
name = DFA.Unescape(name.Substring(1, name.Length-2)); |
|
||||||
foreach (char ch in name) s[ch] = true; |
|
||||||
.) |
|
||||||
| Char<out n1> (. s[n1] = true; .) |
|
||||||
[ ".." Char<out n2> (. for (int i = n1; i <= n2; i++) s[i] = true; .) |
|
||||||
] |
|
||||||
| "ANY" (. s = new BitArray(CharClass.charSetSize, true); |
|
||||||
s[0] = false; |
|
||||||
.) |
|
||||||
) |
|
||||||
. |
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------------------*/ |
|
||||||
|
|
||||||
Char<out int n> |
|
||||||
= |
|
||||||
char (. string name = t.val; |
|
||||||
name = DFA.Unescape(name.Substring(1, name.Length-2)); |
|
||||||
int max = CharClass.charSetSize; |
|
||||||
if (name.Length != 1 || name[0] > max-1) SemErr("unacceptable character value"); |
|
||||||
n = name[0] % max; |
|
||||||
.) |
|
||||||
. |
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------------*/ |
|
||||||
|
|
||||||
TokenDecl<int typ> (. string name; int kind; Symbol sym; Graph g; .) |
|
||||||
= |
|
||||||
Sym<out name, out kind> (. sym = Symbol.Find(name); |
|
||||||
if (sym != null) SemErr("name declared twice"); |
|
||||||
else { |
|
||||||
sym = new Symbol(typ, name, t.line); |
|
||||||
sym.tokenKind = Symbol.classToken; |
|
||||||
} |
|
||||||
.) |
|
||||||
SYNC |
|
||||||
( '=' TokenExpr<out g> '.' (. if (kind != id) SemErr("a literal must not be declared with a structure"); |
|
||||||
Graph.Finish(g); |
|
||||||
DFA.ConvertToStates(g.l, sym); |
|
||||||
.) |
|
||||||
| '.' (. if (typ != Node.rslv) SemErr("resolver is only allowed in RESOLVERS section"); .) /* ML-AW */ |
|
||||||
| (. if (kind == id) genScanner = false; |
|
||||||
else DFA.MatchLiteral(sym); |
|
||||||
.) |
|
||||||
) |
|
||||||
( SemText<out sym.semPos> (. if (typ == Node.t) SemErr("semantic action not allowed here"); .) |
|
||||||
| (. if (typ == Node.rslv) SemErr("resolvers must have a semantic action"); .) /* ML-AW */ |
|
||||||
) |
|
||||||
. |
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------------*/ |
|
||||||
|
|
||||||
AttrDecl<Symbol sym> |
|
||||||
= |
|
||||||
'<' (. int beg = la.pos; int col = la.col; .) |
|
||||||
{ ANY |
|
||||||
| badString (. SemErr("bad string in semantic action"); .) |
|
||||||
} |
|
||||||
'>' (. sym.attrPos = new Position(beg, t.pos - beg, col); .) |
|
||||||
. |
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------------*/ |
|
||||||
|
|
||||||
Expression<out Graph g> (. Graph g2; .) |
|
||||||
= |
|
||||||
Term<out g> (. bool first = true; .) |
|
||||||
{ WEAK |
|
||||||
'|' |
|
||||||
Term<out g2> (. if (first) { Graph.MakeFirstAlt(g); first = false; } |
|
||||||
Graph.MakeAlternative(g, g2); |
|
||||||
.) |
|
||||||
} |
|
||||||
. |
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------------*/ |
|
||||||
|
|
||||||
Term<out Graph g> (. Graph g2; Position pos; Node rslv = null; |
|
||||||
g = null; |
|
||||||
.) |
|
||||||
= [ (. rslv = new Node(Node.rslv, null, la.line); .) |
|
||||||
ResolveExpr<out pos> (. rslv.pos = pos; |
|
||||||
g = new Graph(rslv); |
|
||||||
.) |
|
||||||
] |
|
||||||
Factor<out g2> (. if (rslv != null) Graph.MakeSequence(g, g2); |
|
||||||
else g = g2; |
|
||||||
.) |
|
||||||
{ Factor<out g2> (. Graph.MakeSequence(g, g2); .) |
|
||||||
} |
|
||||||
| (. g = new Graph(new Node(Node.eps, null, 0)); .) |
|
||||||
. |
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------------*/ |
|
||||||
|
|
||||||
Factor<out Graph g> (. string name; int kind; Position pos; bool weak = false; |
|
||||||
g = null; |
|
||||||
.) |
|
||||||
= [ "WEAK" (. weak = true; .) |
|
||||||
] |
|
||||||
Sym<out name, out kind> (. Symbol sym = Symbol.Find(name); |
|
||||||
bool undef = sym == null; |
|
||||||
if (undef) { |
|
||||||
if (kind == id) |
|
||||||
sym = new Symbol(Node.nt, name, 0); // forward nt |
|
||||||
else if (genScanner) { |
|
||||||
sym = new Symbol(Node.t, name, t.line); |
|
||||||
DFA.MatchLiteral(sym); |
|
||||||
} else { // undefined string in production |
|
||||||
SemErr("undefined string in production"); |
|
||||||
sym = Tab.eofSy; // dummy |
|
||||||
} |
|
||||||
} |
|
||||||
int typ = sym.typ; |
|
||||||
if (typ != Node.t && typ != Node.nt && typ != Node.rslv) /* ML */ |
|
||||||
SemErr("this symbol kind is not allowed in a production"); |
|
||||||
if (weak) |
|
||||||
if (typ == Node.t) typ = Node.wt; |
|
||||||
else SemErr("only terminals may be weak"); |
|
||||||
Node p = new Node(typ, sym, t.line); |
|
||||||
g = new Graph(p); |
|
||||||
.) |
|
||||||
[ Attribs<p> (. if (kind != id) SemErr("a literal must not have attributes"); .) |
|
||||||
] (. if (undef) |
|
||||||
sym.attrPos = p.pos; // dummy |
|
||||||
else if ((p.pos == null) != (sym.attrPos == null)) |
|
||||||
SemErr("attribute mismatch between declaration and use of this symbol"); |
|
||||||
.) |
|
||||||
| '(' Expression<out g> ')' |
|
||||||
| '[' Expression<out g> ']' (. Graph.MakeOption(g); .) |
|
||||||
| '{' Expression<out g> '}' (. Graph.MakeIteration(g); .) |
|
||||||
| SemText<out pos> (. Node p = new Node(Node.sem, null, 0); |
|
||||||
p.pos = pos; |
|
||||||
g = new Graph(p); |
|
||||||
.) |
|
||||||
| "ANY" (. Node p = new Node(Node.any, null, 0); // p.set is set in Tab.SetupAnys |
|
||||||
g = new Graph(p); |
|
||||||
.) |
|
||||||
| "SYNC" (. Node p = new Node(Node.sync, null, 0); |
|
||||||
g = new Graph(p); |
|
||||||
.) |
|
||||||
. |
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------------*/ |
|
||||||
|
|
||||||
ResolveExpr<out Position pos> |
|
||||||
= |
|
||||||
"IF" "(" (. int beg = la.pos; int col = la.col; .) |
|
||||||
( ("=" | "!=") CondPart /* indicate the beginning of a syntax snippet. |
|
||||||
The condition is true if the actual input matches |
|
||||||
the given syntax snippet (or does not match for "!=") |
|
||||||
*/ |
|
||||||
| "(" CondPart ")" |
|
||||||
| ANY CondPart |
|
||||||
) (. pos = new Position(beg, t.pos - beg, col); .) |
|
||||||
. |
|
||||||
|
|
||||||
/* ConPart exists to guarantee an equal number of opening and * |
|
||||||
* closing parentheses inside the conditional expression. */ |
|
||||||
CondPart = { "(" CondPart | ANY } ")" . |
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------------*/ |
|
||||||
|
|
||||||
TokenExpr<out Graph g> (. Graph g2; .) |
|
||||||
= |
|
||||||
TokenTerm<out g> (. bool first = true; .) |
|
||||||
{ WEAK |
|
||||||
'|' |
|
||||||
TokenTerm<out g2> (. if (first) { Graph.MakeFirstAlt(g); first = false; } |
|
||||||
Graph.MakeAlternative(g, g2); |
|
||||||
.) |
|
||||||
} |
|
||||||
. |
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------------*/ |
|
||||||
|
|
||||||
TokenTerm<out Graph g> (. Graph g2; .) |
|
||||||
= |
|
||||||
TokenFactor<out g> |
|
||||||
{ TokenFactor<out g2> (. Graph.MakeSequence(g, g2); .) |
|
||||||
} |
|
||||||
[ "CONTEXT" |
|
||||||
'(' TokenExpr<out g2> (. Graph.SetContextTrans(g2.l); Graph.MakeSequence(g, g2); .) |
|
||||||
')' |
|
||||||
] |
|
||||||
. |
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------------*/ |
|
||||||
|
|
||||||
TokenFactor<out Graph g> (. string name; int kind; .) |
|
||||||
= |
|
||||||
(. g = new Graph(); .) |
|
||||||
( Sym<out name, out kind> (. if (kind == id) { |
|
||||||
CharClass c = CharClass.Find(name); |
|
||||||
if (c == null) { |
|
||||||
SemErr("undefined name"); |
|
||||||
c = new CharClass(name, new BitArray(CharClass.charSetSize)); |
|
||||||
} |
|
||||||
Node p = new Node(Node.clas, null, 0); p.val = c.n; |
|
||||||
g = new Graph(p); |
|
||||||
} else g = Graph.StrToGraph(name); // str |
|
||||||
.) |
|
||||||
| '(' TokenExpr<out g> ')' |
|
||||||
| '[' TokenExpr<out g> ']' (. Graph.MakeOption(g); .) |
|
||||||
| '{' TokenExpr<out g> '}' (. Graph.MakeIteration(g); .) |
|
||||||
) |
|
||||||
. |
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------------*/ |
|
||||||
|
|
||||||
Sym<out string name, out int kind> |
|
||||||
= (. name = "???"; kind = id; .) |
|
||||||
( ident (. kind = id; name = t.val; .) |
|
||||||
| (string (. name = t.val; .) |
|
||||||
| char (. name = "\"" + t.val.Substring(1, t.val.Length-2) + "\""; .) |
|
||||||
) (. kind = str; .) |
|
||||||
) |
|
||||||
. |
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------------*/ |
|
||||||
|
|
||||||
Attribs<Node p> |
|
||||||
= |
|
||||||
'<' (. int beg = la.pos; int col = la.col; .) |
|
||||||
{ ANY |
|
||||||
| badString (. SemErr("bad string in attributes"); .) |
|
||||||
} |
|
||||||
'>' (. p.pos = new Position(beg, t.pos - beg, col); .) |
|
||||||
. |
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------------*/ |
|
||||||
|
|
||||||
SemText<out Position pos> |
|
||||||
= |
|
||||||
"(." (. int beg = la.pos; int col = la.col; .) |
|
||||||
{ ANY |
|
||||||
| badString (. SemErr("bad string in semantic action"); .) |
|
||||||
| "(." (. SemErr("missing end of previous semantic action"); .) |
|
||||||
} |
|
||||||
".)" (. pos = new Position(beg, t.pos - beg, col); .) |
|
||||||
. |
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------------*/ |
|
||||||
|
|
||||||
UsingDecl<out Position pos> |
|
||||||
= |
|
||||||
"using" (. int beg = t.pos; .) |
|
||||||
{ ANY } ';' (. int end = t.pos; .) |
|
||||||
{ "using" { ANY } ';' (. end = t.pos; .) |
|
||||||
} (. pos = new Position(beg, end - beg + 1, 0); .) |
|
||||||
. |
|
||||||
|
|
||||||
END Coco. |
|
@ -1,71 +0,0 @@ |
|||||||
/*------------------------------------------------------------------------- |
|
||||||
Trace output options |
|
||||||
0 | A: prints the states of the scanner automaton |
|
||||||
1 | F: prints the First and Follow sets of all nonterminals |
|
||||||
2 | G: prints the syntax graph of the productions |
|
||||||
3 | I: traces the computation of the First sets |
|
||||||
4 | J: prints the sets associated with ANYs and synchronisation sets |
|
||||||
6 | S: prints the symbol table (terminals, nonterminals, pragmas) |
|
||||||
7 | X: prints a cross reference list of all syntax symbols |
|
||||||
8 | P: prints statistics about the Coco run |
|
||||||
|
|
||||||
Trace output can be switched on by the pragma |
|
||||||
$ { digit | letter } |
|
||||||
in the attributed grammar or as a command-line option |
|
||||||
-------------------------------------------------------------------------*/ |
|
||||||
|
|
||||||
using System; |
|
||||||
using System.IO; |
|
||||||
|
|
||||||
namespace at.jku.ssw.Coco { |
|
||||||
|
|
||||||
public class Coco { |
|
||||||
|
|
||||||
public static void Main (string[] arg) { |
|
||||||
Console.WriteLine("Coco/R (Aug 4, 2003)"); |
|
||||||
string ATGName = null; |
|
||||||
for (int i = 0; i < arg.Length; i++) { |
|
||||||
if (arg[i] == "-nonamespace") Tab.nsName = null; |
|
||||||
else if (arg[i] == "-namespace") Tab.nsName = arg[++i]; |
|
||||||
else if (arg[i] == "-trace") Tab.SetDDT(arg[++i]); |
|
||||||
else ATGName = arg[i]; |
|
||||||
} |
|
||||||
if (arg.Length > 0 && ATGName != null) { |
|
||||||
int pos = ATGName.LastIndexOf('/'); |
|
||||||
if (pos < 0) pos = ATGName.LastIndexOf('\\'); |
|
||||||
string file = ATGName; |
|
||||||
string dir = ATGName.Substring(0, pos+1); |
|
||||||
|
|
||||||
Scanner.Init(file); |
|
||||||
Trace.Init(dir); |
|
||||||
Tab.Init(); |
|
||||||
DFA.Init(dir); |
|
||||||
ParserGen.Init(file, dir); |
|
||||||
|
|
||||||
Parser.Parse(); |
|
||||||
|
|
||||||
Trace.Close(); |
|
||||||
Console.WriteLine(); |
|
||||||
Console.WriteLine("{0} errors detected", Errors.count); |
|
||||||
} else { |
|
||||||
Console.WriteLine("Usage: Coco {{Option}} Grammar.ATG {{Option}}{0}" + |
|
||||||
"Options:{0}" + |
|
||||||
" -nonamespace{0}" + |
|
||||||
" -namespace <packageName>{0}" + |
|
||||||
" -trace <traceString>{0}" + |
|
||||||
"Valid characters in the trace string:{0}" + |
|
||||||
" A trace automaton{0}" + |
|
||||||
" F list first/follow sets{0}" + |
|
||||||
" G print syntax graph{0}" + |
|
||||||
" I trace computation of first sets{0}" + |
|
||||||
" P print statistics{0}" + |
|
||||||
" S list symbol table{0}" + |
|
||||||
" X list cross reference table{0}" + |
|
||||||
"Scanner.frame and Parser.frame files needed in ATG directory{0}" + |
|
||||||
"or in a directory referenced by the environment variable CRFRAMES.", |
|
||||||
Environment.NewLine); |
|
||||||
} |
|
||||||
} |
|
||||||
} // end Coco
|
|
||||||
|
|
||||||
} // end namespace
|
|
@ -1,889 +0,0 @@ |
|||||||
// DFA.cs Scaner automaton gnerated by Coco/R H.Moessenboeck, Univ. of Linz
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
using System; |
|
||||||
using System.IO; |
|
||||||
using System.Collections; |
|
||||||
using System.Text; |
|
||||||
|
|
||||||
namespace at.jku.ssw.Coco { |
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// State
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public class State { // state of finite automaton
|
|
||||||
public static int lastNr; // highest state number
|
|
||||||
public int nr; // state number
|
|
||||||
public Action firstAction;// to first action of this state
|
|
||||||
public Symbol endOf; // recognized token if state is final
|
|
||||||
public bool ctx; // true if state is reached via contextTrans
|
|
||||||
public State next; |
|
||||||
|
|
||||||
public State() { |
|
||||||
nr = ++lastNr; |
|
||||||
} |
|
||||||
|
|
||||||
public void AddAction(Action act) { |
|
||||||
Action lasta = null, a = firstAction; |
|
||||||
while (a != null && act.typ >= a.typ) {lasta = a; a = a.next;} |
|
||||||
// collecting classes at the beginning gives better performance
|
|
||||||
act.next = a; |
|
||||||
if (a==firstAction) firstAction = act; else lasta.next = act; |
|
||||||
} |
|
||||||
|
|
||||||
public void DetachAction(Action act) { |
|
||||||
Action lasta = null, a = firstAction; |
|
||||||
while (a != null && a != act) {lasta = a; a = a.next;} |
|
||||||
if (a != null) |
|
||||||
if (a == firstAction) firstAction = a.next; else lasta.next = a.next; |
|
||||||
} |
|
||||||
|
|
||||||
public Action TheAction(char ch) { |
|
||||||
BitArray s; |
|
||||||
for (Action a = firstAction; a != null; a = a.next) |
|
||||||
if (a.typ == Node.chr && ch == a.sym) return a; |
|
||||||
else if (a.typ == Node.clas) { |
|
||||||
s = CharClass.Set(a.sym); |
|
||||||
if (s[ch]) return a; |
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
public void MeltWith(State s) { // copy actions of s to state
|
|
||||||
Action a; |
|
||||||
for (Action action = s.firstAction; action != null; action = action.next) { |
|
||||||
a = new Action(action.typ, action.sym, action.tc); |
|
||||||
a.AddTargets(action); |
|
||||||
AddAction(a); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Action
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public class Action { // action of finite automaton
|
|
||||||
public int typ; // type of action symbol: clas, chr
|
|
||||||
public int sym; // action symbol
|
|
||||||
public int tc; // transition code: normalTrans, contextTrans
|
|
||||||
public Target target; // states reached from this action
|
|
||||||
public Action next; |
|
||||||
|
|
||||||
public Action(int typ, int sym, int tc) { |
|
||||||
this.typ = typ; this.sym = sym; this.tc = tc; |
|
||||||
} |
|
||||||
|
|
||||||
public void AddTarget(Target t) { // add t to the action.targets
|
|
||||||
Target last = null; |
|
||||||
Target p = target; |
|
||||||
while (p != null && t.state.nr >= p.state.nr) { |
|
||||||
if (t.state == p.state) return; |
|
||||||
last = p; p = p.next; |
|
||||||
} |
|
||||||
t.next = p; |
|
||||||
if (p == target) target = t; else last.next = t; |
|
||||||
} |
|
||||||
|
|
||||||
public void AddTargets(Action a) { // add copy of a.targets to action.targets
|
|
||||||
for (Target p = a.target; p != null; p = p.next) { |
|
||||||
Target t = new Target(p.state); |
|
||||||
AddTarget(t); |
|
||||||
} |
|
||||||
if (a.tc == Node.contextTrans) tc = Node.contextTrans; |
|
||||||
} |
|
||||||
|
|
||||||
public BitArray Symbols() { |
|
||||||
BitArray s; |
|
||||||
if (typ == Node.clas) |
|
||||||
s = (BitArray) CharClass.Set(sym).Clone(); |
|
||||||
else { |
|
||||||
s = new BitArray(CharClass.charSetSize); s[sym] = true; |
|
||||||
} |
|
||||||
return s; |
|
||||||
} |
|
||||||
|
|
||||||
public void ShiftWith(BitArray s) { |
|
||||||
if (Sets.Elements(s) == 1) { |
|
||||||
typ = Node.chr; sym = Sets.First(s); |
|
||||||
} else { |
|
||||||
CharClass c = CharClass.Find(s); |
|
||||||
if (c == null) c = new CharClass("#", s); // class with dummy name
|
|
||||||
typ = Node.clas; sym = c.n; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public void GetTargetStates(out BitArray targets, out Symbol endOf, out bool ctx) { |
|
||||||
// compute the set of target states
|
|
||||||
targets = new BitArray(DFA.maxStates); endOf = null; |
|
||||||
ctx = false; |
|
||||||
for (Target t = target; t != null; t = t.next) { |
|
||||||
int stateNr = t.state.nr; |
|
||||||
if (stateNr <= DFA.lastSimState) targets[stateNr] = true; |
|
||||||
else targets.Or(Melted.Set(stateNr)); |
|
||||||
if (t.state.endOf != null) |
|
||||||
if (endOf == null || endOf == t.state.endOf) |
|
||||||
endOf = t.state.endOf; |
|
||||||
else { |
|
||||||
Console.WriteLine("Tokens {0} and {1} cannot be distinguished", endOf.name, t.state.endOf.name); |
|
||||||
Errors.count++; |
|
||||||
} |
|
||||||
if (t.state.ctx) { |
|
||||||
ctx = true; |
|
||||||
// The following check seems to be unnecessary. It reported an error
|
|
||||||
// if a symbol + context was the prefix of another symbol, e.g.
|
|
||||||
// s1 = "a" "b" "c".
|
|
||||||
// s2 = "a" CONTEXT("b").
|
|
||||||
// But this is ok.
|
|
||||||
// if (t.state.endOf != null) {
|
|
||||||
// Console.WriteLine("Ambiguous context clause");
|
|
||||||
// Errors.count++;
|
|
||||||
// }
|
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Target
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public class Target { // set of states that are reached by an action
|
|
||||||
public State state; // target state
|
|
||||||
public Target next; |
|
||||||
|
|
||||||
public Target (State s) { |
|
||||||
state = s; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Melted
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public class Melted { // info about melted states
|
|
||||||
public static Melted first; // head of melted state list
|
|
||||||
public BitArray set; // set of old states
|
|
||||||
public State state; // new state
|
|
||||||
public Melted next; |
|
||||||
|
|
||||||
public Melted(BitArray set, State state) { |
|
||||||
this.set = set; this.state = state; |
|
||||||
this.next = first; first = this; |
|
||||||
} |
|
||||||
|
|
||||||
public static BitArray Set(int nr) { |
|
||||||
Melted m = first; |
|
||||||
while (m != null) { |
|
||||||
if (m.state.nr == nr) return m.set; else m = m.next; |
|
||||||
} |
|
||||||
throw new Exception("-- compiler error in Melted.Set"); |
|
||||||
} |
|
||||||
|
|
||||||
public static Melted StateWithSet(BitArray s) { |
|
||||||
for (Melted m = first; m != null; m = m.next) |
|
||||||
if (Sets.Equals(s, m.set)) return m; |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Comment
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public class Comment { // info about comment syntax
|
|
||||||
public static Comment first; // list of comments
|
|
||||||
public string start; |
|
||||||
public string stop; |
|
||||||
public bool nested; |
|
||||||
public Comment next; |
|
||||||
|
|
||||||
static string Str(Node p) { |
|
||||||
StringBuilder s = new StringBuilder(); |
|
||||||
while (p != null) { |
|
||||||
if (p.typ == Node.chr) { |
|
||||||
s.Append((char)p.val); |
|
||||||
} else if (p.typ == Node.clas) { |
|
||||||
BitArray set = CharClass.Set(p.val); |
|
||||||
if (Sets.Elements(set) != 1) Parser.SemErr("character set contains more than 1 character"); |
|
||||||
s.Append((char)Sets.First(set)); |
|
||||||
} else Parser.SemErr("comment delimiters may not be structured"); |
|
||||||
p = p.next; |
|
||||||
} |
|
||||||
if (s.Length == 0 || s.Length > 2) { |
|
||||||
Parser.SemErr("comment delimiters must be 1 or 2 characters long"); |
|
||||||
s = new StringBuilder("?"); |
|
||||||
} |
|
||||||
return s.ToString(); |
|
||||||
} |
|
||||||
|
|
||||||
public Comment(Node from, Node to, bool nested) { |
|
||||||
start = Str(from); |
|
||||||
stop = Str(to); |
|
||||||
this.nested = nested; |
|
||||||
this.next = first; first = this; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// DFA
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public class DFA { |
|
||||||
public static int maxStates; |
|
||||||
public const int EOF = -1; |
|
||||||
public const char CR = '\r'; |
|
||||||
public const char LF = '\n'; |
|
||||||
|
|
||||||
public static State firstState; |
|
||||||
public static State lastState; // last allocated state
|
|
||||||
public static int lastSimState; // last non melted state
|
|
||||||
public static FileStream fram; // scanner frame input
|
|
||||||
public static StreamWriter gen; // generated scanner file
|
|
||||||
static string srcDir; // directory of attributed grammar file
|
|
||||||
public static Symbol curSy; // current token to be recognized (in FindTrans)
|
|
||||||
public static Node curGraph; // start of graph for current token (in FindTrans)
|
|
||||||
public static bool dirtyDFA; // DFA may become nondeterministic in MatchedDFA
|
|
||||||
public static bool hasCtxMoves; // DFA has context transitions
|
|
||||||
|
|
||||||
//---------- Output primitives
|
|
||||||
private static string Ch(char ch) { |
|
||||||
if (ch < ' ' || ch >= 127 || ch == '\'' || ch == '\\') return Convert.ToString((int)ch); |
|
||||||
else return String.Format("'{0}'", ch); |
|
||||||
} |
|
||||||
|
|
||||||
private static string ChCond(char ch) { |
|
||||||
return String.Format("ch == {0}", Ch(ch)); |
|
||||||
} |
|
||||||
|
|
||||||
private static void PutRange(BitArray s) { |
|
||||||
int[] lo = new int[32]; |
|
||||||
int[] hi = new int[32]; |
|
||||||
// fill lo and hi
|
|
||||||
int max = CharClass.charSetSize; |
|
||||||
int top = -1; |
|
||||||
int i = 0; |
|
||||||
while (i < max) { |
|
||||||
if (s[i]) { |
|
||||||
top++; lo[top] = i; i++; |
|
||||||
while (i < max && s[i]) i++; |
|
||||||
hi[top] = i-1; |
|
||||||
} else i++; |
|
||||||
} |
|
||||||
// print ranges
|
|
||||||
if (top == 1 && lo[0] == 0 && hi[1] == max-1 && hi[0]+2 == lo[1]) { |
|
||||||
BitArray s1 = new BitArray(max); s1[hi[0]+1] = true; |
|
||||||
gen.Write("!"); PutRange(s1); |
|
||||||
} else { |
|
||||||
gen.Write("("); |
|
||||||
for (i = 0; i <= top; i++) { |
|
||||||
if (hi[i] == lo[i]) gen.Write("ch == {0}", Ch((char)lo[i])); |
|
||||||
else if (lo[i] == 0) gen.Write("ch <= {0}", Ch((char)hi[i])); |
|
||||||
else if (hi[i] == max-1) gen.Write("ch >= {0}", Ch((char)lo[i])); |
|
||||||
else gen.Write("ch >= {0} && ch <= {1}", Ch((char)lo[i]), Ch((char)hi[i])); |
|
||||||
if (i < top) gen.Write(" || "); |
|
||||||
} |
|
||||||
gen.Write(")"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
//---------- String handling
|
|
||||||
static char Hex2Char(string s) { |
|
||||||
int val = 0; |
|
||||||
for (int i = 0; i < s.Length; i++) { |
|
||||||
char ch = s[i]; |
|
||||||
if ('0' <= ch && ch <= '9') val = 16 * val + (ch - '0'); |
|
||||||
else if ('a' <= ch && ch <= 'f') val = 16 * val + (10 + ch - 'a'); |
|
||||||
else if ('A' <= ch && ch <= 'Z') val = 16 * val + (10 + ch - 'A'); |
|
||||||
else Parser.SemErr("bad escape sequence in string or character"); |
|
||||||
} |
|
||||||
return (char)val; |
|
||||||
} |
|
||||||
|
|
||||||
static string Char2Hex(char ch) { |
|
||||||
StringWriter w = new StringWriter(); |
|
||||||
w.Write("\\u{0:x4}", (int)ch); |
|
||||||
return w.ToString(); |
|
||||||
} |
|
||||||
|
|
||||||
public static string Unescape (string s) { |
|
||||||
/* replaces escape sequences in s by their Unicode values. */ |
|
||||||
StringBuilder buf = new StringBuilder(); |
|
||||||
int i = 0; |
|
||||||
while (i < s.Length) { |
|
||||||
if (s[i] == '\\') { |
|
||||||
switch (s[i+1]) { |
|
||||||
case '\\': buf.Append('\\'); i += 2; break; |
|
||||||
case '\'': buf.Append('\''); i += 2; break; |
|
||||||
case '\"': buf.Append('\"'); i += 2; break; |
|
||||||
case 'r': buf.Append('\r'); i += 2; break; |
|
||||||
case 'n': buf.Append('\n'); i += 2; break; |
|
||||||
case 't': buf.Append('\t'); i += 2; break; |
|
||||||
case '0': buf.Append('\0'); i += 2; break; |
|
||||||
case 'a': buf.Append('\a'); i += 2; break; |
|
||||||
case 'b': buf.Append('\b'); i += 2; break; |
|
||||||
case 'f': buf.Append('\f'); i += 2; break; |
|
||||||
case 'v': buf.Append('\v'); i += 2; break; |
|
||||||
case 'u': case 'x': |
|
||||||
if (i + 6 <= s.Length) { |
|
||||||
buf.Append(Hex2Char(s.Substring(i+2, 4))); i += 6; break; |
|
||||||
} else { |
|
||||||
Parser.SemErr("bad escape sequence in string or character"); i = s.Length; break; |
|
||||||
} |
|
||||||
default: Parser.SemErr("bad escape sequence in string or character"); i += 2; break; |
|
||||||
} |
|
||||||
} else { |
|
||||||
buf.Append(s[i]); |
|
||||||
i++; |
|
||||||
} |
|
||||||
} |
|
||||||
return buf.ToString(); |
|
||||||
} |
|
||||||
|
|
||||||
public static string Escape (string s) { |
|
||||||
StringBuilder buf = new StringBuilder(); |
|
||||||
foreach (char ch in s) { |
|
||||||
if (ch == '\\') buf.Append("\\\\"); |
|
||||||
else if (ch == '"') buf.Append("\\\""); |
|
||||||
else if (ch < ' ' || ch > '\u007f') buf.Append(Char2Hex(ch)); |
|
||||||
else buf.Append(ch); |
|
||||||
} |
|
||||||
return buf.ToString(); |
|
||||||
} |
|
||||||
|
|
||||||
//---------- State handling
|
|
||||||
static State NewState() { |
|
||||||
State s = new State(); |
|
||||||
if (firstState == null) firstState = s; else lastState.next = s; |
|
||||||
lastState = s; |
|
||||||
return s; |
|
||||||
} |
|
||||||
|
|
||||||
static void NewTransition(State from, State to, int typ, int sym, int tc) { |
|
||||||
if (to == firstState) Parser.SemErr("token must not start with an iteration"); |
|
||||||
Target t = new Target(to); |
|
||||||
Action a = new Action(typ, sym, tc); a.target = t; |
|
||||||
from.AddAction(a); |
|
||||||
} |
|
||||||
|
|
||||||
static void CombineShifts() { |
|
||||||
State state; |
|
||||||
Action a, b, c; |
|
||||||
BitArray seta, setb; |
|
||||||
for (state = firstState; state != null; state = state.next) { |
|
||||||
for (a = state.firstAction; a != null; a = a.next) { |
|
||||||
b = a.next; |
|
||||||
while (b != null) |
|
||||||
if (a.target.state == b.target.state && a.tc == b.tc) { |
|
||||||
seta = a.Symbols(); setb = b.Symbols(); |
|
||||||
seta.Or(setb); |
|
||||||
a.ShiftWith(seta); |
|
||||||
c = b; b = b.next; state.DetachAction(c); |
|
||||||
} else b = b.next; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void FindUsedStates(State state, BitArray used) { |
|
||||||
if (used[state.nr]) return; |
|
||||||
used[state.nr] = true; |
|
||||||
for (Action a = state.firstAction; a != null; a = a.next) |
|
||||||
FindUsedStates(a.target.state, used); |
|
||||||
} |
|
||||||
|
|
||||||
static void DeleteRedundantStates() { |
|
||||||
State[] newState = new State[State.lastNr + 1]; |
|
||||||
BitArray used = new BitArray(State.lastNr + 1); |
|
||||||
FindUsedStates(firstState, used); |
|
||||||
// combine equal final states
|
|
||||||
for (State s1 = firstState.next; s1 != null; s1 = s1.next) // firstState cannot be final
|
|
||||||
if (used[s1.nr] && s1.endOf != null && s1.firstAction == null && !s1.ctx) |
|
||||||
for (State s2 = s1.next; s2 != null; s2 = s2.next) |
|
||||||
if (used[s2.nr] && s1.endOf == s2.endOf && s2.firstAction == null & !s2.ctx) { |
|
||||||
used[s2.nr] = false; newState[s2.nr] = s1; |
|
||||||
} |
|
||||||
for (State state = firstState; state != null; state = state.next) |
|
||||||
if (used[state.nr]) |
|
||||||
for (Action a = state.firstAction; a != null; a = a.next) |
|
||||||
if (!used[a.target.state.nr]) |
|
||||||
a.target.state = newState[a.target.state.nr]; |
|
||||||
// delete unused states
|
|
||||||
lastState = firstState; State.lastNr = 0; // firstState has number 0
|
|
||||||
for (State state = firstState.next; state != null; state = state.next) |
|
||||||
if (used[state.nr]) {state.nr = ++State.lastNr; lastState = state;} |
|
||||||
else lastState.next = state.next; |
|
||||||
} |
|
||||||
|
|
||||||
static State TheState(Node p) { |
|
||||||
State state; |
|
||||||
if (p == null) {state = NewState(); state.endOf = curSy; return state;} |
|
||||||
else return p.state; |
|
||||||
} |
|
||||||
|
|
||||||
static void Step(State from, Node p, BitArray stepped) { |
|
||||||
if (p == null) return; |
|
||||||
stepped[p.n] = true; |
|
||||||
switch (p.typ) { |
|
||||||
case Node.clas: case Node.chr: { |
|
||||||
NewTransition(from, TheState(p.next), p.typ, p.val, p.code); |
|
||||||
break; |
|
||||||
} |
|
||||||
case Node.alt: { |
|
||||||
Step(from, p.sub, stepped); Step(from, p.down, stepped); |
|
||||||
break; |
|
||||||
} |
|
||||||
case Node.iter: case Node.opt: { |
|
||||||
if (p.next != null && !stepped[p.next.n]) Step(from, p.next, stepped); |
|
||||||
Step(from, p.sub, stepped); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void NumberNodes(Node p, State state) { |
|
||||||
/* Assigns a state n.state to every node n. There will be a transition from |
|
||||||
n.state to n.next.state triggered by n.val. All nodes in an alternative |
|
||||||
chain are represented by the same state. |
|
||||||
*/ |
|
||||||
if (p == null) return; |
|
||||||
if (p.state != null) return; // already visited;
|
|
||||||
if (state == null) state = NewState(); |
|
||||||
p.state = state; |
|
||||||
if (Node.DelGraph(p)) state.endOf = curSy; |
|
||||||
switch (p.typ) { |
|
||||||
case Node.clas: case Node.chr: { |
|
||||||
NumberNodes(p.next, null); |
|
||||||
break; |
|
||||||
} |
|
||||||
case Node.opt: { |
|
||||||
NumberNodes(p.next, null); NumberNodes(p.sub, state); |
|
||||||
break; |
|
||||||
} |
|
||||||
case Node.iter: { |
|
||||||
NumberNodes(p.next, state); NumberNodes(p.sub, state); |
|
||||||
break; |
|
||||||
} |
|
||||||
case Node.alt: { |
|
||||||
NumberNodes(p.sub, state); NumberNodes(p.down, state); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void FindTrans (Node p, bool start, BitArray marked) { |
|
||||||
if (p == null || marked[p.n]) return; |
|
||||||
marked[p.n] = true; |
|
||||||
if (start) Step(p.state, p, new BitArray(Node.nodes.Count)); // start of group of equally numbered nodes
|
|
||||||
switch (p.typ) { |
|
||||||
case Node.clas: case Node.chr: { |
|
||||||
FindTrans(p.next, true, marked); |
|
||||||
break; |
|
||||||
} |
|
||||||
case Node.opt: { |
|
||||||
FindTrans(p.next, true, marked); FindTrans(p.sub, false, marked); |
|
||||||
break; |
|
||||||
} |
|
||||||
case Node.iter: { |
|
||||||
FindTrans(p.next, false, marked); FindTrans(p.sub, false, marked); |
|
||||||
break; |
|
||||||
} |
|
||||||
case Node.alt: { |
|
||||||
FindTrans(p.sub, false, marked); FindTrans(p.down, false, marked); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static void ConvertToStates(Node p, Symbol sym) { |
|
||||||
curGraph = p; curSy = sym; |
|
||||||
if (Node.DelGraph(curGraph)) Parser.SemErr("token might be empty"); |
|
||||||
NumberNodes(curGraph, firstState); |
|
||||||
FindTrans(curGraph, true, new BitArray(Node.nodes.Count)); |
|
||||||
} |
|
||||||
|
|
||||||
static Symbol MatchedDFA(string s, Symbol sym) { |
|
||||||
int i, len = s.Length; |
|
||||||
bool weakMatch = false; |
|
||||||
// s has no quotes
|
|
||||||
State state = firstState; |
|
||||||
for (i = 0; i < len; i++) { // try to match s against existing DFA
|
|
||||||
Action a = state.TheAction(s[i]); |
|
||||||
if (a == null) break; |
|
||||||
if (a.typ == Node.clas) weakMatch = true; |
|
||||||
state = a.target.state; |
|
||||||
} |
|
||||||
// don't execute the following block if s was totally consumed and the DFA is in a final state
|
|
||||||
if (weakMatch && (i != len || state.endOf == null)) { |
|
||||||
state = firstState; i = 0; |
|
||||||
dirtyDFA = true; |
|
||||||
} |
|
||||||
for (; i < len; i++) { // make new DFA for s[i..len-1]
|
|
||||||
State to = NewState(); |
|
||||||
NewTransition(state, to, Node.chr, s[i], Node.normalTrans); |
|
||||||
state = to; |
|
||||||
} |
|
||||||
Symbol matchedSym = state.endOf; |
|
||||||
if (state.endOf == null) state.endOf = sym; |
|
||||||
return matchedSym; |
|
||||||
} |
|
||||||
|
|
||||||
public static void MatchLiteral(Symbol sym) { // store string either as token or as literal
|
|
||||||
string name = Unescape(sym.name.Substring(1, sym.name.Length-2)); |
|
||||||
if (name.IndexOf('\0') >= 0) Parser.SemErr("\\0 not allowed here. Used as eof character"); |
|
||||||
Symbol matchedSym = MatchedDFA(name, sym); |
|
||||||
if (matchedSym == null) |
|
||||||
sym.tokenKind = Symbol.classToken; |
|
||||||
else { |
|
||||||
matchedSym.tokenKind = Symbol.classLitToken; |
|
||||||
sym.tokenKind = Symbol.litToken; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void SplitActions(State state, Action a, Action b) { |
|
||||||
Action c; BitArray seta, setb, setc; |
|
||||||
seta = a.Symbols(); setb = b.Symbols(); |
|
||||||
if (Sets.Equals(seta, setb)) { |
|
||||||
a.AddTargets(b); |
|
||||||
state.DetachAction(b); |
|
||||||
} else if (Sets.Includes(seta, setb)) { |
|
||||||
setc = (BitArray)seta.Clone(); Sets.Subtract(setc, setb); |
|
||||||
b.AddTargets(a); |
|
||||||
a.ShiftWith(setc); |
|
||||||
} else if (Sets.Includes(setb, seta)) { |
|
||||||
setc = (BitArray)setb.Clone(); Sets.Subtract(setc, seta); |
|
||||||
a.AddTargets(b); |
|
||||||
b.ShiftWith(setc); |
|
||||||
} else { |
|
||||||
setc = (BitArray)seta.Clone(); setc.And(setb); |
|
||||||
Sets.Subtract(seta, setc); |
|
||||||
Sets.Subtract(setb, setc); |
|
||||||
a.ShiftWith(seta); |
|
||||||
b.ShiftWith(setb); |
|
||||||
c = new Action(0, 0, Node.normalTrans); // typ and sym are set in ShiftWith
|
|
||||||
c.AddTargets(a); |
|
||||||
c.AddTargets(b); |
|
||||||
c.ShiftWith(setc); |
|
||||||
state.AddAction(c); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private static bool Overlap(Action a, Action b) { |
|
||||||
BitArray seta, setb; |
|
||||||
if (a.typ == Node.chr) |
|
||||||
if (b.typ == Node.chr) return a.sym == b.sym; |
|
||||||
else {setb = CharClass.Set(b.sym); return setb[a.sym];} |
|
||||||
else { |
|
||||||
seta = CharClass.Set(a.sym); |
|
||||||
if (b.typ ==Node.chr) return seta[b.sym]; |
|
||||||
else {setb = CharClass.Set(b.sym); return Sets.Intersect(seta, setb);} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static bool MakeUnique(State state) { // return true if actions were split
|
|
||||||
bool changed = false; |
|
||||||
for (Action a = state.firstAction; a != null; a = a.next) |
|
||||||
for (Action b = a.next; b != null; b = b.next) |
|
||||||
if (Overlap(a, b)) {SplitActions(state, a, b); changed = true;} |
|
||||||
return changed; |
|
||||||
} |
|
||||||
|
|
||||||
static void MeltStates(State state) { |
|
||||||
bool changed, ctx; |
|
||||||
BitArray targets; |
|
||||||
Symbol endOf; |
|
||||||
for (Action action = state.firstAction; action != null; action = action.next) { |
|
||||||
if (action.target.next != null) { |
|
||||||
action.GetTargetStates(out targets, out endOf, out ctx); |
|
||||||
Melted melt = Melted.StateWithSet(targets); |
|
||||||
if (melt == null) { |
|
||||||
State s = NewState(); s.endOf = endOf; s.ctx = ctx; |
|
||||||
for (Target targ = action.target; targ != null; targ = targ.next) |
|
||||||
s.MeltWith(targ.state); |
|
||||||
do {changed = MakeUnique(s);} while (changed); |
|
||||||
melt = new Melted(targets, s); |
|
||||||
} |
|
||||||
action.target.next = null; |
|
||||||
action.target.state = melt.state; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void FindCtxStates() { |
|
||||||
for (State state = firstState; state != null; state = state.next) |
|
||||||
for (Action a = state.firstAction; a != null; a = a.next) |
|
||||||
if (a.tc == Node.contextTrans) a.target.state.ctx = true; |
|
||||||
} |
|
||||||
|
|
||||||
public static void MakeDeterministic() { |
|
||||||
State state; |
|
||||||
bool changed; |
|
||||||
lastSimState = lastState.nr; |
|
||||||
maxStates = 2 * lastSimState; // heuristic for set size in Melted.set
|
|
||||||
FindCtxStates(); |
|
||||||
for (state = firstState; state != null; state = state.next) |
|
||||||
do {changed = MakeUnique(state);} while (changed); |
|
||||||
for (state = firstState; state != null; state = state.next) |
|
||||||
MeltStates(state); |
|
||||||
DeleteRedundantStates(); |
|
||||||
CombineShifts(); |
|
||||||
} |
|
||||||
|
|
||||||
public static void PrintStates() { |
|
||||||
Trace.WriteLine("\n---------- states ----------"); |
|
||||||
for (State state = firstState; state != null; state = state.next) { |
|
||||||
bool first = true; |
|
||||||
if (state.endOf == null) Trace.Write(" "); |
|
||||||
else Trace.Write("E({0,12})", Node.Name(state.endOf.name)); |
|
||||||
Trace.Write("{0,3}:", state.nr); |
|
||||||
if (state.firstAction == null) Trace.WriteLine(); |
|
||||||
for (Action action = state.firstAction; action != null; action = action.next) { |
|
||||||
if (first) {Trace.Write(" "); first = false;} else Trace.Write(" "); |
|
||||||
if (action.typ == Node.clas) Trace.Write(((CharClass)CharClass.classes[action.sym]).name); |
|
||||||
else Trace.Write("{0, 3}", Ch((char)action.sym)); |
|
||||||
for (Target targ = action.target; targ != null; targ = targ.next) |
|
||||||
Trace.Write(" {0, 3}", targ.state.nr); |
|
||||||
if (action.tc == Node.contextTrans) Trace.WriteLine(" context"); else Trace.WriteLine(); |
|
||||||
} |
|
||||||
} |
|
||||||
Trace.WriteLine("\n---------- character classes ----------"); |
|
||||||
CharClass.WriteClasses(); |
|
||||||
} |
|
||||||
|
|
||||||
static void GenComBody(Comment com) { |
|
||||||
gen.WriteLine( "\t\t\tfor(;;) {"); |
|
||||||
gen.Write ( "\t\t\t\tif ({0}) ", ChCond(com.stop[0])); gen.WriteLine("{"); |
|
||||||
if (com.stop.Length == 1) { |
|
||||||
gen.WriteLine("\t\t\t\t\tlevel--;"); |
|
||||||
gen.WriteLine("\t\t\t\t\tif (level == 0) { oldEols = line - line0; NextCh(); return true; }"); |
|
||||||
gen.WriteLine("\t\t\t\t\tNextCh();"); |
|
||||||
} else { |
|
||||||
gen.WriteLine("\t\t\t\t\tNextCh();"); |
|
||||||
gen.WriteLine("\t\t\t\t\tif ({0}) {{", ChCond(com.stop[1])); |
|
||||||
gen.WriteLine("\t\t\t\t\t\tlevel--;"); |
|
||||||
gen.WriteLine("\t\t\t\t\t\tif (level == 0) { oldEols = line - line0; NextCh(); return true; }"); |
|
||||||
gen.WriteLine("\t\t\t\t\t\tNextCh();"); |
|
||||||
gen.WriteLine("\t\t\t\t\t}"); |
|
||||||
} |
|
||||||
if (com.nested) { |
|
||||||
gen.Write ("\t\t\t\t}"); gen.Write(" else if ({0}) ", ChCond(com.start[0])); gen.WriteLine("{"); |
|
||||||
if (com.start.Length == 1) |
|
||||||
gen.WriteLine("\t\t\t\t\tlevel++; NextCh();"); |
|
||||||
else { |
|
||||||
gen.WriteLine("\t\t\t\t\tNextCh();"); |
|
||||||
gen.Write ("\t\t\t\t\tif ({0}) ", ChCond(com.start[1])); gen.WriteLine("{"); |
|
||||||
gen.WriteLine("\t\t\t\t\t\tlevel++; NextCh();"); |
|
||||||
gen.WriteLine("\t\t\t\t\t}"); |
|
||||||
} |
|
||||||
} |
|
||||||
gen.WriteLine( "\t\t\t\t} else if (ch == EOF) return false;"); |
|
||||||
gen.WriteLine( "\t\t\t\telse NextCh();"); |
|
||||||
gen.WriteLine( "\t\t\t}"); |
|
||||||
} |
|
||||||
|
|
||||||
static void GenComment(Comment com, int i) { |
|
||||||
gen.Write ("\n\tstatic bool Comment{0}() ", i); gen.WriteLine("{"); |
|
||||||
gen.WriteLine("\t\tint level = 1, line0 = line, lineStart0 = lineStart;"); |
|
||||||
if (com.start.Length == 1) { |
|
||||||
gen.WriteLine("\t\tNextCh();"); |
|
||||||
GenComBody(com); |
|
||||||
} else { |
|
||||||
gen.WriteLine("\t\tNextCh();"); |
|
||||||
gen.Write ("\t\tif ({0}) ", ChCond(com.start[1])); gen.WriteLine("{"); |
|
||||||
gen.WriteLine("\t\t\tNextCh();"); |
|
||||||
GenComBody(com); |
|
||||||
gen.WriteLine("\t\t} else {"); |
|
||||||
gen.WriteLine("\t\t\tif (ch==EOL) {line--; lineStart = lineStart0;}"); |
|
||||||
gen.WriteLine("\t\t\tpos = pos - 2; Buffer.Pos = pos+1; NextCh();"); |
|
||||||
gen.WriteLine("\t\t}"); |
|
||||||
gen.WriteLine("\t\treturn false;"); |
|
||||||
} |
|
||||||
gen.WriteLine("\t}"); |
|
||||||
} |
|
||||||
|
|
||||||
static void CopyFramePart(string stop) { |
|
||||||
char startCh = stop[0]; |
|
||||||
int endOfStopString = stop.Length-1; |
|
||||||
int ch = fram.ReadByte(); |
|
||||||
while (ch != EOF) |
|
||||||
if (ch == startCh) { |
|
||||||
int i = 0; |
|
||||||
do { |
|
||||||
if (i == endOfStopString) return; // stop[0..i] found
|
|
||||||
ch = fram.ReadByte(); i++; |
|
||||||
} while (ch == stop[i]); |
|
||||||
// stop[0..i-1] found; continue with last read character
|
|
||||||
gen.Write(stop.Substring(0, i)); |
|
||||||
} else { |
|
||||||
gen.Write((char)ch); ch = fram.ReadByte(); |
|
||||||
} |
|
||||||
Errors.Exception(" -- incomplete or corrupt scanner frame file"); |
|
||||||
} |
|
||||||
|
|
||||||
static void GenLiterals () { |
|
||||||
foreach (Symbol sym in Symbol.terminals) { |
|
||||||
if (sym.tokenKind == Symbol.litToken) { |
|
||||||
// sym.name stores literals with quotes, e.g. "\"Literal\"",
|
|
||||||
// therefore do NOT place any quotes around {0} after the case
|
|
||||||
// or you'll get: case ""Literal"": t.kind = ..., which causes an error
|
|
||||||
gen.WriteLine("\t\t\tcase {0}: t.kind = {1}; break;", sym.name, sym.n); |
|
||||||
} |
|
||||||
} |
|
||||||
gen.WriteLine("\t\t\tdefault: break;"); |
|
||||||
} |
|
||||||
|
|
||||||
static void WriteState(State state) { |
|
||||||
Symbol endOf = state.endOf; |
|
||||||
gen.WriteLine("\t\t\tcase {0}:", state.nr); |
|
||||||
bool ctxEnd = state.ctx; |
|
||||||
for (Action action = state.firstAction; action != null; action = action.next) { |
|
||||||
if (action == state.firstAction) gen.Write("\t\t\t\tif ("); |
|
||||||
else gen.Write("\t\t\t\telse if ("); |
|
||||||
if (action.typ == Node.chr) gen.Write(ChCond((char)action.sym)); |
|
||||||
else PutRange(CharClass.Set(action.sym)); |
|
||||||
gen.Write(") {"); |
|
||||||
if (action.tc == Node.contextTrans) { |
|
||||||
gen.Write("apx++; "); ctxEnd = false; |
|
||||||
} else if (state.ctx) |
|
||||||
gen.Write("apx = 0; "); |
|
||||||
gen.Write("buf.Append(ch); NextCh(); goto case {0};", action.target.state.nr); |
|
||||||
gen.WriteLine("}"); |
|
||||||
} |
|
||||||
if (state.firstAction == null) |
|
||||||
gen.Write("\t\t\t\t{"); |
|
||||||
else |
|
||||||
gen.Write("\t\t\t\telse {"); |
|
||||||
if (ctxEnd) { // final context state: cut appendix
|
|
||||||
gen.WriteLine(); |
|
||||||
gen.WriteLine("\t\t\t\t\tbuf.Length = buf.Length - apx;"); |
|
||||||
gen.WriteLine("\t\t\t\t\tpos = pos - apx - 1; line = t.line;"); |
|
||||||
gen.WriteLine("\t\t\t\t\tBuffer.Pos = pos+1; NextCh();"); |
|
||||||
gen.Write( "\t\t\t\t\t"); |
|
||||||
} |
|
||||||
if (endOf == null) { |
|
||||||
gen.WriteLine("t.kind = noSym; goto done;}"); |
|
||||||
} else { |
|
||||||
gen.Write("t.kind = {0}; ", endOf.n); |
|
||||||
if (endOf.tokenKind == Symbol.classLitToken) { |
|
||||||
gen.WriteLine("t.val = buf.ToString(); CheckLiteral(); return t;}"); |
|
||||||
} else { |
|
||||||
gen.WriteLine("goto done;}"); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void FillStartTab(int[] startTab) { |
|
||||||
startTab[0] = State.lastNr + 1; // eof
|
|
||||||
for (Action action = firstState.firstAction; action != null; action = action.next) { |
|
||||||
int targetState = action.target.state.nr; |
|
||||||
if (action.typ == Node.chr) startTab[action.sym] = targetState; |
|
||||||
else { |
|
||||||
BitArray s = CharClass.Set(action.sym); |
|
||||||
for (int i = 0; i < s.Count; i++) |
|
||||||
if (s[i]) startTab[i] = targetState; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static void WriteScanner() { |
|
||||||
int i, j; |
|
||||||
int[] startTab = new int[CharClass.charSetSize]; |
|
||||||
string dir = System.Environment.CurrentDirectory; |
|
||||||
string fr = dir + "\\Scanner.frame"; |
|
||||||
if (!File.Exists(fr)) { |
|
||||||
string frameDir = Environment.GetEnvironmentVariable("crframes"); |
|
||||||
if (frameDir != null) fr = frameDir.Trim() + "\\Scanner.frame"; |
|
||||||
if (!File.Exists(fr)) Errors.Exception("-- Cannot find Scanner.frame"); |
|
||||||
} |
|
||||||
try { |
|
||||||
fram = new FileStream(fr, FileMode.Open, FileAccess.Read, FileShare.Read); |
|
||||||
} catch (FileNotFoundException) { |
|
||||||
Errors.Exception("-- Cannot open Scanner.frame."); |
|
||||||
} |
|
||||||
try { |
|
||||||
string fn = dir + "\\Scanner.cs"; |
|
||||||
if (File.Exists(fn)) File.Copy(fn, fn+".old", true); |
|
||||||
FileStream s = new FileStream(fn, FileMode.Create); |
|
||||||
gen = new StreamWriter(s); |
|
||||||
} catch (IOException) { |
|
||||||
Errors.Exception("-- Cannot generate scanner file."); |
|
||||||
} |
|
||||||
if (dirtyDFA) MakeDeterministic(); |
|
||||||
FillStartTab(startTab); |
|
||||||
|
|
||||||
CopyFramePart("-->namespace"); |
|
||||||
/* AW add namespace, if it exists */ |
|
||||||
if (Tab.nsName != null && Tab.nsName.Length > 0) { |
|
||||||
gen.Write("namespace "); |
|
||||||
gen.Write(Tab.nsName); |
|
||||||
gen.Write(" {"); |
|
||||||
} |
|
||||||
CopyFramePart("-->constants"); |
|
||||||
gen.WriteLine("\tconst int maxT = {0};", Symbol.terminals.Count - 1); |
|
||||||
CopyFramePart("-->declarations"); |
|
||||||
gen.WriteLine("\tconst int noSym = {0};", Tab.noSym.n); |
|
||||||
gen.WriteLine("\tstatic short[] start = {"); |
|
||||||
for (i = 0; i < CharClass.charSetSize / 16; i++) { |
|
||||||
gen.Write("\t"); |
|
||||||
for (j = 0; j < 16; j++) |
|
||||||
gen.Write("{0,3},", startTab[16*i+j]); |
|
||||||
gen.WriteLine(); |
|
||||||
} |
|
||||||
gen.WriteLine("\t 0};"); |
|
||||||
CopyFramePart("-->initialization"); |
|
||||||
gen.WriteLine("\t\tignore = new BitArray({0});", CharClass.charSetSize); |
|
||||||
gen.Write("\t\t"); |
|
||||||
if (Tab.ignored == null) gen.Write("ignore[' '] = true;"); |
|
||||||
else { |
|
||||||
j = 0; |
|
||||||
for (i = 0; i < Tab.ignored.Count; i++) |
|
||||||
if (Tab.ignored[i]) { |
|
||||||
gen.Write("ignore[{0}] = true; ", i); |
|
||||||
if (++j % 4 == 0) { gen.WriteLine(); gen.Write("\t\t"); } |
|
||||||
} |
|
||||||
} |
|
||||||
CopyFramePart("-->comment"); |
|
||||||
Comment com = Comment.first; i = 0; |
|
||||||
while (com != null) { |
|
||||||
GenComment(com, i); |
|
||||||
com = com.next; i++; |
|
||||||
} |
|
||||||
CopyFramePart("-->literals"); GenLiterals(); |
|
||||||
CopyFramePart("-->scan1"); |
|
||||||
if (Comment.first!=null) { |
|
||||||
gen.Write("\t\tif ("); |
|
||||||
com = Comment.first; i = 0; |
|
||||||
while (com != null) { |
|
||||||
gen.Write(ChCond(com.start[0])); |
|
||||||
gen.Write(" && Comment{0}()", i); |
|
||||||
if (com.next != null) gen.Write(" ||"); |
|
||||||
com = com.next; i++; |
|
||||||
} |
|
||||||
gen.Write(") return NextToken();"); |
|
||||||
} |
|
||||||
if (hasCtxMoves) gen.WriteLine("\t\tint apx = 0;"); |
|
||||||
CopyFramePart("-->scan2"); |
|
||||||
for (State state = firstState.next; state != null; state = state.next) |
|
||||||
WriteState(state); |
|
||||||
gen.Write("\t\t\tcase "+(State.lastNr+1)+": {t.kind = 0; goto done;}"); |
|
||||||
CopyFramePart("$$$"); |
|
||||||
/* AW 12-20-02 close namespace, if it exists */ |
|
||||||
if (Tab.nsName != null && Tab.nsName.Length > 0) gen.Write("}"); |
|
||||||
gen.Close(); |
|
||||||
} |
|
||||||
|
|
||||||
public static void Init (string dir) { |
|
||||||
srcDir = dir; |
|
||||||
firstState = null; lastState = null; State.lastNr = -1; |
|
||||||
firstState = NewState(); |
|
||||||
Melted.first = null; Comment.first = null; |
|
||||||
dirtyDFA = false; |
|
||||||
hasCtxMoves = false; |
|
||||||
} |
|
||||||
|
|
||||||
} // end DFA
|
|
||||||
|
|
||||||
} // end namespace
|
|
@ -1,764 +0,0 @@ |
|||||||
using System.Collections; |
|
||||||
using System.Text; |
|
||||||
using System; |
|
||||||
using System.Reflection; |
|
||||||
|
|
||||||
namespace at.jku.ssw.Coco { |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class Parser { |
|
||||||
const int maxT = 42; |
|
||||||
|
|
||||||
const bool T = true; |
|
||||||
const bool x = false; |
|
||||||
const int minErrDist = 2; |
|
||||||
const string errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text
|
|
||||||
|
|
||||||
static Token t; // last recognized token
|
|
||||||
static Token la; // lookahead token
|
|
||||||
static int errDist = minErrDist; |
|
||||||
|
|
||||||
const int id = 0; |
|
||||||
const int str = 1; |
|
||||||
|
|
||||||
static bool genScanner; |
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/ |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void SynErr (int n) { |
|
||||||
if (errDist >= minErrDist) Errors.SynErr(la.line, la.col, n); |
|
||||||
errDist = 0; |
|
||||||
} |
|
||||||
|
|
||||||
public static void SemErr (string msg) { |
|
||||||
if (errDist >= minErrDist) Errors.Error(t.line, t.col, msg); |
|
||||||
errDist = 0; |
|
||||||
} |
|
||||||
|
|
||||||
static void Get () { |
|
||||||
for (;;) { |
|
||||||
t = la; |
|
||||||
la = Scanner.Scan(); |
|
||||||
if (la.kind <= maxT) { ++errDist; break; } /* ML return changed to break */ |
|
||||||
if (la.kind == 43) { |
|
||||||
Tab.SetDDT(la.val); |
|
||||||
} |
|
||||||
|
|
||||||
la = t; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void Expect (int n) { |
|
||||||
if (la.kind==n) Get(); else { SynErr(n); } |
|
||||||
} |
|
||||||
|
|
||||||
static bool StartOf (int s) { |
|
||||||
return set[s, la.kind]; |
|
||||||
} |
|
||||||
|
|
||||||
static void ExpectWeak (int n, int follow) { |
|
||||||
if (la.kind == n) Get(); |
|
||||||
else { |
|
||||||
SynErr(n); |
|
||||||
while (!StartOf(follow)) Get(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static bool WeakSeparator (int n, int syFol, int repFol) { |
|
||||||
bool[] s = new bool[maxT+1]; |
|
||||||
if (la.kind == n) { Get(); return true; } |
|
||||||
else if (StartOf(repFol)) return false; |
|
||||||
else { |
|
||||||
for (int i=0; i <= maxT; i++) { |
|
||||||
s[i] = set[syFol, i] || set[repFol, i] || set[0, i]; |
|
||||||
} |
|
||||||
SynErr(n); |
|
||||||
while (!s[la.kind]) Get(); |
|
||||||
return StartOf(syFol); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void Coco() { |
|
||||||
Symbol sym; Graph g; string gramName; |
|
||||||
if (la.kind == 40) { |
|
||||||
UsingDecl(out ParserGen.usingPos); |
|
||||||
} |
|
||||||
Expect(6); |
|
||||||
int gramLine = t.line; |
|
||||||
genScanner = true; |
|
||||||
bool ok = true; |
|
||||||
Tab.ignored = null; |
|
||||||
|
|
||||||
Expect(1); |
|
||||||
gramName = t.val; |
|
||||||
int beg = la.pos; |
|
||||||
|
|
||||||
while (StartOf(1)) { |
|
||||||
Get(); |
|
||||||
} |
|
||||||
Tab.semDeclPos = new Position(beg, la.pos-beg, 0); |
|
||||||
while (StartOf(2)) { |
|
||||||
Declaration(); |
|
||||||
} |
|
||||||
while (!(la.kind == 0 || la.kind == 7)) {SynErr(43); Get();} |
|
||||||
Expect(7); |
|
||||||
if (genScanner) DFA.MakeDeterministic(); |
|
||||||
Graph.DeleteNodes(); |
|
||||||
|
|
||||||
while (la.kind == 1) { |
|
||||||
Get(); |
|
||||||
sym = Symbol.Find(t.val); |
|
||||||
bool undef = sym == null; |
|
||||||
if (undef) sym = new Symbol(Node.nt, t.val, t.line); |
|
||||||
else { |
|
||||||
if (sym.typ == Node.nt) { |
|
||||||
if (sym.graph != null) SemErr("name declared twice"); |
|
||||||
} else SemErr("this symbol kind not allowed on left side of production"); |
|
||||||
sym.line = t.line; |
|
||||||
} |
|
||||||
bool noAttrs = sym.attrPos == null; |
|
||||||
sym.attrPos = null; |
|
||||||
|
|
||||||
if (la.kind == 24) { |
|
||||||
AttrDecl(sym); |
|
||||||
} |
|
||||||
if (!undef) |
|
||||||
if (noAttrs != (sym.attrPos == null)) |
|
||||||
SemErr("attribute mismatch between declaration and use of this symbol"); |
|
||||||
|
|
||||||
if (la.kind == 38) { |
|
||||||
SemText(out sym.semPos); |
|
||||||
} |
|
||||||
ExpectWeak(8, 3); |
|
||||||
Expression(out g); |
|
||||||
sym.graph = g.l; |
|
||||||
Graph.Finish(g); |
|
||||||
|
|
||||||
ExpectWeak(9, 4); |
|
||||||
} |
|
||||||
Expect(10); |
|
||||||
Expect(1); |
|
||||||
if (gramName != t.val) |
|
||||||
SemErr("name does not match grammar name"); |
|
||||||
Tab.gramSy = Symbol.Find(gramName); |
|
||||||
if (Tab.gramSy == null) |
|
||||||
SemErr("missing production for grammar name"); |
|
||||||
else { |
|
||||||
sym = Tab.gramSy; |
|
||||||
if (sym.attrPos != null) |
|
||||||
SemErr("grammar symbol must not have attributes"); |
|
||||||
} |
|
||||||
Tab.noSym = new Symbol(Node.t, "???", 0); // noSym gets highest number
|
|
||||||
Tab.SetupAnys(); |
|
||||||
Tab.RenumberPragmas(); |
|
||||||
if (Tab.ddt[2]) Node.PrintNodes(); |
|
||||||
if (Errors.count == 0) { |
|
||||||
Console.WriteLine("checking"); |
|
||||||
Tab.CompSymbolSets(); |
|
||||||
ok = ok && Tab.GrammarOk(); |
|
||||||
if (Tab.ddt[7]) Tab.XRef(); |
|
||||||
if (ok) { |
|
||||||
Console.Write("parser"); |
|
||||||
ParserGen.WriteParser(); |
|
||||||
if (genScanner) { |
|
||||||
Console.Write(" + scanner"); |
|
||||||
DFA.WriteScanner(); |
|
||||||
if (Tab.ddt[0]) DFA.PrintStates(); |
|
||||||
} |
|
||||||
Console.WriteLine(" generated"); |
|
||||||
if (Tab.ddt[8]) ParserGen.WriteStatistics(); |
|
||||||
} |
|
||||||
} |
|
||||||
if (Tab.ddt[6]) Tab.PrintSymbolTable(); |
|
||||||
|
|
||||||
Expect(9); |
|
||||||
} |
|
||||||
|
|
||||||
static void UsingDecl(out Position pos) { |
|
||||||
Expect(40); |
|
||||||
int beg = t.pos; |
|
||||||
while (StartOf(5)) { |
|
||||||
Get(); |
|
||||||
} |
|
||||||
Expect(41); |
|
||||||
int end = t.pos; |
|
||||||
while (la.kind == 40) { |
|
||||||
Get(); |
|
||||||
while (StartOf(5)) { |
|
||||||
Get(); |
|
||||||
} |
|
||||||
Expect(41); |
|
||||||
end = t.pos; |
|
||||||
} |
|
||||||
pos = new Position(beg, end - beg + 1, 0); |
|
||||||
} |
|
||||||
|
|
||||||
static void Declaration() { |
|
||||||
Graph g1, g2; bool nested = false; |
|
||||||
switch (la.kind) { |
|
||||||
case 11: { |
|
||||||
Get(); |
|
||||||
while (la.kind == 1) { |
|
||||||
SetDecl(); |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
case 12: { |
|
||||||
Get(); |
|
||||||
while (la.kind == 1 || la.kind == 3 || la.kind == 5) { |
|
||||||
TokenDecl(Node.t); |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
case 13: { |
|
||||||
Get(); |
|
||||||
while (la.kind == 1 || la.kind == 3 || la.kind == 5) { |
|
||||||
TokenDecl(Node.pr); |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
case 14: { |
|
||||||
Get(); |
|
||||||
Expect(15); |
|
||||||
TokenExpr(out g1); |
|
||||||
Expect(16); |
|
||||||
TokenExpr(out g2); |
|
||||||
if (la.kind == 17) { |
|
||||||
Get(); |
|
||||||
nested = true; |
|
||||||
} else if (StartOf(6)) { |
|
||||||
nested = false; |
|
||||||
} else SynErr(44); |
|
||||||
new Comment(g1.l, g2.l, nested); |
|
||||||
break; |
|
||||||
} |
|
||||||
case 18: { |
|
||||||
Get(); |
|
||||||
Set(out Tab.ignored); |
|
||||||
Tab.ignored[' '] = true; /* ' ' is always ignored */ |
|
||||||
if (Tab.ignored[0]) SemErr("may not ignore \'\\0\'"); |
|
||||||
break; |
|
||||||
} |
|
||||||
case 19: { |
|
||||||
Get(); |
|
||||||
Symbol.tokenNames = new Hashtable(); |
|
||||||
while (la.kind == 1 || la.kind == 3) { |
|
||||||
if (la.kind == 3) { |
|
||||||
Get(); |
|
||||||
} else { |
|
||||||
Get(); |
|
||||||
} |
|
||||||
string key = t.val; |
|
||||||
Expect(8); |
|
||||||
Expect(1); |
|
||||||
string val = t.val; Symbol.tokenNames.Add(key, val); |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
default: SynErr(45); break; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void AttrDecl(Symbol sym) { |
|
||||||
Expect(24); |
|
||||||
int beg = la.pos; int col = la.col; |
|
||||||
while (StartOf(7)) { |
|
||||||
if (la.kind == 24) { |
|
||||||
AttrDecl(sym); |
|
||||||
} else if (StartOf(8)) { |
|
||||||
Get(); |
|
||||||
} else { |
|
||||||
Get(); |
|
||||||
SemErr("bad string in semantic action"); |
|
||||||
} |
|
||||||
} |
|
||||||
Expect(25); |
|
||||||
sym.attrPos = new Position(beg, t.pos - beg, col); |
|
||||||
} |
|
||||||
|
|
||||||
static void SemText(out Position pos) { |
|
||||||
Expect(38); |
|
||||||
int beg = la.pos; int col = la.col; |
|
||||||
while (StartOf(9)) { |
|
||||||
if (StartOf(10)) { |
|
||||||
Get(); |
|
||||||
} else if (la.kind == 4) { |
|
||||||
Get(); |
|
||||||
SemErr("bad string in semantic action"); |
|
||||||
} else { |
|
||||||
Get(); |
|
||||||
SemErr("missing end of previous semantic action"); |
|
||||||
} |
|
||||||
} |
|
||||||
Expect(39); |
|
||||||
pos = new Position(beg, t.pos - beg, col); |
|
||||||
} |
|
||||||
|
|
||||||
static void Expression(out Graph g) { |
|
||||||
Graph g2; |
|
||||||
Term(out g); |
|
||||||
bool first = true; |
|
||||||
while (WeakSeparator(26,11,12) ) { |
|
||||||
Term(out g2); |
|
||||||
if (first) { Graph.MakeFirstAlt(g); first = false; } |
|
||||||
Graph.MakeAlternative(g, g2); |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void SetDecl() { |
|
||||||
BitArray s; |
|
||||||
Expect(1); |
|
||||||
string name = t.val; |
|
||||||
CharClass c = CharClass.Find(name); |
|
||||||
if (c != null) SemErr("name declared twice"); |
|
||||||
|
|
||||||
Expect(8); |
|
||||||
Set(out s); |
|
||||||
if (Sets.Elements(s) == 0) SemErr("character set must not be empty"); |
|
||||||
c = new CharClass(name, s); |
|
||||||
|
|
||||||
Expect(9); |
|
||||||
} |
|
||||||
|
|
||||||
static void TokenDecl(int typ) { |
|
||||||
string name; int kind; Symbol sym; Graph g; |
|
||||||
Sym(out name, out kind); |
|
||||||
sym = Symbol.Find(name); |
|
||||||
if (sym != null) SemErr("name declared twice"); |
|
||||||
else { |
|
||||||
sym = new Symbol(typ, name, t.line); |
|
||||||
sym.tokenKind = Symbol.classToken; |
|
||||||
} |
|
||||||
|
|
||||||
while (!(StartOf(13))) {SynErr(46); Get();} |
|
||||||
if (la.kind == 8) { |
|
||||||
Get(); |
|
||||||
TokenExpr(out g); |
|
||||||
Expect(9); |
|
||||||
if (kind != id) SemErr("a literal must not be declared with a structure"); |
|
||||||
Graph.Finish(g); |
|
||||||
DFA.ConvertToStates(g.l, sym); |
|
||||||
|
|
||||||
} else if (la.kind == 9) { |
|
||||||
Get(); |
|
||||||
if (typ != Node.rslv) SemErr("resolver is only allowed in RESOLVERS section"); |
|
||||||
} else if (StartOf(14)) { |
|
||||||
if (kind == id) genScanner = false; |
|
||||||
else DFA.MatchLiteral(sym); |
|
||||||
|
|
||||||
} else SynErr(47); |
|
||||||
if (la.kind == 38) { |
|
||||||
SemText(out sym.semPos); |
|
||||||
if (typ == Node.t) SemErr("semantic action not allowed here"); |
|
||||||
} else if (StartOf(15)) { |
|
||||||
if (typ == Node.rslv) SemErr("resolvers must have a semantic action"); |
|
||||||
} else SynErr(48); |
|
||||||
} |
|
||||||
|
|
||||||
static void TokenExpr(out Graph g) { |
|
||||||
Graph g2; |
|
||||||
TokenTerm(out g); |
|
||||||
bool first = true; |
|
||||||
while (WeakSeparator(26,16,17) ) { |
|
||||||
TokenTerm(out g2); |
|
||||||
if (first) { Graph.MakeFirstAlt(g); first = false; } |
|
||||||
Graph.MakeAlternative(g, g2); |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void Set(out BitArray s) { |
|
||||||
BitArray s2; |
|
||||||
SimSet(out s); |
|
||||||
while (la.kind == 20 || la.kind == 21) { |
|
||||||
if (la.kind == 20) { |
|
||||||
Get(); |
|
||||||
SimSet(out s2); |
|
||||||
s.Or(s2); |
|
||||||
} else { |
|
||||||
Get(); |
|
||||||
SimSet(out s2); |
|
||||||
Sets.Subtract(s, s2); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void SimSet(out BitArray s) { |
|
||||||
int n1, n2; |
|
||||||
s = new BitArray(CharClass.charSetSize); |
|
||||||
if (la.kind == 1) { |
|
||||||
Get(); |
|
||||||
CharClass c = CharClass.Find(t.val); |
|
||||||
if (c == null) SemErr("undefined name"); else s.Or(c.set); |
|
||||||
|
|
||||||
} else if (la.kind == 3) { |
|
||||||
Get(); |
|
||||||
string name = t.val; |
|
||||||
name = DFA.Unescape(name.Substring(1, name.Length-2)); |
|
||||||
foreach (char ch in name) s[ch] = true; |
|
||||||
|
|
||||||
} else if (la.kind == 5) { |
|
||||||
Char(out n1); |
|
||||||
s[n1] = true; |
|
||||||
if (la.kind == 22) { |
|
||||||
Get(); |
|
||||||
Char(out n2); |
|
||||||
for (int i = n1; i <= n2; i++) s[i] = true; |
|
||||||
} |
|
||||||
} else if (la.kind == 23) { |
|
||||||
Get(); |
|
||||||
s = new BitArray(CharClass.charSetSize, true); |
|
||||||
s[0] = false; |
|
||||||
|
|
||||||
} else SynErr(49); |
|
||||||
} |
|
||||||
|
|
||||||
static void Char(out int n) { |
|
||||||
Expect(5); |
|
||||||
string name = t.val; |
|
||||||
name = DFA.Unescape(name.Substring(1, name.Length-2)); |
|
||||||
int max = CharClass.charSetSize; |
|
||||||
if (name.Length != 1 || name[0] > max-1) SemErr("unacceptable character value"); |
|
||||||
n = name[0] % max; |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
static void Sym(out string name, out int kind) { |
|
||||||
name = "???"; kind = id; |
|
||||||
if (la.kind == 1) { |
|
||||||
Get(); |
|
||||||
kind = id; name = t.val; |
|
||||||
} else if (la.kind == 3 || la.kind == 5) { |
|
||||||
if (la.kind == 3) { |
|
||||||
Get(); |
|
||||||
name = t.val; |
|
||||||
} else { |
|
||||||
Get(); |
|
||||||
name = "\"" + t.val.Substring(1, t.val.Length-2) + "\""; |
|
||||||
} |
|
||||||
kind = str; |
|
||||||
} else SynErr(50); |
|
||||||
} |
|
||||||
|
|
||||||
static void Term(out Graph g) { |
|
||||||
Graph g2; Position pos; Node rslv = null; |
|
||||||
g = null; |
|
||||||
|
|
||||||
if (StartOf(18)) { |
|
||||||
if (la.kind == 35) { |
|
||||||
rslv = new Node(Node.rslv, null, la.line); |
|
||||||
ResolveExpr(out pos); |
|
||||||
rslv.pos = pos; |
|
||||||
g = new Graph(rslv); |
|
||||||
|
|
||||||
} |
|
||||||
Factor(out g2); |
|
||||||
if (rslv != null) Graph.MakeSequence(g, g2); |
|
||||||
else g = g2; |
|
||||||
|
|
||||||
while (StartOf(19)) { |
|
||||||
Factor(out g2); |
|
||||||
Graph.MakeSequence(g, g2); |
|
||||||
} |
|
||||||
} else if (StartOf(20)) { |
|
||||||
g = new Graph(new Node(Node.eps, null, 0)); |
|
||||||
} else SynErr(51); |
|
||||||
} |
|
||||||
|
|
||||||
static void ResolveExpr(out Position pos) { |
|
||||||
Expect(35); |
|
||||||
Expect(28); |
|
||||||
int beg = la.pos; int col = la.col; |
|
||||||
if (la.kind == 8 || la.kind == 36) { |
|
||||||
if (la.kind == 8) { |
|
||||||
Get(); |
|
||||||
} else { |
|
||||||
Get(); |
|
||||||
} |
|
||||||
CondPart(); |
|
||||||
} else if (la.kind == 28) { |
|
||||||
Get(); |
|
||||||
CondPart(); |
|
||||||
Expect(29); |
|
||||||
} else if (StartOf(21)) { |
|
||||||
Get(); |
|
||||||
CondPart(); |
|
||||||
} else SynErr(52); |
|
||||||
pos = new Position(beg, t.pos - beg, col); |
|
||||||
} |
|
||||||
|
|
||||||
static void Factor(out Graph g) { |
|
||||||
string name; int kind; Position pos; bool weak = false; |
|
||||||
g = null; |
|
||||||
|
|
||||||
switch (la.kind) { |
|
||||||
case 1: case 3: case 5: case 27: { |
|
||||||
if (la.kind == 27) { |
|
||||||
Get(); |
|
||||||
weak = true; |
|
||||||
} |
|
||||||
Sym(out name, out kind); |
|
||||||
Symbol sym = Symbol.Find(name); |
|
||||||
bool undef = sym == null; |
|
||||||
if (undef) { |
|
||||||
if (kind == id) |
|
||||||
sym = new Symbol(Node.nt, name, 0); // forward nt
|
|
||||||
else if (genScanner) { |
|
||||||
sym = new Symbol(Node.t, name, t.line); |
|
||||||
DFA.MatchLiteral(sym); |
|
||||||
} else { // undefined string in production
|
|
||||||
SemErr("undefined string in production"); |
|
||||||
sym = Tab.eofSy; // dummy
|
|
||||||
} |
|
||||||
} |
|
||||||
int typ = sym.typ; |
|
||||||
if (typ != Node.t && typ != Node.nt && typ != Node.rslv) /* ML */ |
|
||||||
SemErr("this symbol kind is not allowed in a production"); |
|
||||||
if (weak) |
|
||||||
if (typ == Node.t) typ = Node.wt; |
|
||||||
else SemErr("only terminals may be weak"); |
|
||||||
Node p = new Node(typ, sym, t.line); |
|
||||||
g = new Graph(p); |
|
||||||
|
|
||||||
if (la.kind == 24) { |
|
||||||
Attribs(p); |
|
||||||
if (kind != id) SemErr("a literal must not have attributes"); |
|
||||||
} |
|
||||||
if (undef) |
|
||||||
sym.attrPos = p.pos; // dummy
|
|
||||||
else if ((p.pos == null) != (sym.attrPos == null)) |
|
||||||
SemErr("attribute mismatch between declaration and use of this symbol"); |
|
||||||
|
|
||||||
break; |
|
||||||
} |
|
||||||
case 28: { |
|
||||||
Get(); |
|
||||||
Expression(out g); |
|
||||||
Expect(29); |
|
||||||
break; |
|
||||||
} |
|
||||||
case 30: { |
|
||||||
Get(); |
|
||||||
Expression(out g); |
|
||||||
Expect(31); |
|
||||||
Graph.MakeOption(g); |
|
||||||
break; |
|
||||||
} |
|
||||||
case 32: { |
|
||||||
Get(); |
|
||||||
Expression(out g); |
|
||||||
Expect(33); |
|
||||||
Graph.MakeIteration(g); |
|
||||||
break; |
|
||||||
} |
|
||||||
case 38: { |
|
||||||
SemText(out pos); |
|
||||||
Node p = new Node(Node.sem, null, 0); |
|
||||||
p.pos = pos; |
|
||||||
g = new Graph(p); |
|
||||||
|
|
||||||
break; |
|
||||||
} |
|
||||||
case 23: { |
|
||||||
Get(); |
|
||||||
Node p = new Node(Node.any, null, 0); // p.set is set in Tab.SetupAnys
|
|
||||||
g = new Graph(p); |
|
||||||
|
|
||||||
break; |
|
||||||
} |
|
||||||
case 34: { |
|
||||||
Get(); |
|
||||||
Node p = new Node(Node.sync, null, 0); |
|
||||||
g = new Graph(p); |
|
||||||
|
|
||||||
break; |
|
||||||
} |
|
||||||
default: SynErr(53); break; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void Attribs(Node p) |
|
||||||
{ |
|
||||||
Expect(24); |
|
||||||
int beg = la.pos; int col = la.col; |
|
||||||
while (StartOf(7)) { |
|
||||||
if (StartOf(8)) { |
|
||||||
Get(); |
|
||||||
} else { |
|
||||||
Get(); |
|
||||||
SemErr("bad string in attributes"); |
|
||||||
} |
|
||||||
} |
|
||||||
Expect(25); |
|
||||||
p.pos = new Position(beg, t.pos - beg, col); |
|
||||||
} |
|
||||||
|
|
||||||
static void CondPart() { |
|
||||||
while (StartOf(22)) { |
|
||||||
if (la.kind == 28) { |
|
||||||
Get(); |
|
||||||
CondPart(); |
|
||||||
} else { |
|
||||||
Get(); |
|
||||||
} |
|
||||||
} |
|
||||||
Expect(29); |
|
||||||
} |
|
||||||
|
|
||||||
static void TokenTerm(out Graph g) { |
|
||||||
Graph g2; |
|
||||||
TokenFactor(out g); |
|
||||||
while (StartOf(16)) { |
|
||||||
TokenFactor(out g2); |
|
||||||
Graph.MakeSequence(g, g2); |
|
||||||
} |
|
||||||
if (la.kind == 37) { |
|
||||||
Get(); |
|
||||||
Expect(28); |
|
||||||
TokenExpr(out g2); |
|
||||||
Graph.SetContextTrans(g2.l); Graph.MakeSequence(g, g2); |
|
||||||
Expect(29); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void TokenFactor(out Graph g) { |
|
||||||
string name; int kind; |
|
||||||
g = new Graph(); |
|
||||||
if (la.kind == 1 || la.kind == 3 || la.kind == 5) { |
|
||||||
Sym(out name, out kind); |
|
||||||
if (kind == id) { |
|
||||||
CharClass c = CharClass.Find(name); |
|
||||||
if (c == null) { |
|
||||||
SemErr("undefined name"); |
|
||||||
c = new CharClass(name, new BitArray(CharClass.charSetSize)); |
|
||||||
} |
|
||||||
Node p = new Node(Node.clas, null, 0); p.val = c.n; |
|
||||||
g = new Graph(p); |
|
||||||
} else g = Graph.StrToGraph(name); // str
|
|
||||||
|
|
||||||
} else if (la.kind == 28) { |
|
||||||
Get(); |
|
||||||
TokenExpr(out g); |
|
||||||
Expect(29); |
|
||||||
} else if (la.kind == 30) { |
|
||||||
Get(); |
|
||||||
TokenExpr(out g); |
|
||||||
Expect(31); |
|
||||||
Graph.MakeOption(g); |
|
||||||
} else if (la.kind == 32) { |
|
||||||
Get(); |
|
||||||
TokenExpr(out g); |
|
||||||
Expect(33); |
|
||||||
Graph.MakeIteration(g); |
|
||||||
} else SynErr(54); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void Parse() { |
|
||||||
Errors.SynErr = new ErrorCodeProc(SynErr); |
|
||||||
la = new Token(); |
|
||||||
la.val = ""; |
|
||||||
Get(); |
|
||||||
Coco(); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
static void SynErr (int line, int col, int n) { |
|
||||||
Errors.count++; |
|
||||||
string s; |
|
||||||
switch (n) { |
|
||||||
case 0: s = "EOF expected"; break; |
|
||||||
case 1: s = "ident expected"; break; |
|
||||||
case 2: s = "number expected"; break; |
|
||||||
case 3: s = "string expected"; break; |
|
||||||
case 4: s = "badString expected"; break; |
|
||||||
case 5: s = "char expected"; break; |
|
||||||
case 6: s = "\"COMPILER\" expected"; break; |
|
||||||
case 7: s = "\"PRODUCTIONS\" expected"; break; |
|
||||||
case 8: s = "\"=\" expected"; break; |
|
||||||
case 9: s = "\".\" expected"; break; |
|
||||||
case 10: s = "\"END\" expected"; break; |
|
||||||
case 11: s = "\"CHARACTERS\" expected"; break; |
|
||||||
case 12: s = "\"TOKENS\" expected"; break; |
|
||||||
case 13: s = "\"PRAGMAS\" expected"; break; |
|
||||||
case 14: s = "\"COMMENTS\" expected"; break; |
|
||||||
case 15: s = "\"FROM\" expected"; break; |
|
||||||
case 16: s = "\"TO\" expected"; break; |
|
||||||
case 17: s = "\"NESTED\" expected"; break; |
|
||||||
case 18: s = "\"IGNORE\" expected"; break; |
|
||||||
case 19: s = "\"TOKENNAMES\" expected"; break; |
|
||||||
case 20: s = "\"+\" expected"; break; |
|
||||||
case 21: s = "\"-\" expected"; break; |
|
||||||
case 22: s = "\"..\" expected"; break; |
|
||||||
case 23: s = "\"ANY\" expected"; break; |
|
||||||
case 24: s = "\"<\" expected"; break; |
|
||||||
case 25: s = "\">\" expected"; break; |
|
||||||
case 26: s = "\"|\" expected"; break; |
|
||||||
case 27: s = "\"WEAK\" expected"; break; |
|
||||||
case 28: s = "\"(\" expected"; break; |
|
||||||
case 29: s = "\")\" expected"; break; |
|
||||||
case 30: s = "\"[\" expected"; break; |
|
||||||
case 31: s = "\"]\" expected"; break; |
|
||||||
case 32: s = "\"{\" expected"; break; |
|
||||||
case 33: s = "\"}\" expected"; break; |
|
||||||
case 34: s = "\"SYNC\" expected"; break; |
|
||||||
case 35: s = "\"IF\" expected"; break; |
|
||||||
case 36: s = "\"!=\" expected"; break; |
|
||||||
case 37: s = "\"CONTEXT\" expected"; break; |
|
||||||
case 38: s = "\"(.\" expected"; break; |
|
||||||
case 39: s = "\".)\" expected"; break; |
|
||||||
case 40: s = "\"using\" expected"; break; |
|
||||||
case 41: s = "\";\" expected"; break; |
|
||||||
case 42: s = "??? expected"; break; |
|
||||||
case 43: s = "this symbol not expected in Coco"; break; |
|
||||||
case 44: s = "invalid Declaration"; break; |
|
||||||
case 45: s = "invalid Declaration"; break; |
|
||||||
case 46: s = "this symbol not expected in TokenDecl"; break; |
|
||||||
case 47: s = "invalid TokenDecl"; break; |
|
||||||
case 48: s = "invalid TokenDecl"; break; |
|
||||||
case 49: s = "invalid SimSet"; break; |
|
||||||
case 50: s = "invalid Sym"; break; |
|
||||||
case 51: s = "invalid Term"; break; |
|
||||||
case 52: s = "invalid ResolveExpr"; break; |
|
||||||
case 53: s = "invalid Factor"; break; |
|
||||||
case 54: s = "invalid TokenFactor"; break; |
|
||||||
|
|
||||||
default: s = "error " + n; break; |
|
||||||
} |
|
||||||
Console.WriteLine(errMsgFormat, line, col, s); |
|
||||||
} |
|
||||||
|
|
||||||
static bool[,] set = { |
|
||||||
{T,T,x,T, x,T,x,T, T,T,x,T, T,T,T,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x}, |
|
||||||
{x,T,T,T, T,T,T,x, T,T,T,x, x,x,x,T, T,T,x,x, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,x}, |
|
||||||
{x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x}, |
|
||||||
{T,T,x,T, x,T,x,T, T,T,x,T, T,T,T,x, x,x,T,T, x,x,x,T, x,x,T,T, T,x,T,x, T,x,T,T, x,x,T,x, x,x,x,x}, |
|
||||||
{T,T,x,T, x,T,x,T, T,T,T,T, T,T,T,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x}, |
|
||||||
{x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,T,x}, |
|
||||||
{x,x,x,x, x,x,x,T, x,x,x,T, T,T,T,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x}, |
|
||||||
{x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,x}, |
|
||||||
{x,T,T,T, x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,x}, |
|
||||||
{x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,x, T,T,T,x}, |
|
||||||
{x,T,T,T, x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,x,x, T,T,T,x}, |
|
||||||
{x,T,x,T, x,T,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,T,T, T,T,T,T, T,T,T,T, x,x,T,x, x,x,x,x}, |
|
||||||
{x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x}, |
|
||||||
{T,T,x,T, x,T,x,T, T,T,x,T, T,T,T,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x}, |
|
||||||
{x,T,x,T, x,T,x,T, x,x,x,T, T,T,T,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x}, |
|
||||||
{x,T,x,T, x,T,x,T, x,x,x,T, T,T,T,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x}, |
|
||||||
{x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,T,x, T,x,x,x, x,x,x,x, x,x,x,x}, |
|
||||||
{x,x,x,x, x,x,x,T, x,T,x,T, T,T,T,x, T,T,T,T, x,x,x,x, x,x,x,x, x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x}, |
|
||||||
{x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,T, T,x,T,x, T,x,T,T, x,x,T,x, x,x,x,x}, |
|
||||||
{x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,T, T,x,T,x, T,x,T,x, x,x,T,x, x,x,x,x}, |
|
||||||
{x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x}, |
|
||||||
{x,T,T,T, T,T,T,T, x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, x,T,T,T, T,T,T,T, x,T,T,T, T,T,T,x}, |
|
||||||
{x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,T,T, T,T,T,T, T,T,T,T, T,T,T,x} |
|
||||||
|
|
||||||
}; |
|
||||||
} // end Parser
|
|
||||||
|
|
||||||
} |
|
@ -1,120 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Reflection; |
|
||||||
|
|
||||||
-->namespace |
|
||||||
|
|
||||||
-->tokens |
|
||||||
|
|
||||||
public class Parser |
|
||||||
{ |
|
||||||
-->constants |
|
||||||
const bool T = true; |
|
||||||
const bool x = false; |
|
||||||
const int minErrDist = 2; |
|
||||||
const string errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text |
|
||||||
int errDist = minErrDist; |
|
||||||
Errors errors; |
|
||||||
Lexer lexer; |
|
||||||
|
|
||||||
public Errors Errors { |
|
||||||
get { |
|
||||||
return errors; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
-->declarations |
|
||||||
|
|
||||||
/* |
|
||||||
-->pragmas |
|
||||||
*/ |
|
||||||
void SynErr(int n) |
|
||||||
{ |
|
||||||
if (errDist >= minErrDist) { |
|
||||||
errors.SynErr(lexer.LookAhead.line, lexer.LookAhead.col, n); |
|
||||||
} |
|
||||||
errDist = 0; |
|
||||||
} |
|
||||||
|
|
||||||
public void SemErr(string msg) |
|
||||||
{ |
|
||||||
if (errDist >= minErrDist) { |
|
||||||
errors.Error(lexer.Token.line, lexer.Token.col, msg); |
|
||||||
} |
|
||||||
errDist = 0; |
|
||||||
} |
|
||||||
|
|
||||||
void Expect(int n) |
|
||||||
{ |
|
||||||
if (lexer.LookAhead.kind == n) { |
|
||||||
lexer.NextToken(); |
|
||||||
} else { |
|
||||||
SynErr(n); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
bool StartOf(int s) |
|
||||||
{ |
|
||||||
return set[s, lexer.LookAhead.kind]; |
|
||||||
} |
|
||||||
|
|
||||||
void ExpectWeak(int n, int follow) |
|
||||||
{ |
|
||||||
if (lexer.LookAhead.kind == n) { |
|
||||||
lexer.NextToken(); |
|
||||||
} else { |
|
||||||
SynErr(n); |
|
||||||
while (!StartOf(follow)) { |
|
||||||
lexer.NextToken(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
bool WeakSeparator(int n, int syFol, int repFol) |
|
||||||
{ |
|
||||||
bool[] s = new bool[maxT + 1]; |
|
||||||
|
|
||||||
if (lexer.LookAhead.kind == n) { |
|
||||||
lexer.NextToken(); |
|
||||||
return true; |
|
||||||
} else if (StartOf(repFol)) { |
|
||||||
return false; |
|
||||||
} else { |
|
||||||
for (int i = 0; i <= maxT; i++) { |
|
||||||
s[i] = set[syFol, i] || set[repFol, i] || set[0, i]; |
|
||||||
} |
|
||||||
SynErr(n); |
|
||||||
while (!s[lexer.LookAhead.kind]) { |
|
||||||
lexer.NextToken(); |
|
||||||
} |
|
||||||
return StartOf(syFol); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
-->productions |
|
||||||
|
|
||||||
public void Parse(Lexer lexer) |
|
||||||
{ |
|
||||||
this.errors = lexer.Errors; |
|
||||||
this.lexer = lexer; |
|
||||||
errors.SynErr = new ErrorCodeProc(SynErr); |
|
||||||
lexer.NextToken(); |
|
||||||
-->parseRoot |
|
||||||
} |
|
||||||
|
|
||||||
void SynErr(int line, int col, int errorNumber) |
|
||||||
{ |
|
||||||
errors.count++; |
|
||||||
string s; |
|
||||||
switch (errorNumber) { |
|
||||||
-->errors |
|
||||||
default: s = "error " + errorNumber; break; |
|
||||||
} |
|
||||||
errors.Error(line, col, s); |
|
||||||
} |
|
||||||
|
|
||||||
static bool[,] set = { |
|
||||||
-->initialization |
|
||||||
}; |
|
||||||
} // end Parser |
|
||||||
|
|
||||||
$$$ |
|
@ -1,430 +0,0 @@ |
|||||||
// ParserGen.cs Parser generator of Coco/R H.Moessenboeck, Univ. of Linz
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
using System; |
|
||||||
using System.IO; |
|
||||||
using System.Collections; |
|
||||||
using System.Text; |
|
||||||
|
|
||||||
namespace at.jku.ssw.Coco { |
|
||||||
|
|
||||||
public class ParserGen { |
|
||||||
|
|
||||||
const int maxTerm = 3; // sets of size < maxTerm are enumerated
|
|
||||||
const char CR = '\r'; |
|
||||||
const char LF = '\n'; |
|
||||||
const char TAB = '\t'; |
|
||||||
const int EOF = -1; |
|
||||||
|
|
||||||
const int tErr = 0; // error codes
|
|
||||||
const int altErr = 1; |
|
||||||
const int syncErr = 2; |
|
||||||
|
|
||||||
public static Position usingPos; // "using" definitions from the attributed grammar
|
|
||||||
|
|
||||||
static int errorNr; // highest parser error number
|
|
||||||
static Symbol curSy; // symbol whose production is currently generated
|
|
||||||
static FileStream fram; // parser frame file
|
|
||||||
static StreamWriter gen; // generated parser source file
|
|
||||||
static StringWriter err; // generated parser error messages
|
|
||||||
static string srcName; // name of attributed grammar file
|
|
||||||
static string srcDir; // directory of attributed grammar file
|
|
||||||
static ArrayList symSet = new ArrayList(); |
|
||||||
|
|
||||||
static void Indent (int n) { |
|
||||||
for (int i = 1; i <= n; i++) gen.Write('\t'); |
|
||||||
} |
|
||||||
|
|
||||||
/* AW: this replaces the method int Alternatives (Node p) */ |
|
||||||
static bool UseSwitch (Node p) { |
|
||||||
if (p.typ != Node.alt) return false; |
|
||||||
int nAlts = 0; |
|
||||||
while (p != null) { |
|
||||||
++nAlts; |
|
||||||
// must not optimize with switch-statement, if alt uses a resolver expression
|
|
||||||
if (p.sub.typ == Node.rslv) return false; |
|
||||||
p = p.down; |
|
||||||
} |
|
||||||
return nAlts > 5; |
|
||||||
} |
|
||||||
|
|
||||||
static void CopyFramePart (string stop) { |
|
||||||
char startCh = stop[0]; |
|
||||||
int endOfStopString = stop.Length-1; |
|
||||||
int ch = fram.ReadByte(); |
|
||||||
while (ch != EOF) |
|
||||||
if (ch == startCh) { |
|
||||||
int i = 0; |
|
||||||
do { |
|
||||||
if (i == endOfStopString) return; // stop[0..i] found
|
|
||||||
ch = fram.ReadByte(); i++; |
|
||||||
} while (ch == stop[i]); |
|
||||||
// stop[0..i-1] found; continue with last read character
|
|
||||||
gen.Write(stop.Substring(0, i)); |
|
||||||
} else { |
|
||||||
gen.Write((char)ch); ch = fram.ReadByte(); |
|
||||||
} |
|
||||||
Errors.Exception(" -- incomplete or corrupt parser frame file"); |
|
||||||
} |
|
||||||
|
|
||||||
static void CopySourcePart (Position pos, int indent) { |
|
||||||
// Copy text described by pos from atg to gen
|
|
||||||
int ch, nChars, i; |
|
||||||
if (pos != null) { |
|
||||||
Buffer.Pos = pos.beg; ch = Buffer.Read(); nChars = pos.len - 1; |
|
||||||
// CHANGES BY M.KRUEGER (#line pragma generation)
|
|
||||||
gen.WriteLine(); |
|
||||||
gen.WriteLine(String.Format("#line {0} \"{1}\" ", Buffer.CountLines(pos.beg) + 1, Buffer.fileName)); |
|
||||||
// EOC
|
|
||||||
Indent(indent); |
|
||||||
while (nChars >= 0) { |
|
||||||
while (ch == CR || ch == LF) { // eol is either CR or CRLF or LF
|
|
||||||
gen.WriteLine(); Indent(indent); |
|
||||||
if (ch == CR) { ch = Buffer.Read(); nChars--; } // skip CR
|
|
||||||
if (ch == LF) { ch = Buffer.Read(); nChars--; } // skip LF
|
|
||||||
for (i = 1; i <= pos.col && ch <= ' '; i++) { |
|
||||||
// skip blanks at beginning of line
|
|
||||||
ch = Buffer.Read(); nChars--; |
|
||||||
} |
|
||||||
if (i <= pos.col) pos.col = i - 1; // heading TABs => not enough blanks
|
|
||||||
if (nChars < 0) goto done; |
|
||||||
} |
|
||||||
gen.Write((char)ch); |
|
||||||
ch = Buffer.Read(); nChars--; |
|
||||||
} |
|
||||||
done: |
|
||||||
if (indent > 0) gen.WriteLine(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void GenErrorMsg (int errTyp, Symbol sym) { |
|
||||||
errorNr++; |
|
||||||
err.Write("\t\t\tcase " + errorNr + ": s = \""); |
|
||||||
switch (errTyp) { |
|
||||||
case tErr: |
|
||||||
if (sym.name[0] == '"') err.Write(DFA.Escape(sym.name) + " expected"); |
|
||||||
else err.Write(sym.name + " expected"); |
|
||||||
break; |
|
||||||
case altErr: err.Write("invalid " + sym.name); break; |
|
||||||
case syncErr: err.Write("this symbol not expected in " + sym.name); break; |
|
||||||
} |
|
||||||
err.WriteLine("\"; break;"); |
|
||||||
} |
|
||||||
|
|
||||||
static int NewCondSet (BitArray s) { |
|
||||||
for (int i = 1; i < symSet.Count; i++) // skip symSet[0] (reserved for union of SYNC sets)
|
|
||||||
if (Sets.Equals(s, (BitArray)symSet[i])) return i; |
|
||||||
symSet.Add(s.Clone()); |
|
||||||
return symSet.Count - 1; |
|
||||||
} |
|
||||||
|
|
||||||
static void GenCond (BitArray s, Node p) { |
|
||||||
if (p.typ == Node.rslv) CopySourcePart(p.pos, 0); |
|
||||||
else { |
|
||||||
GenCond(s); |
|
||||||
if (p.typ == Node.alt) { |
|
||||||
// for { ... | IF ... | ... } or [ ... | IF ... | ... ]
|
|
||||||
// generate conditions: StartOf(...) || IF
|
|
||||||
Node q = p; |
|
||||||
while (q != null) { |
|
||||||
if (q.sub.typ == Node.rslv) { |
|
||||||
gen.Write(" || "); |
|
||||||
CopySourcePart(q.sub.pos, 0); |
|
||||||
} |
|
||||||
q = q.down; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void GenCond (BitArray s) { |
|
||||||
int n = Sets.Elements(s); |
|
||||||
if (n == 0) gen.Write("false"); // should never happen
|
|
||||||
else if (n <= maxTerm) |
|
||||||
foreach (Symbol sym in Symbol.terminals) { |
|
||||||
if (s[sym.n]) { |
|
||||||
gen.Write("la.kind == {0}", sym.n); |
|
||||||
--n; |
|
||||||
if (n > 0) gen.Write(" || "); |
|
||||||
} |
|
||||||
} |
|
||||||
else gen.Write("StartOf({0})", NewCondSet(s)); |
|
||||||
} |
|
||||||
|
|
||||||
static void PutCaseLabels (BitArray s) { |
|
||||||
foreach (Symbol sym in Symbol.terminals) |
|
||||||
if (s[sym.n]) gen.Write("case {0}: ", sym.n); |
|
||||||
} |
|
||||||
|
|
||||||
static void GenCode (Node p, int indent, BitArray isChecked) { |
|
||||||
Node p2; |
|
||||||
BitArray s1, s2; |
|
||||||
while (p != null) { |
|
||||||
switch (p.typ) { |
|
||||||
case Node.nt: { |
|
||||||
Indent(indent); |
|
||||||
gen.Write(p.sym.name + "("); |
|
||||||
CopySourcePart(p.pos, 0); |
|
||||||
gen.WriteLine(");"); |
|
||||||
break; |
|
||||||
} |
|
||||||
case Node.t: { |
|
||||||
Indent(indent); |
|
||||||
// M.Krueger: changed Get() to lexer.NextToken();
|
|
||||||
if (isChecked[p.sym.n]) gen.WriteLine("lexer.NextToken();"); |
|
||||||
else gen.WriteLine("Expect({0});", p.sym.n); |
|
||||||
break; |
|
||||||
} |
|
||||||
case Node.wt: { |
|
||||||
Indent(indent); |
|
||||||
s1 = Tab.Expected(p.next, curSy); |
|
||||||
s1.Or(Tab.allSyncSets); |
|
||||||
gen.WriteLine("ExpectWeak({0}, {1});", p.sym.n, NewCondSet(s1)); |
|
||||||
break; |
|
||||||
} |
|
||||||
case Node.any: { |
|
||||||
Indent(indent); |
|
||||||
// M.Krueger: changed Get() to lexer.NextToken();
|
|
||||||
gen.WriteLine("lexer.NextToken();"); |
|
||||||
break; |
|
||||||
} |
|
||||||
case Node.eps: break; // nothing
|
|
||||||
case Node.sem: { |
|
||||||
CopySourcePart(p.pos, indent); |
|
||||||
break; |
|
||||||
} |
|
||||||
case Node.sync: { |
|
||||||
Indent(indent); |
|
||||||
GenErrorMsg(syncErr, curSy); |
|
||||||
s1 = (BitArray)p.set.Clone(); |
|
||||||
gen.Write("while (!("); GenCond(s1); gen.Write(")) {"); |
|
||||||
// M.Krueger: changed Get() to lexer.NextToken();
|
|
||||||
gen.Write("SynErr({0}); lexer.NextToken(); ", errorNr); gen.WriteLine("}"); |
|
||||||
break; |
|
||||||
} |
|
||||||
case Node.alt: { |
|
||||||
s1 = Tab.First(p); |
|
||||||
bool equal = Sets.Equals(s1, isChecked); |
|
||||||
bool useSwitch = UseSwitch(p); |
|
||||||
if (useSwitch) { Indent(indent); gen.WriteLine("switch (la.kind) {"); } |
|
||||||
p2 = p; |
|
||||||
while (p2 != null) { |
|
||||||
s1 = Tab.Expected(p2.sub, curSy, 1); |
|
||||||
Indent(indent); |
|
||||||
if (useSwitch) { PutCaseLabels(s1); gen.WriteLine("{"); } |
|
||||||
else if (p2 == p) { |
|
||||||
gen.Write("if ("); GenCond(s1, p2.sub); gen.WriteLine(") {"); |
|
||||||
} else if (p2.down == null && equal) { gen.WriteLine("} else {"); |
|
||||||
} else { |
|
||||||
gen.Write("} else if ("); GenCond(s1, p2.sub); gen.WriteLine(") {"); |
|
||||||
} |
|
||||||
s1.Or(isChecked); |
|
||||||
if (p2.sub.typ != Node.rslv) GenCode(p2.sub, indent + 1, s1); |
|
||||||
else GenCode(p2.sub.next, indent + 1, s1); |
|
||||||
if (useSwitch) { |
|
||||||
Indent(indent); gen.WriteLine("\tbreak;"); |
|
||||||
Indent(indent); gen.WriteLine("}"); |
|
||||||
} |
|
||||||
p2 = p2.down; |
|
||||||
} |
|
||||||
Indent(indent); |
|
||||||
if (equal) { |
|
||||||
gen.WriteLine("}"); |
|
||||||
} else { |
|
||||||
GenErrorMsg(altErr, curSy); |
|
||||||
if (useSwitch) { |
|
||||||
gen.WriteLine("default: SynErr({0}); break;", errorNr); |
|
||||||
Indent(indent); gen.WriteLine("}"); |
|
||||||
} else { |
|
||||||
gen.Write("} "); gen.WriteLine("else SynErr({0});", errorNr); |
|
||||||
} |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
case Node.iter: { |
|
||||||
Indent(indent); |
|
||||||
p2 = p.sub; |
|
||||||
gen.Write("while ("); |
|
||||||
if (p2.typ == Node.wt) { |
|
||||||
s1 = Tab.Expected(p2.next, curSy); |
|
||||||
s2 = Tab.Expected(p.next, curSy); |
|
||||||
gen.Write("WeakSeparator({0},{1},{2}) ", p2.sym.n, NewCondSet(s1), NewCondSet(s2)); |
|
||||||
s1 = new BitArray(Symbol.terminals.Count); // for inner structure
|
|
||||||
if (p2.up || p2.next == null) p2 = null; else p2 = p2.next; |
|
||||||
} else { |
|
||||||
s1 = Tab.First(p2); |
|
||||||
GenCond(s1, p2); |
|
||||||
} |
|
||||||
gen.WriteLine(") {"); |
|
||||||
GenCode(p2, indent + 1, s1); |
|
||||||
Indent(indent); |
|
||||||
gen.WriteLine("}"); |
|
||||||
break; |
|
||||||
} |
|
||||||
case Node.opt: |
|
||||||
if (p.sub.typ != Node.rslv) s1 = Tab.First(p.sub); |
|
||||||
else s1 = Tab.First(p.sub.next); |
|
||||||
if (!Sets.Equals(isChecked, s1)) { |
|
||||||
Indent(indent); |
|
||||||
gen.Write("if ("); GenCond(s1, p.sub); gen.WriteLine(") {"); |
|
||||||
if (p.sub.typ != Node.rslv) GenCode(p.sub, indent + 1, s1); |
|
||||||
else GenCode(p.sub.next, indent + 1, s1); |
|
||||||
Indent(indent); gen.WriteLine("}"); |
|
||||||
} else GenCode(p.sub, indent, isChecked); |
|
||||||
break; |
|
||||||
} |
|
||||||
if (p.typ != Node.eps && p.typ != Node.sem && p.typ != Node.sync) |
|
||||||
isChecked.SetAll(false); // = new BitArray(Symbol.terminals.Count);
|
|
||||||
if (p.up) break; |
|
||||||
p = p.next; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/* ML 2002-09-07 Generates the class "Tokens" * |
|
||||||
* which maps the token number to meaningfully named integer constants, * |
|
||||||
* as specified in the NAMES section. */ |
|
||||||
static void GenTokens() { |
|
||||||
if (Symbol.tokenNames != null && Symbol.tokenNames.Count > 0) { |
|
||||||
|
|
||||||
gen.WriteLine("public class Tokens {"); |
|
||||||
|
|
||||||
foreach (DictionaryEntry entry in Symbol.tokenNames) { |
|
||||||
string token = entry.Key as string; |
|
||||||
string name = entry.Value as string; |
|
||||||
if (IsCSharpKW(name)) { |
|
||||||
Parser.SemErr(name + " is a C# keyword." + |
|
||||||
"Use another name for the token " + token); |
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
Symbol sym = Symbol.Find(token); |
|
||||||
if (sym != null && (sym.typ == Node.t || sym.typ == Node.wt)) |
|
||||||
gen.WriteLine("\tpublic const int {0} = {1};", name, sym.n); |
|
||||||
} |
|
||||||
|
|
||||||
gen.WriteLine("}"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/* AW 03-01-20 to generate token name: * |
|
||||||
* a C# keyword must not be used as an identifier */ |
|
||||||
static bool IsCSharpKW (string name) { |
|
||||||
return Array.BinarySearch(csKeywords, name) >= 0; |
|
||||||
} |
|
||||||
|
|
||||||
static string[] csKeywords = new string[] { |
|
||||||
"abstract", "as", "base", "bool", "break", "byte", |
|
||||||
"case", "catch", "char", "checked", "class", "const", |
|
||||||
"continue", "decimal", "default", "delegate", "do", "double", |
|
||||||
"else", "enum", "event", "explicit", "extern", "false", |
|
||||||
"finally", "fixed", "float", "for", "foreach", "goto", |
|
||||||
"if", "implicit", "in", "int", "interface", "internal", |
|
||||||
"is", "lock", "long", "namespace", "new", "null", |
|
||||||
"object", "operator", "out", "override", "params", "private", |
|
||||||
"protected", "public", "readonly", "ref", "return", "sbyte", |
|
||||||
"sealed", "short", "sizeof", "stackalloc", "static", "string", |
|
||||||
"struct", "switch", "this", "throw", "true", "try", |
|
||||||
"typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", |
|
||||||
"using", "virtual", "void", "volatile", "while" |
|
||||||
}; |
|
||||||
|
|
||||||
static void GenCodePragmas() { |
|
||||||
foreach (Symbol sym in Symbol.pragmas) { |
|
||||||
gen.WriteLine("\t\t\t\tif (la.kind == {0}) {{", sym.n); |
|
||||||
CopySourcePart(sym.semPos, 4); |
|
||||||
gen.WriteLine("\t\t\t\t}"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void GenProductions() { |
|
||||||
foreach (Symbol sym in Symbol.nonterminals) { |
|
||||||
curSy = sym; |
|
||||||
gen.Write("\tvoid {0}(", sym.name); |
|
||||||
CopySourcePart(sym.attrPos, 0); |
|
||||||
gen.WriteLine(") {"); |
|
||||||
CopySourcePart(sym.semPos, 2); |
|
||||||
GenCode(sym.graph, 2, new BitArray(Symbol.terminals.Count)); |
|
||||||
gen.WriteLine("\t}"); gen.WriteLine(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void InitSets() { |
|
||||||
for (int i = 0; i < symSet.Count; i++) { |
|
||||||
BitArray s = (BitArray)symSet[i]; |
|
||||||
gen.Write("\t{"); |
|
||||||
int j = 0; |
|
||||||
foreach (Symbol sym in Symbol.terminals) { |
|
||||||
if (s[sym.n]) gen.Write("T,"); else gen.Write("x,"); |
|
||||||
++j; |
|
||||||
if (j%4 == 0) gen.Write(" "); |
|
||||||
} |
|
||||||
if (i == symSet.Count-1) gen.WriteLine("x}"); else gen.WriteLine("x},"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static void WriteParser () { |
|
||||||
FileStream s; |
|
||||||
symSet.Add(Tab.allSyncSets); |
|
||||||
string fr = srcDir + "Parser.frame"; |
|
||||||
if (!File.Exists(fr)) { |
|
||||||
string frameDir = Environment.GetEnvironmentVariable("crframes"); |
|
||||||
if (frameDir != null) fr = frameDir.Trim() + "\\Parser.frame"; |
|
||||||
if (!File.Exists(fr)) Errors.Exception("-- Cannot find Parser.frame"); |
|
||||||
} |
|
||||||
try { |
|
||||||
fram = new FileStream(fr, FileMode.Open, FileAccess.Read, FileShare.Read); |
|
||||||
} catch (IOException) { |
|
||||||
Errors.Exception("-- Cannot open Parser.frame."); |
|
||||||
} |
|
||||||
try { |
|
||||||
string fn = srcDir + "Parser.cs"; |
|
||||||
if (File.Exists(fn)) File.Copy(fn, fn.Replace(".cs", ".old.cs"), true); |
|
||||||
s = new FileStream(fn, FileMode.Create); |
|
||||||
gen = new StreamWriter(s); |
|
||||||
} catch (IOException) { |
|
||||||
Errors.Exception("-- Cannot generate parser file"); |
|
||||||
} |
|
||||||
err = new StringWriter(); |
|
||||||
foreach (Symbol sym in Symbol.terminals) GenErrorMsg(tErr, sym); |
|
||||||
if (usingPos != null) CopySourcePart(usingPos, 0); |
|
||||||
gen.WriteLine(); |
|
||||||
CopyFramePart("-->namespace"); |
|
||||||
/* AW open namespace, if it exists */ |
|
||||||
if (Tab.nsName != null && Tab.nsName.Length > 0) { |
|
||||||
gen.Write("namespace "); |
|
||||||
gen.Write(Tab.nsName); |
|
||||||
gen.Write(" {"); |
|
||||||
} |
|
||||||
CopyFramePart("-->tokens"); GenTokens(); /* ML 2002/09/07 write the tokenkinds */ |
|
||||||
CopyFramePart("-->constants"); |
|
||||||
gen.WriteLine("\tconst int maxT = {0};", Symbol.terminals.Count-1); |
|
||||||
CopyFramePart("-->declarations"); CopySourcePart(Tab.semDeclPos, 0); |
|
||||||
CopyFramePart("-->pragmas"); GenCodePragmas(); |
|
||||||
CopyFramePart("-->productions"); GenProductions(); |
|
||||||
CopyFramePart("-->parseRoot"); gen.WriteLine("\t\t{0}();", Tab.gramSy.name); |
|
||||||
CopyFramePart("-->errors"); gen.Write(err.ToString()); |
|
||||||
CopyFramePart("-->initialization"); InitSets(); |
|
||||||
CopyFramePart("$$$"); |
|
||||||
/* AW 2002-12-20 close namespace, if it exists */ |
|
||||||
if (Tab.nsName != null && Tab.nsName.Length > 0) gen.Write("}"); |
|
||||||
gen.Close(); |
|
||||||
} |
|
||||||
|
|
||||||
public static void WriteStatistics () { |
|
||||||
Trace.WriteLine(); |
|
||||||
Trace.WriteLine("{0} terminals", Symbol.terminals.Count); |
|
||||||
Trace.WriteLine("{0} symbols", Symbol.terminals.Count + Symbol.pragmas.Count + |
|
||||||
Symbol.nonterminals.Count); |
|
||||||
Trace.WriteLine("{0} nodes", Node.nodes.Count); |
|
||||||
Trace.WriteLine("{0} sets", symSet.Count); |
|
||||||
} |
|
||||||
|
|
||||||
public static void Init (string file, string dir) { |
|
||||||
srcName = file; |
|
||||||
srcDir = dir; |
|
||||||
errorNr = -1; |
|
||||||
usingPos = null; |
|
||||||
} |
|
||||||
|
|
||||||
} // end ParserGen
|
|
||||||
|
|
||||||
} // end namespace
|
|
@ -1,688 +0,0 @@ |
|||||||
using System; |
|
||||||
|
|
||||||
using System.IO; |
|
||||||
|
|
||||||
using System.Collections; |
|
||||||
|
|
||||||
using System.Text; |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace at.jku.ssw.Coco { |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class Token { |
|
||||||
|
|
||||||
public int kind; // token kind
|
|
||||||
|
|
||||||
public int pos; // token position in the source text (starting at 0)
|
|
||||||
|
|
||||||
public int col; // token column (starting at 0)
|
|
||||||
|
|
||||||
public int line; // token line (starting at 1)
|
|
||||||
|
|
||||||
public string val; // token value
|
|
||||||
|
|
||||||
public Token next; // AW 2003-03-07 Tokens are kept in linked list
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Token () { } |
|
||||||
|
|
||||||
public Token (int kind) { this.kind = kind; } |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class Buffer { |
|
||||||
|
|
||||||
public const int eof = '\uffff'; |
|
||||||
|
|
||||||
static byte[] buf; |
|
||||||
static int bufLen; |
|
||||||
static int pos; |
|
||||||
public static string fileName; |
|
||||||
|
|
||||||
public static int CountLines(int offset) |
|
||||||
{ |
|
||||||
int line = 0; |
|
||||||
for (int i = 0; i <= offset; ++i) { |
|
||||||
if (buf[i] == '\n') { |
|
||||||
++line; |
|
||||||
} |
|
||||||
} |
|
||||||
return line; |
|
||||||
} |
|
||||||
|
|
||||||
public static void Fill (string fileName) { |
|
||||||
Buffer.fileName = fileName; |
|
||||||
FileStream s = null; |
|
||||||
try { |
|
||||||
s = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); |
|
||||||
bufLen = (int) s.Length; |
|
||||||
buf = new byte[bufLen]; |
|
||||||
s.Read(buf, 0, bufLen); |
|
||||||
pos = 0; |
|
||||||
|
|
||||||
} catch (IOException) { |
|
||||||
|
|
||||||
Console.WriteLine("--- Cannot open file {0}", fileName); |
|
||||||
|
|
||||||
System.Environment.Exit(0); |
|
||||||
|
|
||||||
} finally { |
|
||||||
|
|
||||||
if (s != null) s.Close(); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static int Read () { |
|
||||||
|
|
||||||
if (pos < bufLen) return buf[pos++]; |
|
||||||
|
|
||||||
else return 0; |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static int Peek () { |
|
||||||
|
|
||||||
if (pos < bufLen) return buf[pos]; |
|
||||||
|
|
||||||
else return 0; |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* AW 2003-03-10 moved this from ParserGen.cs */ |
|
||||||
|
|
||||||
public static string GetString (int beg, int end) { |
|
||||||
|
|
||||||
StringBuilder s = new StringBuilder(64); |
|
||||||
|
|
||||||
int oldPos = Buffer.Pos; |
|
||||||
|
|
||||||
Buffer.Pos = beg; |
|
||||||
|
|
||||||
while (beg < end) { s.Append((char)Buffer.Read()); beg++; } |
|
||||||
|
|
||||||
Buffer.Pos = oldPos; |
|
||||||
|
|
||||||
return s.ToString(); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static int Pos { |
|
||||||
|
|
||||||
get { return pos; } |
|
||||||
|
|
||||||
set { |
|
||||||
|
|
||||||
if (value < 0) pos = 0; |
|
||||||
|
|
||||||
else if (value >= bufLen) pos = bufLen; |
|
||||||
|
|
||||||
else pos = value; |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class Scanner { |
|
||||||
|
|
||||||
const char EOF = '\0'; |
|
||||||
|
|
||||||
const char EOL = '\n'; |
|
||||||
|
|
||||||
const int maxT = 42; |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const int noSym = 42; |
|
||||||
|
|
||||||
static short[] start = { |
|
||||||
|
|
||||||
32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
||||||
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
||||||
|
|
||||||
0, 27, 11, 0, 10, 0, 0, 5, 21, 22, 0, 15, 0, 16, 14, 0, |
|
||||||
|
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 31, 18, 13, 19, 0, |
|
||||||
|
|
||||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
|
||||||
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23, 0, 24, 0, 0, |
|
||||||
|
|
||||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
|
||||||
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 25, 20, 26, 0, 0, |
|
||||||
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
||||||
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
||||||
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
||||||
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
||||||
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
||||||
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
||||||
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
||||||
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
||||||
|
|
||||||
0}; |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static Token t; // current token
|
|
||||||
|
|
||||||
static char ch; // current input character
|
|
||||||
|
|
||||||
static int pos; // column number of current character
|
|
||||||
|
|
||||||
static int line; // line number of current character
|
|
||||||
|
|
||||||
static int lineStart; // start position of current line
|
|
||||||
|
|
||||||
static int oldEols; // EOLs that appeared in a comment;
|
|
||||||
|
|
||||||
static BitArray ignore; // set of characters to be ignored by the scanner
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ML ----- begin */ |
|
||||||
|
|
||||||
static Token tokens; // the complete input token stream
|
|
||||||
|
|
||||||
static Token pt; // current peek token
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int peekCount = 0; |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static int PeekCount { get { return peekCount; } } |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void Init (String fileName) { |
|
||||||
|
|
||||||
Buffer.Fill(fileName); |
|
||||||
|
|
||||||
pos = -1; line = 1; lineStart = 0; |
|
||||||
|
|
||||||
oldEols = 0; |
|
||||||
|
|
||||||
NextCh(); |
|
||||||
|
|
||||||
ignore = new BitArray(256); |
|
||||||
|
|
||||||
ignore[9] = true; ignore[10] = true; ignore[13] = true; ignore[32] = true; |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* AW 2003-03-07 fill token list */ |
|
||||||
|
|
||||||
tokens = new Token(); // first token is a dummy
|
|
||||||
|
|
||||||
Token node = tokens; |
|
||||||
|
|
||||||
do { |
|
||||||
|
|
||||||
node.next = NextToken(); |
|
||||||
|
|
||||||
node = node.next; |
|
||||||
|
|
||||||
} while (node.kind != 0); /* AW: 0 => EOF */ |
|
||||||
|
|
||||||
t = pt = tokens; |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void NextCh() { |
|
||||||
|
|
||||||
if (oldEols > 0) { ch = EOL; oldEols--; } |
|
||||||
|
|
||||||
else { |
|
||||||
|
|
||||||
ch = (char)Buffer.Read(); pos++; |
|
||||||
|
|
||||||
// replace isolated '\r' by '\n' in order to make
|
|
||||||
|
|
||||||
// eol handling uniform across Windows, Unix and Mac
|
|
||||||
|
|
||||||
if (ch == '\r' && Buffer.Peek() != '\n') ch = EOL; |
|
||||||
|
|
||||||
else if (ch > '\u007f') ch = '?'; |
|
||||||
|
|
||||||
if (ch == EOL) { line++; lineStart = pos + 1; } |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static bool Comment0() { |
|
||||||
|
|
||||||
int level = 1, line0 = line, lineStart0 = lineStart; |
|
||||||
|
|
||||||
NextCh(); |
|
||||||
|
|
||||||
if (ch == '*') { |
|
||||||
|
|
||||||
NextCh(); |
|
||||||
|
|
||||||
for(;;) { |
|
||||||
|
|
||||||
if (ch == '*') { |
|
||||||
|
|
||||||
NextCh(); |
|
||||||
|
|
||||||
if (ch == '/') { |
|
||||||
|
|
||||||
level--; |
|
||||||
|
|
||||||
if (level == 0) { oldEols = line - line0; NextCh(); return true; } |
|
||||||
|
|
||||||
NextCh(); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
} else if (ch == '/') { |
|
||||||
|
|
||||||
NextCh(); |
|
||||||
|
|
||||||
if (ch == '*') { |
|
||||||
|
|
||||||
level++; NextCh(); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
} else if (ch == EOF) return false; |
|
||||||
|
|
||||||
else NextCh(); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
} else { |
|
||||||
|
|
||||||
if (ch==EOL) {line--; lineStart = lineStart0;} |
|
||||||
|
|
||||||
pos = pos - 2; Buffer.Pos = pos+1; NextCh(); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
return false; |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void CheckLiteral() { |
|
||||||
|
|
||||||
switch (t.val) { |
|
||||||
|
|
||||||
case "COMPILER": t.kind = 6; break; |
|
||||||
|
|
||||||
case "PRODUCTIONS": t.kind = 7; break; |
|
||||||
|
|
||||||
case "END": t.kind = 10; break; |
|
||||||
|
|
||||||
case "CHARACTERS": t.kind = 11; break; |
|
||||||
|
|
||||||
case "TOKENS": t.kind = 12; break; |
|
||||||
|
|
||||||
case "PRAGMAS": t.kind = 13; break; |
|
||||||
|
|
||||||
case "COMMENTS": t.kind = 14; break; |
|
||||||
|
|
||||||
case "FROM": t.kind = 15; break; |
|
||||||
|
|
||||||
case "TO": t.kind = 16; break; |
|
||||||
|
|
||||||
case "NESTED": t.kind = 17; break; |
|
||||||
|
|
||||||
case "IGNORE": t.kind = 18; break; |
|
||||||
|
|
||||||
case "TOKENNAMES": t.kind = 19; break; |
|
||||||
|
|
||||||
case "ANY": t.kind = 23; break; |
|
||||||
|
|
||||||
case "WEAK": t.kind = 27; break; |
|
||||||
|
|
||||||
case "SYNC": t.kind = 34; break; |
|
||||||
|
|
||||||
case "IF": t.kind = 35; break; |
|
||||||
|
|
||||||
case "CONTEXT": t.kind = 37; break; |
|
||||||
|
|
||||||
case "using": t.kind = 40; break; |
|
||||||
|
|
||||||
default: break; |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* AW Scan() renamed to NextToken() */ |
|
||||||
|
|
||||||
static Token NextToken() { |
|
||||||
|
|
||||||
while (ignore[ch]) NextCh(); |
|
||||||
|
|
||||||
if (ch == '/' && Comment0()) return NextToken(); |
|
||||||
|
|
||||||
t = new Token(); |
|
||||||
|
|
||||||
t.pos = pos; t.col = pos - lineStart + 1; t.line = line; |
|
||||||
|
|
||||||
int state = start[ch]; |
|
||||||
|
|
||||||
StringBuilder buf = new StringBuilder(16); |
|
||||||
|
|
||||||
buf.Append(ch); NextCh(); |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
switch (state) { |
|
||||||
|
|
||||||
case 0: { t.kind = noSym; goto done; } // NextCh already done
|
|
||||||
|
|
||||||
case 1: |
|
||||||
|
|
||||||
if ((ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')) {buf.Append(ch); NextCh(); goto case 1;} |
|
||||||
|
|
||||||
else {t.kind = 1; t.val = buf.ToString(); CheckLiteral(); return t;} |
|
||||||
|
|
||||||
case 2: |
|
||||||
|
|
||||||
if ((ch >= '0' && ch <= '9')) {buf.Append(ch); NextCh(); goto case 2;} |
|
||||||
|
|
||||||
else {t.kind = 2; goto done;} |
|
||||||
|
|
||||||
case 3: |
|
||||||
|
|
||||||
{t.kind = 3; goto done;} |
|
||||||
|
|
||||||
case 4: |
|
||||||
|
|
||||||
{t.kind = 4; goto done;} |
|
||||||
|
|
||||||
case 5: |
|
||||||
|
|
||||||
if ((ch >= 1 && ch <= 9 || ch >= 11 && ch <= 12 || ch >= 14 && ch <= '&' || ch >= '(' && ch <= '[' || ch >= ']')) {buf.Append(ch); NextCh(); goto case 6;} |
|
||||||
|
|
||||||
else if (ch == 92) {buf.Append(ch); NextCh(); goto case 7;} |
|
||||||
|
|
||||||
else {t.kind = noSym; goto done;} |
|
||||||
|
|
||||||
case 6: |
|
||||||
|
|
||||||
if (ch == 39) {buf.Append(ch); NextCh(); goto case 9;} |
|
||||||
|
|
||||||
else {t.kind = noSym; goto done;} |
|
||||||
|
|
||||||
case 7: |
|
||||||
|
|
||||||
if ((ch >= ' ' && ch <= '~')) {buf.Append(ch); NextCh(); goto case 8;} |
|
||||||
|
|
||||||
else {t.kind = noSym; goto done;} |
|
||||||
|
|
||||||
case 8: |
|
||||||
|
|
||||||
if ((ch >= '0' && ch <= '9' || ch >= 'a' && ch <= 'f')) {buf.Append(ch); NextCh(); goto case 8;} |
|
||||||
|
|
||||||
else if (ch == 39) {buf.Append(ch); NextCh(); goto case 9;} |
|
||||||
|
|
||||||
else {t.kind = noSym; goto done;} |
|
||||||
|
|
||||||
case 9: |
|
||||||
|
|
||||||
{t.kind = 5; goto done;} |
|
||||||
|
|
||||||
case 10: |
|
||||||
|
|
||||||
if ((ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')) {buf.Append(ch); NextCh(); goto case 10;} |
|
||||||
|
|
||||||
else {t.kind = 43; goto done;} |
|
||||||
|
|
||||||
case 11: |
|
||||||
|
|
||||||
if ((ch >= 1 && ch <= 9 || ch >= 11 && ch <= 12 || ch >= 14 && ch <= '!' || ch >= '#' && ch <= '[' || ch >= ']')) {buf.Append(ch); NextCh(); goto case 11;} |
|
||||||
|
|
||||||
else if ((ch == 10 || ch == 13)) {buf.Append(ch); NextCh(); goto case 4;} |
|
||||||
|
|
||||||
else if (ch == '"') {buf.Append(ch); NextCh(); goto case 3;} |
|
||||||
|
|
||||||
else if (ch == 92) {buf.Append(ch); NextCh(); goto case 12;} |
|
||||||
|
|
||||||
else {t.kind = noSym; goto done;} |
|
||||||
|
|
||||||
case 12: |
|
||||||
|
|
||||||
if ((ch >= ' ' && ch <= '~')) {buf.Append(ch); NextCh(); goto case 11;} |
|
||||||
|
|
||||||
else {t.kind = noSym; goto done;} |
|
||||||
|
|
||||||
case 13: |
|
||||||
|
|
||||||
{t.kind = 8; goto done;} |
|
||||||
|
|
||||||
case 14: |
|
||||||
|
|
||||||
if (ch == '.') {buf.Append(ch); NextCh(); goto case 17;} |
|
||||||
|
|
||||||
else if (ch == ')') {buf.Append(ch); NextCh(); goto case 30;} |
|
||||||
|
|
||||||
else {t.kind = 9; goto done;} |
|
||||||
|
|
||||||
case 15: |
|
||||||
|
|
||||||
{t.kind = 20; goto done;} |
|
||||||
|
|
||||||
case 16: |
|
||||||
|
|
||||||
{t.kind = 21; goto done;} |
|
||||||
|
|
||||||
case 17: |
|
||||||
|
|
||||||
{t.kind = 22; goto done;} |
|
||||||
|
|
||||||
case 18: |
|
||||||
|
|
||||||
{t.kind = 24; goto done;} |
|
||||||
|
|
||||||
case 19: |
|
||||||
|
|
||||||
{t.kind = 25; goto done;} |
|
||||||
|
|
||||||
case 20: |
|
||||||
|
|
||||||
{t.kind = 26; goto done;} |
|
||||||
|
|
||||||
case 21: |
|
||||||
|
|
||||||
if (ch == '.') {buf.Append(ch); NextCh(); goto case 29;} |
|
||||||
|
|
||||||
else {t.kind = 28; goto done;} |
|
||||||
|
|
||||||
case 22: |
|
||||||
|
|
||||||
{t.kind = 29; goto done;} |
|
||||||
|
|
||||||
case 23: |
|
||||||
|
|
||||||
{t.kind = 30; goto done;} |
|
||||||
|
|
||||||
case 24: |
|
||||||
|
|
||||||
{t.kind = 31; goto done;} |
|
||||||
|
|
||||||
case 25: |
|
||||||
|
|
||||||
{t.kind = 32; goto done;} |
|
||||||
|
|
||||||
case 26: |
|
||||||
|
|
||||||
{t.kind = 33; goto done;} |
|
||||||
|
|
||||||
case 27: |
|
||||||
|
|
||||||
if (ch == '=') {buf.Append(ch); NextCh(); goto case 28;} |
|
||||||
|
|
||||||
else {t.kind = noSym; goto done;} |
|
||||||
|
|
||||||
case 28: |
|
||||||
|
|
||||||
{t.kind = 36; goto done;} |
|
||||||
|
|
||||||
case 29: |
|
||||||
|
|
||||||
{t.kind = 38; goto done;} |
|
||||||
|
|
||||||
case 30: |
|
||||||
|
|
||||||
{t.kind = 39; goto done;} |
|
||||||
|
|
||||||
case 31: |
|
||||||
|
|
||||||
{t.kind = 41; goto done;} |
|
||||||
|
|
||||||
case 32: {t.kind = 0; goto done;} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
done: |
|
||||||
|
|
||||||
t.val = buf.ToString(); |
|
||||||
|
|
||||||
return t; |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* AW 2003-03-07 get the next token, move on and synch peek token with current */ |
|
||||||
|
|
||||||
public static Token Scan () { |
|
||||||
|
|
||||||
t = pt = t.next; |
|
||||||
|
|
||||||
return t; |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* AW 2003-03-07 get the next token, ignore pragmas */ |
|
||||||
|
|
||||||
public static Token Peek () { |
|
||||||
|
|
||||||
do { // skip pragmas while peeking
|
|
||||||
|
|
||||||
pt = pt.next; |
|
||||||
|
|
||||||
} while (pt != null && pt.kind > maxT); |
|
||||||
|
|
||||||
return pt; |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* AW 2003-03-11 to make sure peek start at current scan position */ |
|
||||||
|
|
||||||
public static void StartPeek () { pt = t; } |
|
||||||
|
|
||||||
} // end Scanner
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public delegate void ErrorCodeProc (int line, int col, int n); |
|
||||||
|
|
||||||
public delegate void ErrorMsgProc (int line, int col, string msg); |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class Errors { |
|
||||||
|
|
||||||
public static int count = 0; // number of errors detected
|
|
||||||
|
|
||||||
public static ErrorCodeProc SynErr = new ErrorCodeProc(DefaultCodeError); // syntactic errors
|
|
||||||
|
|
||||||
public static ErrorCodeProc SemErr = new ErrorCodeProc(DefaultCodeError); // semantic errors
|
|
||||||
|
|
||||||
public static ErrorMsgProc Error = new ErrorMsgProc(DefaultMsgError); // user defined string based errors
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void Exception (string s) { |
|
||||||
|
|
||||||
Console.WriteLine(s); |
|
||||||
|
|
||||||
System.Environment.Exit(0); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void DefaultCodeError (int line, int col, int n) { |
|
||||||
|
|
||||||
Console.WriteLine("-- line {0} col {1}: error {2}", line, col, n); |
|
||||||
|
|
||||||
count++; |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void DefaultMsgError (int line, int col, string s) { |
|
||||||
|
|
||||||
Console.WriteLine("-- line {0} col {1}: {2}", line, col, s); |
|
||||||
|
|
||||||
count++; |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
} // Errors
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} |
|
@ -1,222 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Drawing; |
|
||||||
using System.IO; |
|
||||||
using System.Collections; |
|
||||||
using System.Text; |
|
||||||
|
|
||||||
-->namespace |
|
||||||
|
|
||||||
public class Token { |
|
||||||
public int kind; // token kind |
|
||||||
public int pos; // token position in the source text (starting at 0) |
|
||||||
public int col; // token column (starting at 0) |
|
||||||
public int line; // token line (starting at 1) |
|
||||||
public string val; // token value |
|
||||||
public Token next; // AW 2003-03-07 Tokens are kept in linked list |
|
||||||
|
|
||||||
public Point Location { |
|
||||||
get { |
|
||||||
return new Point(line, col); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public Token () { } |
|
||||||
public Token (int kind) { this.kind = kind; } |
|
||||||
} |
|
||||||
|
|
||||||
public class Buffer { |
|
||||||
public const int eof = '\uffff'; |
|
||||||
|
|
||||||
static byte[] buf; |
|
||||||
static int bufLen; |
|
||||||
static int pos; |
|
||||||
|
|
||||||
public static void Fill (string fileName) { |
|
||||||
FileStream s = null; |
|
||||||
try { |
|
||||||
s = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); |
|
||||||
Fill(s); |
|
||||||
} catch (IOException) { |
|
||||||
Console.WriteLine("--- Cannot open file {0}", fileName); |
|
||||||
System.Environment.Exit(0); |
|
||||||
} finally { |
|
||||||
if (s != null) s.Close(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static void Fill (Stream s) { |
|
||||||
bufLen = (int) s.Length; |
|
||||||
buf = new byte[bufLen]; |
|
||||||
s.Read(buf, 0, bufLen); |
|
||||||
pos = 0; |
|
||||||
} |
|
||||||
|
|
||||||
public static int Read () { |
|
||||||
if (pos < bufLen) return buf[pos++]; |
|
||||||
else return 0; |
|
||||||
} |
|
||||||
|
|
||||||
public static int Peek () { |
|
||||||
if (pos < bufLen) return buf[pos]; |
|
||||||
else return 0; |
|
||||||
} |
|
||||||
|
|
||||||
/* AW 2003-03-10 moved this from ParserGen.cs */ |
|
||||||
public static string GetString (int beg, int end) { |
|
||||||
StringBuilder s = new StringBuilder(64); |
|
||||||
int oldPos = Buffer.Pos; |
|
||||||
Buffer.Pos = beg; |
|
||||||
while (beg < end) { s.Append((char)Buffer.Read()); beg++; } |
|
||||||
Buffer.Pos = oldPos; |
|
||||||
return s.ToString(); |
|
||||||
} |
|
||||||
|
|
||||||
public static int Pos { |
|
||||||
get { return pos; } |
|
||||||
set { |
|
||||||
if (value < 0) pos = 0; |
|
||||||
else if (value >= bufLen) pos = bufLen; |
|
||||||
else pos = value; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public class Scanner { |
|
||||||
const char EOF = '\0'; |
|
||||||
const char EOL = '\n'; |
|
||||||
const char CR = '\n'; |
|
||||||
|
|
||||||
-->constants |
|
||||||
|
|
||||||
-->declarations |
|
||||||
|
|
||||||
static Token t; // current token |
|
||||||
static char ch; // current input character |
|
||||||
static int pos; // column number of current character |
|
||||||
static int line; // line number of current character |
|
||||||
static int lineStart; // start position of current line |
|
||||||
static int oldEols; // EOLs that appeared in a comment; |
|
||||||
static BitArray ignore; // set of characters to be ignored by the scanner |
|
||||||
|
|
||||||
/* ML ----- begin */ |
|
||||||
static Token tokens; // the complete input token stream |
|
||||||
static Token pt; // current peek token |
|
||||||
|
|
||||||
static int peekCount = 0; |
|
||||||
|
|
||||||
public static int PeekCount { get { return peekCount; } } |
|
||||||
|
|
||||||
static void Init() |
|
||||||
{ |
|
||||||
pos = -1; line = 1; lineStart = 0; |
|
||||||
oldEols = 0; |
|
||||||
NextCh(); |
|
||||||
-->initialization |
|
||||||
|
|
||||||
/* AW 2003-03-07 fill token list */ |
|
||||||
tokens = new Token(); // first token is a dummy |
|
||||||
Token node = tokens; |
|
||||||
do { |
|
||||||
node.next = NextToken(); |
|
||||||
node = node.next; |
|
||||||
} while (node.kind != 0); /* AW: 0 => EOF */ |
|
||||||
t = pt = tokens; |
|
||||||
} |
|
||||||
|
|
||||||
public static void Init(String fileName) { |
|
||||||
Buffer.Fill(fileName); |
|
||||||
Init(); |
|
||||||
} |
|
||||||
|
|
||||||
public static void Init(Stream s) { |
|
||||||
Buffer.Fill(s); |
|
||||||
Init(); |
|
||||||
} |
|
||||||
|
|
||||||
static void NextCh() { |
|
||||||
if (oldEols > 0) { ch = EOL; oldEols--; } |
|
||||||
else { |
|
||||||
ch = (char)Buffer.Read(); pos++; |
|
||||||
// replace isolated '\r' by '\n' in order to make |
|
||||||
// eol handling uniform across Windows, Unix and Mac |
|
||||||
if (ch == '\r' && Buffer.Peek() != '\n') ch = EOL; |
|
||||||
else if (ch > '\u007f') ch = '?'; |
|
||||||
if (ch == EOL) { line++; lineStart = pos + 1; } |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
-->comment |
|
||||||
|
|
||||||
static void CheckLiteral() { |
|
||||||
switch (t.val) { |
|
||||||
-->literals |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/* AW Scan() renamed to NextToken() */ |
|
||||||
static Token NextToken() { |
|
||||||
while (ignore[ch]) NextCh(); |
|
||||||
-->scan1 |
|
||||||
t = new Token(); |
|
||||||
t.pos = pos; t.col = pos - lineStart + 1; t.line = line; |
|
||||||
int state = start[ch]; |
|
||||||
StringBuilder buf = new StringBuilder(16); |
|
||||||
buf.Append(ch); NextCh(); |
|
||||||
|
|
||||||
switch (state) { |
|
||||||
case 0: { t.kind = noSym; goto done; } // NextCh already done |
|
||||||
-->scan2 |
|
||||||
} |
|
||||||
done: |
|
||||||
t.val = buf.ToString(); |
|
||||||
return t; |
|
||||||
} |
|
||||||
|
|
||||||
/* AW 2003-03-07 get the next token, move on and synch peek token with current */ |
|
||||||
public static Token Scan () { |
|
||||||
t = pt = t.next; |
|
||||||
return t; |
|
||||||
} |
|
||||||
|
|
||||||
/* AW 2003-03-07 get the next token, ignore pragmas */ |
|
||||||
public static Token Peek () { |
|
||||||
do { // skip pragmas while peeking |
|
||||||
pt = pt.next; |
|
||||||
} while (pt != null && pt.kind > maxT); |
|
||||||
return pt; |
|
||||||
} |
|
||||||
|
|
||||||
/* AW 2003-03-11 to make sure peek start at current scan position */ |
|
||||||
public static void StartPeek () { pt = t; } |
|
||||||
} // end Scanner |
|
||||||
|
|
||||||
|
|
||||||
public delegate void ErrorCodeProc (int line, int col, int n); |
|
||||||
public delegate void ErrorMsgProc (int line, int col, string msg); |
|
||||||
|
|
||||||
public class Errors { |
|
||||||
public static int count = 0; // number of errors detected |
|
||||||
public static ErrorCodeProc SynErr = new ErrorCodeProc(DefaultCodeError); // syntactic errors |
|
||||||
public static ErrorCodeProc SemErr = new ErrorCodeProc(DefaultCodeError); // semantic errors |
|
||||||
public static ErrorMsgProc Error = new ErrorMsgProc(DefaultMsgError); // user defined string based errors |
|
||||||
public static StringBuilder errorText = new StringBuilder(); |
|
||||||
|
|
||||||
public static void Exception (string s) { |
|
||||||
Console.WriteLine(s); |
|
||||||
System.Environment.Exit(0); |
|
||||||
} |
|
||||||
|
|
||||||
static void DefaultCodeError (int line, int col, int n) { |
|
||||||
errorText.Append(String.Format("-- line {0} col {1}: error {2}", line, col, n)); |
|
||||||
errorText.Append("\n"); |
|
||||||
count++; |
|
||||||
} |
|
||||||
|
|
||||||
static void DefaultMsgError (int line, int col, string s) { |
|
||||||
errorText.Append(String.Format("-- line {0} col {1}: {2}", line, col, s)); |
|
||||||
errorText.Append("\n"); |
|
||||||
count++; |
|
||||||
} |
|
||||||
} // Errors |
|
||||||
|
|
||||||
$$$ |
|
@ -1,59 +0,0 @@ |
|||||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|
||||||
<PropertyGroup> |
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
|
||||||
<SchemaVersion>2.0</SchemaVersion> |
|
||||||
<ProjectGuid>{47D8A4A2-BBD9-4E24-85DC-A287383F7C42}</ProjectGuid> |
|
||||||
<RootNamespace>NewProject</RootNamespace> |
|
||||||
<AssemblyName>SharpCoco</AssemblyName> |
|
||||||
<OutputType>Exe</OutputType> |
|
||||||
<WarningLevel>4</WarningLevel> |
|
||||||
<RunPostBuildEvent>OnSuccessfulBuild</RunPostBuildEvent> |
|
||||||
<NoStdLib>False</NoStdLib> |
|
||||||
</PropertyGroup> |
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
|
||||||
<DebugSymbols>true</DebugSymbols> |
|
||||||
<Optimize>True</Optimize> |
|
||||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks> |
|
||||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> |
|
||||||
<OutputPath>..\bin\Debug\</OutputPath> |
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors> |
|
||||||
<DebugType>Full</DebugType> |
|
||||||
</PropertyGroup> |
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
|
||||||
<DebugSymbols>True</DebugSymbols> |
|
||||||
<Optimize>True</Optimize> |
|
||||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks> |
|
||||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> |
|
||||||
<OutputPath>..\bin\Release\</OutputPath> |
|
||||||
<TreatWarningsAsErrors>True</TreatWarningsAsErrors> |
|
||||||
</PropertyGroup> |
|
||||||
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' "> |
|
||||||
<RegisterForComInterop>False</RegisterForComInterop> |
|
||||||
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies> |
|
||||||
<BaseAddress>4194304</BaseAddress> |
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget> |
|
||||||
<FileAlignment>4096</FileAlignment> |
|
||||||
</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> |
|
@ -1,5 +0,0 @@ |
|||||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
|
||||||
<StartArguments>CS.ATG</StartArguments> |
|
||||||
</PropertyGroup> |
|
||||||
</Project> |
|
File diff suppressed because it is too large
Load Diff
@ -1,37 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.IO; |
|
||||||
|
|
||||||
namespace at.jku.ssw.Coco { |
|
||||||
|
|
||||||
class Trace { |
|
||||||
const string FILENAME = "trace.txt"; |
|
||||||
static StreamWriter trace; |
|
||||||
|
|
||||||
public static void Init (String dir) { |
|
||||||
FileStream s; |
|
||||||
try { |
|
||||||
s = new FileStream(dir + FILENAME, FileMode.Create); /* AW use FILENAME */ |
|
||||||
trace = new StreamWriter(s); |
|
||||||
} catch (IOException) { |
|
||||||
Errors.Exception("-- could not open trace file"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static void Write (string s) { trace.Write(s); } |
|
||||||
|
|
||||||
public static void Write (string s, params object[] args) { |
|
||||||
trace.Write(s, args); |
|
||||||
} |
|
||||||
|
|
||||||
public static void WriteLine (string s) { trace.WriteLine(s); } |
|
||||||
|
|
||||||
public static void WriteLine (string s, params object[] args) { |
|
||||||
trace.WriteLine(s, args); |
|
||||||
} |
|
||||||
|
|
||||||
public static void WriteLine () { trace.WriteLine(); } |
|
||||||
|
|
||||||
public static void Close () { trace.Close(); } |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
Loading…
Reference in new issue