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