Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@1977 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
21 changed files with 2 additions and 11304 deletions
Binary file not shown.
@ -1,55 +0,0 @@
@@ -1,55 +0,0 @@
|
||||
-->begin |
||||
/* |
||||
Parser.frame file for NRefactory. |
||||
*/ |
||||
using System; |
||||
using System.Reflection; |
||||
|
||||
-->namespace |
||||
|
||||
|
||||
internal class Parser : AbstractParser |
||||
{ |
||||
-->constants |
||||
const bool T = true; |
||||
const bool x = false; |
||||
|
||||
-->declarations |
||||
|
||||
/* |
||||
-->pragmas |
||||
*/ |
||||
|
||||
-->productions |
||||
public Parser(ILexer lexer) : base(lexer) |
||||
{ |
||||
} |
||||
|
||||
public override void Parse() |
||||
{ |
||||
-->parseRoot |
||||
} |
||||
|
||||
private bool StartOf(int s) |
||||
{ |
||||
return set[s, lexer.LookAhead.kind]; |
||||
} |
||||
|
||||
static bool[,] set = { |
||||
-->initialization |
||||
}; |
||||
|
||||
protected override void SynErr(int line, int col, int errorNumber) |
||||
{ |
||||
errors.count++; |
||||
string s; |
||||
switch (errorNumber) { |
||||
-->errors |
||||
default: s = "error " + errorNumber; break; |
||||
} |
||||
this.Errors.Error(line, col, s); |
||||
} |
||||
|
||||
} // end Parser |
||||
|
||||
$$$ |
||||
@ -1,50 +0,0 @@
@@ -1,50 +0,0 @@
|
||||
/* |
||||
Parser.frame file for NRefactory. |
||||
*/ |
||||
using System; |
||||
using System.Reflection; |
||||
|
||||
-->namespace |
||||
|
||||
-->tokens |
||||
|
||||
partial class Parser : AbstractParser |
||||
{ |
||||
-->constants |
||||
const bool T = true; |
||||
const bool x = false; |
||||
|
||||
-->declarations |
||||
|
||||
/* |
||||
-->pragmas |
||||
*/ |
||||
|
||||
-->productions |
||||
|
||||
public override void Parse() |
||||
{ |
||||
-->parseRoot |
||||
} |
||||
|
||||
protected override void SynErr(int line, int col, int errorNumber) |
||||
{ |
||||
string s; |
||||
switch (errorNumber) { |
||||
-->errors |
||||
default: s = "error " + errorNumber; break; |
||||
} |
||||
this.Errors.Error(line, col, s); |
||||
} |
||||
|
||||
private bool StartOf(int s) |
||||
{ |
||||
return set[s, lexer.LookAhead.kind]; |
||||
} |
||||
|
||||
static bool[,] set = { |
||||
-->initialization |
||||
}; |
||||
} // end Parser |
||||
|
||||
$$$ |
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@ -1,14 +0,0 @@
@@ -1,14 +0,0 @@
|
||||
Modified version of Coco/R |
||||
|
||||
The original version can be found at: |
||||
http://www.ssw.uni-linz.ac.at/Research/Projects/Coco/CSharp/ |
||||
|
||||
Changes |
||||
|
||||
+ Added #line pragmas for the generated parser |
||||
+ Now Coco uses more enums than ints... |
||||
+ no static method generation (now all is public) |
||||
+ Error & Scanner are now fields inside the parser, no more static |
||||
calling |
||||
|
||||
Mike |
||||
@ -1,32 +0,0 @@
@@ -1,32 +0,0 @@
|
||||
using System.Reflection; |
||||
using System.Runtime.CompilerServices; |
||||
|
||||
// Information about this assembly is defined by the following
|
||||
// attributes.
|
||||
//
|
||||
// change them to the information which is associated with the assembly
|
||||
// you compile.
|
||||
|
||||
[assembly: AssemblyTitle("")] |
||||
[assembly: AssemblyDescription("")] |
||||
[assembly: AssemblyConfiguration("")] |
||||
[assembly: AssemblyCompany("")] |
||||
[assembly: AssemblyProduct("")] |
||||
[assembly: AssemblyCopyright("")] |
||||
[assembly: AssemblyTrademark("")] |
||||
[assembly: AssemblyCulture("")] |
||||
|
||||
// The assembly version has following format :
|
||||
//
|
||||
// Major.Minor.Build.Revision
|
||||
//
|
||||
// You can specify all values by your own or you can build default build and revision
|
||||
// numbers with the '*' character (the default):
|
||||
|
||||
[assembly: AssemblyVersion("2.0.0.1")] |
||||
|
||||
// The following attributes specify the key for the sign of your assembly. See the
|
||||
// .NET Framework documentation for more information about signing.
|
||||
// This is not required, if you don't want signing let these attributes like they're.
|
||||
[assembly: AssemblyDelaySign(false)] |
||||
[assembly: AssemblyKeyFile("")] |
||||
@ -1,461 +0,0 @@
@@ -1,461 +0,0 @@
|
||||
/*------------------------------------------------------------------------- |
||||
Coco.ATG -- Attributed Grammar |
||||
Compiler Generator Coco/R, |
||||
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz |
||||
extended by M. Loeberbauer & A. Woess, Univ. of Linz |
||||
with improvements by Pat Terry, Rhodes University |
||||
|
||||
This program is free software; you can redistribute it and/or modify it |
||||
under the terms of the GNU General Public License as published by the |
||||
Free Software Foundation; either version 2, or (at your option) any |
||||
later version. |
||||
|
||||
This program is distributed in the hope that it will be useful, but |
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
||||
for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License along |
||||
with this program; if not, write to the Free Software Foundation, Inc., |
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
||||
|
||||
As an exception, it is allowed to write an extension of Coco/R that is |
||||
used as a plugin in non-free software. |
||||
|
||||
If not otherwise stated, any source code generated by Coco/R (other than |
||||
Coco/R itself) does not fall under the GNU General Public License. |
||||
-------------------------------------------------------------------------*/ |
||||
/*------------------------------------------------------------------------- |
||||
compile with: |
||||
Coco Coco.ATG -namespace at.jku.ssw.Coco |
||||
-------------------------------------------------------------------------*/ |
||||
|
||||
using System.Collections; |
||||
|
||||
COMPILER Coco |
||||
|
||||
const int id = 0; |
||||
const int str = 1; |
||||
|
||||
static bool genScanner; |
||||
static string tokenString; // used in declarations of literal tokens |
||||
static string noString = "-none-"; // used in declarations of literal tokens |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
CHARACTERS |
||||
letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz". |
||||
digit = "0123456789". |
||||
cr = '\r'. |
||||
lf = '\n'. |
||||
tab = '\t'. |
||||
stringCh = ANY - '"' - '\\' - cr - lf. |
||||
charCh = ANY - '\'' - '\\' - cr - lf. |
||||
printable = '\u0020' .. '\u007e'. |
||||
hex = "0123456789abcdef". |
||||
|
||||
TOKENS |
||||
ident = letter { letter | digit }. |
||||
number = digit { digit }. |
||||
string = '"' { stringCh | '\\' printable } '"'. |
||||
badString = '"' { stringCh | '\\' printable } (cr | lf). |
||||
char = '\'' ( charCh | '\\' printable { hex } ) '\''. |
||||
|
||||
PRAGMAS |
||||
ddtSym = '$' { digit | letter }. (. Tab.SetDDT(la.val); .) |
||||
|
||||
COMMENTS FROM "/*" TO "*/" NESTED |
||||
|
||||
IGNORE cr + lf + tab |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
PRODUCTIONS |
||||
|
||||
Coco (. Symbol sym; Graph g, g1, g2; string gramName; .) |
||||
= |
||||
[ UsingDecl<out ParserGen.usingPos> ] |
||||
|
||||
"COMPILER" (. genScanner = true; Tab.ignored = null; .) |
||||
ident (. gramName = t.val; |
||||
int beg = la.pos; |
||||
.) |
||||
{ ANY } (. Tab.semDeclPos = new Position(beg, la.pos-beg, 0); .) |
||||
[ "IGNORECASE" (. DFA.ignoreCase = true; .) ] /* pdt */ |
||||
[ "CHARACTERS" { SetDecl }] |
||||
[ "TOKENS" { TokenDecl<Node.t> }] |
||||
[ "PRAGMAS" { TokenDecl<Node.pr> }] |
||||
{ "COMMENTS" (. bool nested = false; .) |
||||
"FROM" TokenExpr<out g1> |
||||
"TO" TokenExpr<out g2> |
||||
[ "NESTED" (. nested = true; .) |
||||
] (. new Comment(g1.l, g2.l, nested); .) |
||||
} |
||||
{ "IGNORE" |
||||
Set<out Tab.ignored> (. Tab.ignored[' '] = true; /* ' ' is always ignored */ .) |
||||
} |
||||
|
||||
SYNC |
||||
"PRODUCTIONS" (. if (genScanner) DFA.MakeDeterministic(); |
||||
Graph.DeleteNodes(); |
||||
.) |
||||
{ ident (. sym = Symbol.Find(t.val); |
||||
bool undef = sym == null; |
||||
if (undef) sym = new Symbol(Node.nt, t.val, t.line); |
||||
else { |
||||
if (sym.typ == Node.nt) { |
||||
if (sym.graph != null) SemErr("name declared twice"); |
||||
} else SemErr("this symbol kind not allowed on left side of production"); |
||||
sym.line = t.line; |
||||
} |
||||
bool noAttrs = sym.attrPos == null; |
||||
sym.attrPos = null; |
||||
.) |
||||
[ AttrDecl<sym> ] (. if (!undef) |
||||
if (noAttrs != (sym.attrPos == null)) |
||||
SemErr("attribute mismatch between declaration and use of this symbol"); |
||||
.) |
||||
[ SemText<out sym.semPos> ] WEAK |
||||
'=' |
||||
Expression<out g> (. sym.graph = g.l; |
||||
Graph.Finish(g); |
||||
.) |
||||
WEAK |
||||
'.' |
||||
} |
||||
"END" ident (. if (gramName != t.val) |
||||
SemErr("name does not match grammar name"); |
||||
Tab.gramSy = Symbol.Find(gramName); |
||||
if (Tab.gramSy == null) |
||||
SemErr("missing production for grammar name"); |
||||
else { |
||||
sym = Tab.gramSy; |
||||
if (sym.attrPos != null) |
||||
SemErr("grammar symbol must not have attributes"); |
||||
} |
||||
Tab.noSym = new Symbol(Node.t, "???", 0); // noSym gets highest number |
||||
Tab.SetupAnys(); |
||||
Tab.RenumberPragmas(); |
||||
if (Tab.ddt[2]) Node.PrintNodes(); |
||||
if (Errors.count == 0) { |
||||
Console.WriteLine("checking"); |
||||
Tab.CompSymbolSets(); |
||||
if (Tab.ddt[7]) Tab.XRef(); |
||||
if (Tab.GrammarOk()) { |
||||
Console.Write("parser"); |
||||
ParserGen.WriteParser(); |
||||
if (genScanner) { |
||||
Console.Write(" + scanner"); |
||||
DFA.WriteScanner(); |
||||
if (Tab.ddt[0]) DFA.PrintStates(); |
||||
} |
||||
Console.WriteLine(" generated"); |
||||
if (Tab.ddt[8]) ParserGen.WriteStatistics(); |
||||
} |
||||
} |
||||
if (Tab.ddt[6]) Tab.PrintSymbolTable(); |
||||
.) |
||||
'.' |
||||
. |
||||
|
||||
/*------------------------------------------------------------------------------------*/ |
||||
|
||||
SetDecl (. BitArray s; .) |
||||
= |
||||
ident (. string name = t.val; |
||||
CharClass c = CharClass.Find(name); |
||||
if (c != null) SemErr("name declared twice"); |
||||
.) |
||||
'=' Set<out s> (. if (Sets.Elements(s) == 0) SemErr("character set must not be empty"); |
||||
c = new CharClass(name, s); |
||||
.) |
||||
'.' |
||||
. |
||||
|
||||
/*------------------------------------------------------------------------------------*/ |
||||
|
||||
Set<out BitArray s> (. BitArray s2; .) |
||||
= |
||||
SimSet<out s> |
||||
{ '+' SimSet<out s2> (. s.Or(s2); .) |
||||
| '-' SimSet<out s2> (. Sets.Subtract(s, s2); .) |
||||
} |
||||
. |
||||
|
||||
/*------------------------------------------------------------------------------------*/ |
||||
|
||||
SimSet<out BitArray s> (. int n1, n2; .) |
||||
= (. s = new BitArray(CharClass.charSetSize); .) |
||||
( ident (. CharClass c = CharClass.Find(t.val); |
||||
if (c == null) SemErr("undefined name"); else s.Or(c.set); |
||||
.) |
||||
| string (. string name = t.val; |
||||
name = DFA.Unescape(name.Substring(1, name.Length-2)); |
||||
foreach (char ch in name) |
||||
if (DFA.ignoreCase) s[char.ToLower(ch)] = true; |
||||
else s[ch] = true; .) |
||||
| Char<out n1> (. s[n1] = true; .) |
||||
[ ".." Char<out n2> (. for (int i = n1; i <= n2; i++) s[i] = true; .) |
||||
] |
||||
| "ANY" (. s = new BitArray(CharClass.charSetSize, true); .) |
||||
) |
||||
. |
||||
|
||||
/*--------------------------------------------------------------------------------------*/ |
||||
|
||||
Char<out int n> |
||||
= |
||||
char (. string name = t.val; n = 0; |
||||
name = DFA.Unescape(name.Substring(1, name.Length-2)); |
||||
int max = CharClass.charSetSize; |
||||
if (name.Length == 1 && name[0] <= max-1) n = name[0] % max; |
||||
else SemErr("unacceptable character value"); |
||||
if (DFA.ignoreCase && (char)n >= 'A' && (char)n <= 'Z') n += 32; |
||||
.) |
||||
. |
||||
|
||||
/*------------------------------------------------------------------------------------*/ |
||||
|
||||
TokenDecl<int typ> (. string name; int kind; Symbol sym; Graph g; .) |
||||
= |
||||
Sym<out name, out kind> (. sym = Symbol.Find(name); |
||||
if (sym != null) SemErr("name declared twice"); |
||||
else { |
||||
sym = new Symbol(typ, name, t.line); |
||||
sym.tokenKind = Symbol.fixedToken; |
||||
} |
||||
tokenString = null; |
||||
.) |
||||
SYNC |
||||
( '=' TokenExpr<out g> '.' (. if (kind == str) SemErr("a literal must not be declared with a structure"); |
||||
Graph.Finish(g); |
||||
if (tokenString == null || tokenString.Equals(noString)) |
||||
DFA.ConvertToStates(g.l, sym); |
||||
else { // TokenExpr is a single string |
||||
if (Tab.literals[tokenString] != null) |
||||
SemErr("token string declared twice"); |
||||
Tab.literals[tokenString] = sym; |
||||
DFA.MatchLiteral(tokenString, sym); |
||||
} |
||||
.) |
||||
| (. if (kind == id) genScanner = false; |
||||
else DFA.MatchLiteral(sym.name, sym); |
||||
.) |
||||
) |
||||
[ SemText<out sym.semPos> (. if (typ != Node.pr) SemErr("semantic action not allowed here"); .) |
||||
] |
||||
. |
||||
|
||||
/*------------------------------------------------------------------------------------*/ |
||||
|
||||
AttrDecl<Symbol sym> |
||||
= |
||||
'<' (. int beg = la.pos; int col = la.col; .) |
||||
{ ANY |
||||
| badString (. SemErr("bad string in attributes"); .) |
||||
} |
||||
'>' (. if (t.pos > beg) |
||||
sym.attrPos = new Position(beg, t.pos - beg, col); .) |
||||
. |
||||
|
||||
/*------------------------------------------------------------------------------------*/ |
||||
|
||||
Expression<out Graph g> (. Graph g2; .) |
||||
= |
||||
Term<out g> (. bool first = true; .) |
||||
{ WEAK |
||||
'|' |
||||
Term<out g2> (. if (first) { Graph.MakeFirstAlt(g); first = false; } |
||||
Graph.MakeAlternative(g, g2); |
||||
.) |
||||
} |
||||
. |
||||
|
||||
/*------------------------------------------------------------------------------------*/ |
||||
|
||||
Term<out Graph g> (. Graph g2; Node rslv = null; g = null; .) |
||||
= |
||||
( [ (. rslv = new Node(Node.rslv, null, la.line); .) |
||||
Resolver<out rslv.pos> (. g = new Graph(rslv); .) |
||||
] |
||||
Factor<out g2> (. if (rslv != null) Graph.MakeSequence(g, g2); |
||||
else g = g2; |
||||
.) |
||||
{ Factor<out g2> (. Graph.MakeSequence(g, g2); .) |
||||
} |
||||
| (. g = new Graph(new Node(Node.eps, null, 0)); .) |
||||
) (. if (g == null) // invalid start of Term |
||||
g = new Graph(new Node(Node.eps, null, 0)); |
||||
.) |
||||
. |
||||
|
||||
/*------------------------------------------------------------------------------------*/ |
||||
|
||||
Factor<out Graph g> (. string name; int kind; Position pos; bool weak = false; |
||||
g = null; |
||||
.) |
||||
= |
||||
( [ "WEAK" (. weak = true; .) |
||||
] |
||||
Sym<out name, out kind> (. Symbol sym = Symbol.Find(name); |
||||
if (sym == null && kind == str) |
||||
sym = Tab.literals[name] as Symbol; |
||||
bool undef = sym == null; |
||||
if (undef) { |
||||
if (kind == id) |
||||
sym = new Symbol(Node.nt, name, 0); // forward nt |
||||
else if (genScanner) { |
||||
sym = new Symbol(Node.t, name, t.line); |
||||
DFA.MatchLiteral(sym.name, sym); |
||||
} else { // undefined string in production |
||||
SemErr("undefined string in production"); |
||||
sym = Tab.eofSy; // dummy |
||||
} |
||||
} |
||||
int typ = sym.typ; |
||||
if (typ != Node.t && typ != Node.nt) |
||||
SemErr("this symbol kind is not allowed in a production"); |
||||
if (weak) |
||||
if (typ == Node.t) typ = Node.wt; |
||||
else SemErr("only terminals may be weak"); |
||||
Node p = new Node(typ, sym, t.line); |
||||
g = new Graph(p); |
||||
.) |
||||
[ Attribs<p> (. if (kind != id) SemErr("a literal must not have attributes"); .) |
||||
] (. if (undef) |
||||
sym.attrPos = p.pos; // dummy |
||||
else if ((p.pos == null) != (sym.attrPos == null)) |
||||
SemErr("attribute mismatch between declaration and use of this symbol"); |
||||
.) |
||||
| '(' Expression<out g> ')' |
||||
| '[' Expression<out g> ']' (. Graph.MakeOption(g); .) |
||||
| '{' Expression<out g> '}' (. Graph.MakeIteration(g); .) |
||||
| SemText<out pos> (. Node p = new Node(Node.sem, null, 0); |
||||
p.pos = pos; |
||||
g = new Graph(p); |
||||
.) |
||||
| "ANY" (. Node p = new Node(Node.any, null, 0); // p.set is set in Tab.SetupAnys |
||||
g = new Graph(p); |
||||
.) |
||||
| "SYNC" (. Node p = new Node(Node.sync, null, 0); |
||||
g = new Graph(p); |
||||
.) |
||||
) (. if (g == null) // invalid start of Factor |
||||
g = new Graph(new Node(Node.eps, null, 0)); |
||||
.) |
||||
. |
||||
|
||||
/*------------------------------------------------------------------------------------*/ |
||||
|
||||
Resolver<out Position pos> |
||||
= |
||||
"IF" "(" (. int beg = la.pos; int col = la.col; .) |
||||
Condition (. pos = new Position(beg, t.pos - beg, col); .) |
||||
. |
||||
|
||||
/*------------------------------------------------------------------------------------*/ |
||||
|
||||
Condition = { "(" Condition | ANY } ")" . |
||||
|
||||
/*------------------------------------------------------------------------------------*/ |
||||
|
||||
TokenExpr<out Graph g> (. Graph g2; .) |
||||
= |
||||
TokenTerm<out g> (. bool first = true; .) |
||||
{ WEAK |
||||
'|' |
||||
TokenTerm<out g2> (. if (first) { Graph.MakeFirstAlt(g); first = false; } |
||||
Graph.MakeAlternative(g, g2); |
||||
.) |
||||
} |
||||
. |
||||
|
||||
/*------------------------------------------------------------------------------------*/ |
||||
|
||||
TokenTerm<out Graph g> (. Graph g2; .) |
||||
= |
||||
TokenFactor<out g> |
||||
{ TokenFactor<out g2> (. Graph.MakeSequence(g, g2); .) |
||||
} |
||||
[ "CONTEXT" |
||||
'(' TokenExpr<out g2> (. Graph.SetContextTrans(g2.l); Graph.MakeSequence(g, g2); .) |
||||
')' |
||||
] |
||||
. |
||||
|
||||
/*------------------------------------------------------------------------------------*/ |
||||
|
||||
TokenFactor<out Graph g> (. string name; int kind; .) |
||||
= |
||||
(. g = null; .) |
||||
( Sym<out name, out kind> (. if (kind == id) { |
||||
CharClass c = CharClass.Find(name); |
||||
if (c == null) { |
||||
SemErr("undefined name"); |
||||
c = new CharClass(name, new BitArray(CharClass.charSetSize)); |
||||
} |
||||
Node p = new Node(Node.clas, null, 0); p.val = c.n; |
||||
g = new Graph(p); |
||||
tokenString = noString; |
||||
} else { // str |
||||
g = Graph.StrToGraph(name); |
||||
if (tokenString == null) tokenString = name; |
||||
else tokenString = noString; |
||||
} |
||||
.) |
||||
| '(' TokenExpr<out g> ')' |
||||
| '[' TokenExpr<out g> ']' (. Graph.MakeOption(g); .) |
||||
| '{' TokenExpr<out g> '}' (. Graph.MakeIteration(g); .) |
||||
) (. if (g == null) // invalid start of TokenFactor |
||||
g = new Graph(new Node(Node.eps, null, 0)); .) |
||||
. |
||||
|
||||
/*------------------------------------------------------------------------------------*/ |
||||
|
||||
Sym<out string name, out int kind> |
||||
= (. name = "???"; kind = id; .) |
||||
( ident (. kind = id; name = t.val; .) |
||||
| (string (. name = t.val; .) |
||||
| char (. name = "\"" + t.val.Substring(1, t.val.Length-2) + "\""; .) |
||||
) (. kind = str; |
||||
if (DFA.ignoreCase) name = name.ToLower(); |
||||
if (name.IndexOf(' ') >= 0) |
||||
SemErr("literal tokens must not contain blanks"); .) |
||||
) |
||||
. |
||||
|
||||
/*------------------------------------------------------------------------------------*/ |
||||
|
||||
Attribs<Node p> |
||||
= |
||||
'<' (. int beg = la.pos; int col = la.col; .) |
||||
{ Attribs<p> |
||||
|ANY |
||||
| badString (. SemErr("bad string in attributes"); .) |
||||
} |
||||
'>' (. if (t.pos > beg) p.pos = new Position(beg, t.pos - beg, col); .) |
||||
. |
||||
|
||||
/*------------------------------------------------------------------------------------*/ |
||||
|
||||
SemText<out Position pos> |
||||
= |
||||
"(." (. int beg = la.pos; int col = la.col; .) |
||||
{ ANY |
||||
| badString (. SemErr("bad string in semantic action"); .) |
||||
| "(." (. SemErr("missing end of previous semantic action"); .) |
||||
} |
||||
".)" (. pos = new Position(beg, t.pos - beg, col); .) |
||||
. |
||||
|
||||
/*------------------------------------------------------------------------------------*/ |
||||
|
||||
UsingDecl<out Position pos> |
||||
= |
||||
"using" (. int beg = t.pos; .) |
||||
{ ANY } ';' (. int end = t.pos; .) |
||||
{ "using" { ANY } ';' (. end = t.pos; .) |
||||
} (. pos = new Position(beg, end - beg + 1, 0); .) |
||||
. |
||||
|
||||
END Coco. |
||||
@ -1,97 +0,0 @@
@@ -1,97 +0,0 @@
|
||||
/*------------------------------------------------------------------------- |
||||
Compiler Generator Coco/R, |
||||
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz |
||||
extended by M. Loeberbauer & A. Woess, Univ. of Linz |
||||
with improvements by Pat Terry, Rhodes University |
||||
|
||||
This program is free software; you can redistribute it and/or modify it |
||||
under the terms of the GNU General Public License as published by the |
||||
Free Software Foundation; either version 2, or (at your option) any |
||||
later version. |
||||
|
||||
This program is distributed in the hope that it will be useful, but |
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
||||
for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License along |
||||
with this program; if not, write to the Free Software Foundation, Inc., |
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
||||
|
||||
As an exception, it is allowed to write an extension of Coco/R that is |
||||
used as a plugin in non-free software. |
||||
|
||||
If not otherwise stated, any source code generated by Coco/R (other than |
||||
Coco/R itself) does not fall under the GNU General Public License. |
||||
-------------------------------------------------------------------------*/ |
||||
/*------------------------------------------------------------------------- |
||||
Trace output options |
||||
0 | A: prints the states of the scanner automaton |
||||
1 | F: prints the First and Follow sets of all nonterminals |
||||
2 | G: prints the syntax graph of the productions |
||||
3 | I: traces the computation of the First sets |
||||
4 | J: prints the sets associated with ANYs and synchronisation sets |
||||
6 | S: prints the symbol table (terminals, nonterminals, pragmas) |
||||
7 | X: prints a cross reference list of all syntax symbols |
||||
8 | P: prints statistics about the Coco run |
||||
|
||||
Trace output can be switched on by the pragma |
||||
$ { digit | letter } |
||||
in the attributed grammar or as a command-line option |
||||
-------------------------------------------------------------------------*/ |
||||
|
||||
using System; |
||||
using System.IO; |
||||
|
||||
namespace at.jku.ssw.Coco { |
||||
|
||||
public class Coco { |
||||
|
||||
public static void Main (string[] arg) { |
||||
Console.WriteLine("Coco/R (Jun 28, 2004)"); |
||||
string ATGName = null; |
||||
for (int i = 0; i < arg.Length; i++) { |
||||
if (arg[i] == "-namespace" && i < arg.Length - 1) Tab.nsName = arg[++i]; |
||||
else if (arg[i] == "-frames" && i < arg.Length - 1) Tab.frameDir = arg[++i]; |
||||
else if (arg[i] == "-trace" && i < arg.Length - 1) Tab.SetDDT(arg[++i]); |
||||
else ATGName = arg[i]; |
||||
} |
||||
if (arg.Length > 0 && ATGName != null) { |
||||
int pos = ATGName.LastIndexOf('/'); |
||||
if (pos < 0) pos = ATGName.LastIndexOf('\\'); |
||||
string file = ATGName; |
||||
string dir = ATGName.Substring(0, pos+1); |
||||
|
||||
Scanner.Init(file); |
||||
Trace.Init(dir); |
||||
Tab.Init(); |
||||
DFA.Init(file, dir); |
||||
ParserGen.Init(file, dir); |
||||
|
||||
Parser.Parse(); |
||||
|
||||
Trace.Close(); |
||||
Console.WriteLine("{0} errors detected", Errors.count); |
||||
} else { |
||||
Console.WriteLine("Usage: Coco Grammar.ATG {{Option}}{0}" + |
||||
"Options:{0}" + |
||||
" -namespace <namespaceName>{0}" + |
||||
" -frames <frameFilesDirectory>{0}" + |
||||
" -trace <traceString>{0}" + |
||||
"Valid characters in the trace string:{0}" + |
||||
" A trace automaton{0}" + |
||||
" F list first/follow sets{0}" + |
||||
" G print syntax graph{0}" + |
||||
" I trace computation of first sets{0}" + |
||||
" J list ANY and SYNC sets{0}" + |
||||
" P print statistics{0}" + |
||||
" S list symbol table{0}" + |
||||
" X list cross reference table{0}" + |
||||
"Scanner.frame and Parser.frame files needed in ATG directory{0}" + |
||||
"or in a directory specified in the -frames option.", |
||||
Environment.NewLine); |
||||
} |
||||
} |
||||
} // end Coco
|
||||
|
||||
} // end namespace
|
||||
@ -1,952 +0,0 @@
@@ -1,952 +0,0 @@
|
||||
/*------------------------------------------------------------------------- |
||||
DFA.cs -- Generation of the Scanner Automaton |
||||
Compiler Generator Coco/R, |
||||
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz |
||||
extended by M. Loeberbauer & A. Woess, Univ. of Linz |
||||
with improvements by Pat Terry, Rhodes University |
||||
|
||||
This program is free software; you can redistribute it and/or modify it |
||||
under the terms of the GNU General Public License as published by the |
||||
Free Software Foundation; either version 2, or (at your option) any |
||||
later version. |
||||
|
||||
This program is distributed in the hope that it will be useful, but |
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
||||
for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License along |
||||
with this program; if not, write to the Free Software Foundation, Inc., |
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
||||
|
||||
As an exception, it is allowed to write an extension of Coco/R that is |
||||
used as a plugin in non-free software. |
||||
|
||||
If not otherwise stated, any source code generated by Coco/R (other than |
||||
Coco/R itself) does not fall under the GNU General Public License. |
||||
-------------------------------------------------------------------------*/ |
||||
using System; |
||||
using System.IO; |
||||
using System.Collections; |
||||
using System.Text; |
||||
|
||||
namespace at.jku.ssw.Coco { |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// State
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
public class State { // state of finite automaton
|
||||
public static int lastNr; // highest state number
|
||||
public int nr; // state number
|
||||
public Action firstAction;// to first action of this state
|
||||
public Symbol endOf; // recognized token if state is final
|
||||
public bool ctx; // true if state is reached via contextTrans
|
||||
public State next; |
||||
|
||||
public State() { |
||||
nr = ++lastNr; |
||||
} |
||||
|
||||
public void AddAction(Action act) { |
||||
Action lasta = null, a = firstAction; |
||||
while (a != null && act.typ >= a.typ) {lasta = a; a = a.next;} |
||||
// collecting classes at the beginning gives better performance
|
||||
act.next = a; |
||||
if (a==firstAction) firstAction = act; else lasta.next = act; |
||||
} |
||||
|
||||
public void DetachAction(Action act) { |
||||
Action lasta = null, a = firstAction; |
||||
while (a != null && a != act) {lasta = a; a = a.next;} |
||||
if (a != null) |
||||
if (a == firstAction) firstAction = a.next; else lasta.next = a.next; |
||||
} |
||||
|
||||
public Action TheAction(char ch) { |
||||
BitArray s; |
||||
for (Action a = firstAction; a != null; a = a.next) |
||||
if (a.typ == Node.chr && ch == a.sym) return a; |
||||
else if (a.typ == Node.clas) { |
||||
s = CharClass.Set(a.sym); |
||||
if (s[ch]) return a; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public void MeltWith(State s) { // copy actions of s to state
|
||||
Action a; |
||||
for (Action action = s.firstAction; action != null; action = action.next) { |
||||
a = new Action(action.typ, action.sym, action.tc); |
||||
a.AddTargets(action); |
||||
AddAction(a); |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Action
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
public class Action { // action of finite automaton
|
||||
public int typ; // type of action symbol: clas, chr
|
||||
public int sym; // action symbol
|
||||
public int tc; // transition code: normalTrans, contextTrans
|
||||
public Target target; // states reached from this action
|
||||
public Action next; |
||||
|
||||
public Action(int typ, int sym, int tc) { |
||||
this.typ = typ; this.sym = sym; this.tc = tc; |
||||
} |
||||
|
||||
public void AddTarget(Target t) { // add t to the action.targets
|
||||
Target last = null; |
||||
Target p = target; |
||||
while (p != null && t.state.nr >= p.state.nr) { |
||||
if (t.state == p.state) return; |
||||
last = p; p = p.next; |
||||
} |
||||
t.next = p; |
||||
if (p == target) target = t; else last.next = t; |
||||
} |
||||
|
||||
public void AddTargets(Action a) { // add copy of a.targets to action.targets
|
||||
for (Target p = a.target; p != null; p = p.next) { |
||||
Target t = new Target(p.state); |
||||
AddTarget(t); |
||||
} |
||||
if (a.tc == Node.contextTrans) tc = Node.contextTrans; |
||||
} |
||||
|
||||
public BitArray Symbols() { |
||||
BitArray s; |
||||
if (typ == Node.clas) |
||||
s = (BitArray) CharClass.Set(sym).Clone(); |
||||
else { |
||||
s = new BitArray(CharClass.charSetSize); s[sym] = true; |
||||
} |
||||
return s; |
||||
} |
||||
|
||||
public void ShiftWith(BitArray s) { |
||||
if (Sets.Elements(s) == 1) { |
||||
typ = Node.chr; sym = Sets.First(s); |
||||
} else { |
||||
CharClass c = CharClass.Find(s); |
||||
if (c == null) c = new CharClass("#", s); // class with dummy name
|
||||
typ = Node.clas; sym = c.n; |
||||
} |
||||
} |
||||
|
||||
public void GetTargetStates(out BitArray targets, out Symbol endOf, out bool ctx) { |
||||
// compute the set of target states
|
||||
targets = new BitArray(DFA.maxStates); endOf = null; |
||||
ctx = false; |
||||
for (Target t = target; t != null; t = t.next) { |
||||
int stateNr = t.state.nr; |
||||
if (stateNr <= DFA.lastSimState) targets[stateNr] = true; |
||||
else targets.Or(Melted.Set(stateNr)); |
||||
if (t.state.endOf != null) |
||||
if (endOf == null || endOf == t.state.endOf) |
||||
endOf = t.state.endOf; |
||||
else { |
||||
Console.WriteLine("Tokens {0} and {1} cannot be distinguished", endOf.name, t.state.endOf.name); |
||||
Errors.count++; |
||||
} |
||||
if (t.state.ctx) { |
||||
ctx = true; |
||||
// The following check seems to be unnecessary. It reported an error
|
||||
// if a symbol + context was the prefix of another symbol, e.g.
|
||||
// s1 = "a" "b" "c".
|
||||
// s2 = "a" CONTEXT("b").
|
||||
// But this is ok.
|
||||
// if (t.state.endOf != null) {
|
||||
// Console.WriteLine("Ambiguous context clause");
|
||||
// Errors.count++;
|
||||
// }
|
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Target
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
public class Target { // set of states that are reached by an action
|
||||
public State state; // target state
|
||||
public Target next; |
||||
|
||||
public Target (State s) { |
||||
state = s; |
||||
} |
||||
} |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Melted
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
public class Melted { // info about melted states
|
||||
public static Melted first; // head of melted state list
|
||||
public BitArray set; // set of old states
|
||||
public State state; // new state
|
||||
public Melted next; |
||||
|
||||
public Melted(BitArray set, State state) { |
||||
this.set = set; this.state = state; |
||||
this.next = first; first = this; |
||||
} |
||||
|
||||
public static BitArray Set(int nr) { |
||||
Melted m = first; |
||||
while (m != null) { |
||||
if (m.state.nr == nr) return m.set; else m = m.next; |
||||
} |
||||
throw new Exception("-- compiler error in Melted.Set"); |
||||
} |
||||
|
||||
public static Melted StateWithSet(BitArray s) { |
||||
for (Melted m = first; m != null; m = m.next) |
||||
if (Sets.Equals(s, m.set)) return m; |
||||
return null; |
||||
} |
||||
|
||||
} |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Comment
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
public class Comment { // info about comment syntax
|
||||
public static Comment first; // list of comments
|
||||
public string start; |
||||
public string stop; |
||||
public bool nested; |
||||
public Comment next; |
||||
|
||||
static string Str(Node p) { |
||||
StringBuilder s = new StringBuilder(); |
||||
while (p != null) { |
||||
if (p.typ == Node.chr) { |
||||
s.Append((char)p.val); |
||||
} else if (p.typ == Node.clas) { |
||||
BitArray set = CharClass.Set(p.val); |
||||
if (Sets.Elements(set) != 1) Parser.SemErr("character set contains more than 1 character"); |
||||
s.Append((char)Sets.First(set)); |
||||
} else Parser.SemErr("comment delimiters may not be structured"); |
||||
p = p.next; |
||||
} |
||||
if (s.Length == 0 || s.Length > 2) { |
||||
Parser.SemErr("comment delimiters must be 1 or 2 characters long"); |
||||
s = new StringBuilder("?"); |
||||
} |
||||
return s.ToString(); |
||||
} |
||||
|
||||
public Comment(Node from, Node to, bool nested) { |
||||
start = Str(from); |
||||
stop = Str(to); |
||||
this.nested = nested; |
||||
this.next = first; first = this; |
||||
} |
||||
|
||||
} |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// DFA
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
public class DFA { |
||||
public static int maxStates; |
||||
public const int EOF = -1; |
||||
|
||||
public static State firstState; |
||||
public static State lastState; // last allocated state
|
||||
public static int lastSimState; // last non melted state
|
||||
public static FileStream fram; // scanner frame input
|
||||
public static StreamWriter gen; // generated scanner file
|
||||
public static Symbol curSy; // current token to be recognized (in FindTrans)
|
||||
public static Node curGraph; // start of graph for current token (in FindTrans)
|
||||
public static bool ignoreCase; // true if input should be treated case-insensitively
|
||||
public static bool dirtyDFA; // DFA may become nondeterministic in MatchLiteral
|
||||
public static bool hasCtxMoves; // DFA has context transitions
|
||||
static string srcName; // name of the attributed grammar file
|
||||
static string srcDir; // directory of attributed grammar file
|
||||
|
||||
//---------- Output primitives
|
||||
private static string Ch(char ch) { |
||||
if (ch < ' ' || ch >= 127 || ch == '\'' || ch == '\\') return Convert.ToString((int)ch); |
||||
else return String.Format("'{0}'", ch); |
||||
} |
||||
|
||||
private static string ChCond(char ch) { |
||||
return String.Format("ch == {0}", Ch(ch)); |
||||
} |
||||
|
||||
private static void PutRange(BitArray s) { |
||||
int[] lo = new int[32]; |
||||
int[] hi = new int[32]; |
||||
// fill lo and hi
|
||||
int max = CharClass.charSetSize; |
||||
int top = -1; |
||||
int i = 0; |
||||
while (i < max) { |
||||
if (s[i]) { |
||||
top++; lo[top] = i; i++; |
||||
while (i < max && s[i]) i++; |
||||
hi[top] = i-1; |
||||
} else i++; |
||||
} |
||||
// print ranges
|
||||
if (top == 1 && lo[0] == 0 && hi[1] == max-1 && hi[0]+2 == lo[1]) { |
||||
BitArray s1 = new BitArray(max); s1[hi[0]+1] = true; |
||||
gen.Write("!"); PutRange(s1); |
||||
} else { |
||||
gen.Write("("); |
||||
for (i = 0; i <= top; i++) { |
||||
if (hi[i] == lo[i]) gen.Write("ch == {0}", Ch((char)lo[i])); |
||||
else if (lo[i] == 0) gen.Write("ch <= {0}", Ch((char)hi[i])); |
||||
else if (hi[i] == max-1) gen.Write("ch >= {0}", Ch((char)lo[i])); |
||||
else gen.Write("ch >= {0} && ch <= {1}", Ch((char)lo[i]), Ch((char)hi[i])); |
||||
if (i < top) gen.Write(" || "); |
||||
} |
||||
gen.Write(")"); |
||||
} |
||||
} |
||||
|
||||
//---------- String handling
|
||||
static char Hex2Char(string s) { |
||||
int val = 0; |
||||
for (int i = 0; i < s.Length; i++) { |
||||
char ch = s[i]; |
||||
if ('0' <= ch && ch <= '9') val = 16 * val + (ch - '0'); |
||||
else if ('a' <= ch && ch <= 'f') val = 16 * val + (10 + ch - 'a'); |
||||
else if ('A' <= ch && ch <= 'F') val = 16 * val + (10 + ch - 'A'); |
||||
else Parser.SemErr("bad escape sequence in string or character"); |
||||
} |
||||
if (val > CharClass.charSetSize) /* pdt */ |
||||
Parser.SemErr("bad escape sequence in string or character"); |
||||
return (char) (val % CharClass.charSetSize); |
||||
} |
||||
|
||||
static string Char2Hex(char ch) { |
||||
StringWriter w = new StringWriter(); |
||||
w.Write("\\u{0:x4}", (int)ch); |
||||
return w.ToString(); |
||||
} |
||||
|
||||
public static string Unescape (string s) { |
||||
/* replaces escape sequences in s by their Unicode values. */ |
||||
StringBuilder buf = new StringBuilder(); |
||||
int i = 0; |
||||
while (i < s.Length) { |
||||
if (s[i] == '\\') { |
||||
switch (s[i+1]) { |
||||
case '\\': buf.Append('\\'); i += 2; break; |
||||
case '\'': buf.Append('\''); i += 2; break; |
||||
case '\"': buf.Append('\"'); i += 2; break; |
||||
case 'r': buf.Append('\r'); i += 2; break; |
||||
case 'n': buf.Append('\n'); i += 2; break; |
||||
case 't': buf.Append('\t'); i += 2; break; |
||||
case '0': buf.Append('\0'); i += 2; break; |
||||
case 'a': buf.Append('\a'); i += 2; break; |
||||
case 'b': buf.Append('\b'); i += 2; break; |
||||
case 'f': buf.Append('\f'); i += 2; break; |
||||
case 'v': buf.Append('\v'); i += 2; break; |
||||
case 'u': case 'x': |
||||
if (i + 6 <= s.Length) { |
||||
buf.Append(Hex2Char(s.Substring(i+2, 4))); i += 6; break; |
||||
} else { |
||||
Parser.SemErr("bad escape sequence in string or character"); i = s.Length; break; |
||||
} |
||||
default: Parser.SemErr("bad escape sequence in string or character"); i += 2; break; |
||||
} |
||||
} else { |
||||
buf.Append(s[i]); |
||||
i++; |
||||
} |
||||
} |
||||
return buf.ToString(); |
||||
} |
||||
|
||||
public static string Escape (string s) { |
||||
StringBuilder buf = new StringBuilder(); |
||||
foreach (char ch in s) { |
||||
switch(ch) { |
||||
case '\\': buf.Append("\\\\"); break; |
||||
case '\'': buf.Append("\\'"); break; |
||||
case '\"': buf.Append("\\\""); break; |
||||
case '\t': buf.Append("\\t"); break; |
||||
case '\r': buf.Append("\\r"); break; |
||||
case '\n': buf.Append("\\n"); break; |
||||
default: |
||||
if (ch < ' ' || ch > '\u007f') buf.Append(Char2Hex(ch)); |
||||
else buf.Append(ch); |
||||
break; |
||||
} |
||||
} |
||||
return buf.ToString(); |
||||
} |
||||
|
||||
//---------- State handling
|
||||
static State NewState() { |
||||
State s = new State(); |
||||
if (firstState == null) firstState = s; else lastState.next = s; |
||||
lastState = s; |
||||
return s; |
||||
} |
||||
|
||||
static void NewTransition(State from, State to, int typ, int sym, int tc) { |
||||
if (to == firstState) Parser.SemErr("token must not start with an iteration"); |
||||
Target t = new Target(to); |
||||
Action a = new Action(typ, sym, tc); a.target = t; |
||||
from.AddAction(a); |
||||
if (typ == Node.clas) curSy.tokenKind = Symbol.classToken; |
||||
} |
||||
|
||||
static void CombineShifts() { |
||||
State state; |
||||
Action a, b, c; |
||||
BitArray seta, setb; |
||||
for (state = firstState; state != null; state = state.next) { |
||||
for (a = state.firstAction; a != null; a = a.next) { |
||||
b = a.next; |
||||
while (b != null) |
||||
if (a.target.state == b.target.state && a.tc == b.tc) { |
||||
seta = a.Symbols(); setb = b.Symbols(); |
||||
seta.Or(setb); |
||||
a.ShiftWith(seta); |
||||
c = b; b = b.next; state.DetachAction(c); |
||||
} else b = b.next; |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void FindUsedStates(State state, BitArray used) { |
||||
if (used[state.nr]) return; |
||||
used[state.nr] = true; |
||||
for (Action a = state.firstAction; a != null; a = a.next) |
||||
FindUsedStates(a.target.state, used); |
||||
} |
||||
|
||||
static void DeleteRedundantStates() { |
||||
State[] newState = new State[State.lastNr + 1]; |
||||
BitArray used = new BitArray(State.lastNr + 1); |
||||
FindUsedStates(firstState, used); |
||||
// combine equal final states
|
||||
for (State s1 = firstState.next; s1 != null; s1 = s1.next) // firstState cannot be final
|
||||
if (used[s1.nr] && s1.endOf != null && s1.firstAction == null && !s1.ctx) |
||||
for (State s2 = s1.next; s2 != null; s2 = s2.next) |
||||
if (used[s2.nr] && s1.endOf == s2.endOf && s2.firstAction == null & !s2.ctx) { |
||||
used[s2.nr] = false; newState[s2.nr] = s1; |
||||
} |
||||
for (State state = firstState; state != null; state = state.next) |
||||
if (used[state.nr]) |
||||
for (Action a = state.firstAction; a != null; a = a.next) |
||||
if (!used[a.target.state.nr]) |
||||
a.target.state = newState[a.target.state.nr]; |
||||
// delete unused states
|
||||
lastState = firstState; State.lastNr = 0; // firstState has number 0
|
||||
for (State state = firstState.next; state != null; state = state.next) |
||||
if (used[state.nr]) {state.nr = ++State.lastNr; lastState = state;} |
||||
else lastState.next = state.next; |
||||
} |
||||
|
||||
static State TheState(Node p) { |
||||
State state; |
||||
if (p == null) {state = NewState(); state.endOf = curSy; return state;} |
||||
else return p.state; |
||||
} |
||||
|
||||
static void Step(State from, Node p, BitArray stepped) { |
||||
if (p == null) return; |
||||
stepped[p.n] = true; |
||||
switch (p.typ) { |
||||
case Node.clas: case Node.chr: { |
||||
NewTransition(from, TheState(p.next), p.typ, p.val, p.code); |
||||
break; |
||||
} |
||||
case Node.alt: { |
||||
Step(from, p.sub, stepped); Step(from, p.down, stepped); |
||||
break; |
||||
} |
||||
case Node.iter: case Node.opt: { |
||||
if (p.next != null && !stepped[p.next.n]) Step(from, p.next, stepped); |
||||
Step(from, p.sub, stepped); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void NumberNodes(Node p, State state) { |
||||
/* Assigns a state n.state to every node n. There will be a transition from |
||||
n.state to n.next.state triggered by n.val. All nodes in an alternative |
||||
chain are represented by the same state. |
||||
*/ |
||||
if (p == null) return; |
||||
if (p.state != null) return; // already visited;
|
||||
if (state == null) state = NewState(); |
||||
p.state = state; |
||||
if (Node.DelGraph(p)) state.endOf = curSy; |
||||
switch (p.typ) { |
||||
case Node.clas: case Node.chr: { |
||||
NumberNodes(p.next, null); |
||||
break; |
||||
} |
||||
case Node.opt: { |
||||
NumberNodes(p.next, null); NumberNodes(p.sub, state); |
||||
break; |
||||
} |
||||
case Node.iter: { |
||||
NumberNodes(p.next, state); NumberNodes(p.sub, state); |
||||
break; |
||||
} |
||||
case Node.alt: { |
||||
NumberNodes(p.sub, state); NumberNodes(p.down, state); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void FindTrans (Node p, bool start, BitArray marked) { |
||||
if (p == null || marked[p.n]) return; |
||||
marked[p.n] = true; |
||||
if (start) Step(p.state, p, new BitArray(Node.nodes.Count)); // start of group of equally numbered nodes
|
||||
switch (p.typ) { |
||||
case Node.clas: case Node.chr: { |
||||
FindTrans(p.next, true, marked); |
||||
break; |
||||
} |
||||
case Node.opt: { |
||||
FindTrans(p.next, true, marked); FindTrans(p.sub, false, marked); |
||||
break; |
||||
} |
||||
case Node.iter: { |
||||
FindTrans(p.next, false, marked); FindTrans(p.sub, false, marked); |
||||
break; |
||||
} |
||||
case Node.alt: { |
||||
FindTrans(p.sub, false, marked); FindTrans(p.down, false, marked); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public static void ConvertToStates(Node p, Symbol sym) { |
||||
curGraph = p; curSy = sym; |
||||
if (Node.DelGraph(curGraph)) Parser.SemErr("token might be empty"); |
||||
NumberNodes(curGraph, firstState); |
||||
FindTrans(curGraph, true, new BitArray(Node.nodes.Count)); |
||||
} |
||||
|
||||
// match string against current automaton; store it either as a fixedToken or as a litToken
|
||||
public static void MatchLiteral(string s, Symbol sym) { |
||||
s = Unescape(s.Substring(1, s.Length-2)); |
||||
int i, len = s.Length; |
||||
State state = firstState; |
||||
Action a = null; |
||||
for (i = 0; i < len; i++) { // try to match s against existing DFA
|
||||
a = state.TheAction(s[i]); |
||||
if (a == null) break; |
||||
state = a.target.state; |
||||
} |
||||
// if s was not totally consumed or leads to a non-final state => make new DFA from it
|
||||
if (i != len || state.endOf == null) { |
||||
state = firstState; i = 0; a = null; |
||||
dirtyDFA = true; |
||||
} |
||||
for (; i < len; i++) { // make new DFA for s[i..len-1]
|
||||
State to = NewState(); |
||||
NewTransition(state, to, Node.chr, s[i], Node.normalTrans); |
||||
state = to; |
||||
} |
||||
Symbol matchedSym = state.endOf; |
||||
if (state.endOf == null) { |
||||
state.endOf = sym; |
||||
} else if (matchedSym.tokenKind == Symbol.fixedToken || (a != null && a.tc == Node.contextTrans)) { |
||||
// s matched a token with a fixed definition or a token with an appendix that will be cut off
|
||||
Parser.SemErr("tokens " + sym.name + " and " + matchedSym.name + " cannot be distinguished"); |
||||
} else { // matchedSym == classToken || classLitToken
|
||||
matchedSym.tokenKind = Symbol.classLitToken; |
||||
sym.tokenKind = Symbol.litToken; |
||||
} |
||||
} |
||||
|
||||
static void SplitActions(State state, Action a, Action b) { |
||||
Action c; BitArray seta, setb, setc; |
||||
seta = a.Symbols(); setb = b.Symbols(); |
||||
if (Sets.Equals(seta, setb)) { |
||||
a.AddTargets(b); |
||||
state.DetachAction(b); |
||||
} else if (Sets.Includes(seta, setb)) { |
||||
setc = (BitArray)seta.Clone(); Sets.Subtract(setc, setb); |
||||
b.AddTargets(a); |
||||
a.ShiftWith(setc); |
||||
} else if (Sets.Includes(setb, seta)) { |
||||
setc = (BitArray)setb.Clone(); Sets.Subtract(setc, seta); |
||||
a.AddTargets(b); |
||||
b.ShiftWith(setc); |
||||
} else { |
||||
setc = (BitArray)seta.Clone(); setc.And(setb); |
||||
Sets.Subtract(seta, setc); |
||||
Sets.Subtract(setb, setc); |
||||
a.ShiftWith(seta); |
||||
b.ShiftWith(setb); |
||||
c = new Action(0, 0, Node.normalTrans); // typ and sym are set in ShiftWith
|
||||
c.AddTargets(a); |
||||
c.AddTargets(b); |
||||
c.ShiftWith(setc); |
||||
state.AddAction(c); |
||||
} |
||||
} |
||||
|
||||
private static bool Overlap(Action a, Action b) { |
||||
BitArray seta, setb; |
||||
if (a.typ == Node.chr) |
||||
if (b.typ == Node.chr) return a.sym == b.sym; |
||||
else {setb = CharClass.Set(b.sym); return setb[a.sym];} |
||||
else { |
||||
seta = CharClass.Set(a.sym); |
||||
if (b.typ ==Node.chr) return seta[b.sym]; |
||||
else {setb = CharClass.Set(b.sym); return Sets.Intersect(seta, setb);} |
||||
} |
||||
} |
||||
|
||||
static bool MakeUnique(State state) { // return true if actions were split
|
||||
bool changed = false; |
||||
for (Action a = state.firstAction; a != null; a = a.next) |
||||
for (Action b = a.next; b != null; b = b.next) |
||||
if (Overlap(a, b)) {SplitActions(state, a, b); changed = true;} |
||||
return changed; |
||||
} |
||||
|
||||
static void MeltStates(State state) { |
||||
bool changed, ctx; |
||||
BitArray targets; |
||||
Symbol endOf; |
||||
for (Action action = state.firstAction; action != null; action = action.next) { |
||||
if (action.target.next != null) { |
||||
action.GetTargetStates(out targets, out endOf, out ctx); |
||||
Melted melt = Melted.StateWithSet(targets); |
||||
if (melt == null) { |
||||
State s = NewState(); s.endOf = endOf; s.ctx = ctx; |
||||
for (Target targ = action.target; targ != null; targ = targ.next) |
||||
s.MeltWith(targ.state); |
||||
do {changed = MakeUnique(s);} while (changed); |
||||
melt = new Melted(targets, s); |
||||
} |
||||
action.target.next = null; |
||||
action.target.state = melt.state; |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void FindCtxStates() { |
||||
for (State state = firstState; state != null; state = state.next) |
||||
for (Action a = state.firstAction; a != null; a = a.next) |
||||
if (a.tc == Node.contextTrans) a.target.state.ctx = true; |
||||
} |
||||
|
||||
public static void MakeDeterministic() { |
||||
State state; |
||||
bool changed; |
||||
lastSimState = lastState.nr; |
||||
maxStates = 2 * lastSimState; // heuristic for set size in Melted.set
|
||||
FindCtxStates(); |
||||
for (state = firstState; state != null; state = state.next) |
||||
do {changed = MakeUnique(state);} while (changed); |
||||
for (state = firstState; state != null; state = state.next) |
||||
MeltStates(state); |
||||
DeleteRedundantStates(); |
||||
CombineShifts(); |
||||
} |
||||
|
||||
public static void PrintStates() { |
||||
Trace.WriteLine(); |
||||
Trace.WriteLine("---------- states ----------"); |
||||
for (State state = firstState; state != null; state = state.next) { |
||||
bool first = true; |
||||
if (state.endOf == null) Trace.Write(" "); |
||||
else Trace.Write("E({0,12})", Node.Name(state.endOf.name)); |
||||
Trace.Write("{0,3}:", state.nr); |
||||
if (state.firstAction == null) Trace.WriteLine(); |
||||
for (Action action = state.firstAction; action != null; action = action.next) { |
||||
if (first) {Trace.Write(" "); first = false;} else Trace.Write(" "); |
||||
if (action.typ == Node.clas) Trace.Write(((CharClass)CharClass.classes[action.sym]).name); |
||||
else Trace.Write("{0, 3}", Ch((char)action.sym)); |
||||
for (Target targ = action.target; targ != null; targ = targ.next) |
||||
Trace.Write(" {0, 3}", targ.state.nr); |
||||
if (action.tc == Node.contextTrans) Trace.WriteLine(" context"); else Trace.WriteLine(); |
||||
} |
||||
} |
||||
Trace.WriteLine(); |
||||
Trace.WriteLine("---------- character classes ----------"); |
||||
CharClass.WriteClasses(); |
||||
} |
||||
|
||||
static void GenComBody(Comment com) { |
||||
gen.WriteLine( "\t\t\tfor(;;) {"); |
||||
gen.Write ( "\t\t\t\tif ({0}) ", ChCond(com.stop[0])); gen.WriteLine("{"); |
||||
if (com.stop.Length == 1) { |
||||
gen.WriteLine("\t\t\t\t\tlevel--;"); |
||||
gen.WriteLine("\t\t\t\t\tif (level == 0) { oldEols = line - line0; NextCh(); return true; }"); |
||||
gen.WriteLine("\t\t\t\t\tNextCh();"); |
||||
} else { |
||||
gen.WriteLine("\t\t\t\t\tNextCh();"); |
||||
gen.WriteLine("\t\t\t\t\tif ({0}) {{", ChCond(com.stop[1])); |
||||
gen.WriteLine("\t\t\t\t\t\tlevel--;"); |
||||
gen.WriteLine("\t\t\t\t\t\tif (level == 0) { oldEols = line - line0; NextCh(); return true; }"); |
||||
gen.WriteLine("\t\t\t\t\t\tNextCh();"); |
||||
gen.WriteLine("\t\t\t\t\t}"); |
||||
} |
||||
if (com.nested) { |
||||
gen.Write ("\t\t\t\t}"); gen.Write(" else if ({0}) ", ChCond(com.start[0])); gen.WriteLine("{"); |
||||
if (com.start.Length == 1) |
||||
gen.WriteLine("\t\t\t\t\tlevel++; NextCh();"); |
||||
else { |
||||
gen.WriteLine("\t\t\t\t\tNextCh();"); |
||||
gen.Write ("\t\t\t\t\tif ({0}) ", ChCond(com.start[1])); gen.WriteLine("{"); |
||||
gen.WriteLine("\t\t\t\t\t\tlevel++; NextCh();"); |
||||
gen.WriteLine("\t\t\t\t\t}"); |
||||
} |
||||
} |
||||
gen.WriteLine( "\t\t\t\t} else if (ch == Buffer.EOF) return false;"); |
||||
gen.WriteLine( "\t\t\t\telse NextCh();"); |
||||
gen.WriteLine( "\t\t\t}"); |
||||
} |
||||
|
||||
static void GenComment(Comment com, int i) { |
||||
gen.WriteLine(); |
||||
gen.Write ("\tstatic bool Comment{0}() ", i); gen.WriteLine("{"); |
||||
gen.WriteLine("\t\tint level = 1, line0 = line, lineStart0 = lineStart;"); |
||||
if (com.start.Length == 1) { |
||||
gen.WriteLine("\t\tNextCh();"); |
||||
GenComBody(com); |
||||
} else { |
||||
gen.WriteLine("\t\tNextCh();"); |
||||
gen.Write ("\t\tif ({0}) ", ChCond(com.start[1])); gen.WriteLine("{"); |
||||
gen.WriteLine("\t\t\tNextCh();"); |
||||
GenComBody(com); |
||||
gen.WriteLine("\t\t} else {"); |
||||
gen.WriteLine("\t\t\tif (ch==EOL) {line--; lineStart = lineStart0;}"); |
||||
gen.WriteLine("\t\t\tpos = pos - 2; Buffer.Pos = pos+1; NextCh();"); |
||||
gen.WriteLine("\t\t}"); |
||||
gen.WriteLine("\t\treturn false;"); |
||||
} |
||||
gen.WriteLine("\t}"); |
||||
} |
||||
|
||||
static void CopyFramePart(string stop) { |
||||
char startCh = stop[0]; |
||||
int endOfStopString = stop.Length-1; |
||||
int ch = fram.ReadByte(); |
||||
while (ch != EOF) |
||||
if (ch == startCh) { |
||||
int i = 0; |
||||
do { |
||||
if (i == endOfStopString) return; // stop[0..i] found
|
||||
ch = fram.ReadByte(); i++; |
||||
} while (ch == stop[i]); |
||||
// stop[0..i-1] found; continue with last read character
|
||||
gen.Write(stop.Substring(0, i)); |
||||
} else { |
||||
gen.Write((char)ch); ch = fram.ReadByte(); |
||||
} |
||||
Errors.Exception(" -- incomplete or corrupt scanner frame file"); |
||||
} |
||||
|
||||
static string SymName(Symbol sym) { |
||||
if (Char.IsLetter(sym.name[0])) { // real name value is stored in Tab.literals
|
||||
foreach (DictionaryEntry e in Tab.literals) |
||||
if ((Symbol)e.Value == sym) return (string)e.Key; |
||||
} |
||||
return sym.name; |
||||
} |
||||
|
||||
static void GenLiterals () { |
||||
if (ignoreCase) { |
||||
gen.WriteLine("\t\tswitch (t.val.ToLower()) {"); |
||||
} else { |
||||
gen.WriteLine("\t\tswitch (t.val) {"); |
||||
} |
||||
foreach (Symbol sym in Symbol.terminals) { |
||||
if (sym.tokenKind == Symbol.litToken) { |
||||
string name = SymName(sym); |
||||
if (ignoreCase) name = name.ToLower(); |
||||
// sym.name stores literals with quotes, e.g. "\"Literal\""
|
||||
gen.WriteLine("\t\t\tcase {0}: t.kind = {1}; break;", name, sym.n); |
||||
} |
||||
} |
||||
gen.WriteLine("\t\t\tdefault: break;"); |
||||
gen.Write("\t\t}"); |
||||
} |
||||
|
||||
static void WriteState(State state) { |
||||
Symbol endOf = state.endOf; |
||||
gen.WriteLine("\t\t\tcase {0}:", state.nr); |
||||
bool ctxEnd = state.ctx; |
||||
for (Action action = state.firstAction; action != null; action = action.next) { |
||||
if (action == state.firstAction) gen.Write("\t\t\t\tif ("); |
||||
else gen.Write("\t\t\t\telse if ("); |
||||
if (action.typ == Node.chr) gen.Write(ChCond((char)action.sym)); |
||||
else PutRange(CharClass.Set(action.sym)); |
||||
gen.Write(") {"); |
||||
if (action.tc == Node.contextTrans) { |
||||
gen.Write("apx++; "); ctxEnd = false; |
||||
} else if (state.ctx) |
||||
gen.Write("apx = 0; "); |
||||
if (ignoreCase) gen.Write("buf.Append(valCh); "); else gen.Write("buf.Append(ch); "); |
||||
gen.Write("NextCh(); goto case {0};", action.target.state.nr); |
||||
gen.WriteLine("}"); |
||||
} |
||||
if (state.firstAction == null) |
||||
gen.Write("\t\t\t\t{"); |
||||
else |
||||
gen.Write("\t\t\t\telse {"); |
||||
if (ctxEnd) { // final context state: cut appendix
|
||||
gen.WriteLine(); |
||||
gen.WriteLine("\t\t\t\t\tbuf.Length = buf.Length - apx;"); |
||||
gen.WriteLine("\t\t\t\t\tpos = pos - apx - 1; line = t.line;"); |
||||
gen.WriteLine("\t\t\t\t\tBuffer.Pos = pos+1; NextCh();"); |
||||
gen.Write( "\t\t\t\t\t"); |
||||
} |
||||
if (endOf == null) { |
||||
gen.WriteLine("t.kind = noSym; goto done;}"); |
||||
} else { |
||||
gen.Write("t.kind = {0}; ", endOf.n); |
||||
if (endOf.tokenKind == Symbol.classLitToken) { |
||||
gen.WriteLine("t.val = buf.ToString(); CheckLiteral(); return t;}"); |
||||
} else { |
||||
gen.WriteLine("goto done;}"); |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void FillStartTab(int[] startTab) { |
||||
for (Action action = firstState.firstAction; action != null; action = action.next) { |
||||
int targetState = action.target.state.nr; |
||||
if (action.typ == Node.chr) startTab[action.sym] = targetState; |
||||
else { |
||||
BitArray s = CharClass.Set(action.sym); |
||||
for (int i = 0; i < s.Count; i++) |
||||
if (s[i]) startTab[i] = targetState; |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void OpenGen(bool backUp) { /* pdt */ |
||||
try { |
||||
string fn = srcDir + "Scanner.cs"; /* pdt */ |
||||
if (File.Exists(fn) && backUp) File.Copy(fn, fn + ".old", true); |
||||
gen = new StreamWriter(new FileStream(fn, FileMode.Create)); /* pdt */ |
||||
} catch (IOException) { |
||||
Errors.Exception("-- Cannot generate scanner file"); |
||||
} |
||||
} |
||||
|
||||
public static void WriteScanner() { |
||||
int i, j; |
||||
int[] startTab = new int[CharClass.charSetSize]; |
||||
string fr = srcDir + "Scanner.frame"; /* pdt */ |
||||
if (!File.Exists(fr)) { |
||||
if (Tab.frameDir != null) fr = Tab.frameDir.Trim() + Path.DirectorySeparatorChar + "Scanner.frame"; |
||||
if (!File.Exists(fr)) Errors.Exception("-- Cannot find Scanner.frame"); |
||||
} |
||||
try { |
||||
fram = new FileStream(fr, FileMode.Open, FileAccess.Read, FileShare.Read); |
||||
} catch (FileNotFoundException) { |
||||
Errors.Exception("-- Cannot open Scanner.frame."); |
||||
} |
||||
OpenGen(true); /* pdt */ |
||||
if (dirtyDFA) MakeDeterministic(); |
||||
FillStartTab(startTab); |
||||
CopyFramePart("-->begin"); |
||||
if (!srcName.ToLower().EndsWith("coco.atg")) { |
||||
gen.Close(); OpenGen(false); /* pdt */ |
||||
} |
||||
CopyFramePart("-->namespace"); |
||||
/* AW add namespace, if it exists */ |
||||
if (Tab.nsName != null && Tab.nsName.Length > 0) { |
||||
gen.Write("namespace "); |
||||
gen.Write(Tab.nsName); |
||||
gen.Write(" {"); |
||||
} |
||||
CopyFramePart("-->declarations"); |
||||
gen.WriteLine("\tconst int charSetSize = {0};", CharClass.charSetSize); |
||||
gen.WriteLine("\tconst int maxT = {0};", Symbol.terminals.Count - 1); |
||||
gen.WriteLine("\tconst int noSym = {0};", Tab.noSym.n); |
||||
gen.WriteLine("\tstatic short[] start = {"); |
||||
for (i = 0; i < CharClass.charSetSize / 16; i++) { |
||||
gen.Write("\t"); |
||||
for (j = 0; j < 16; j++) |
||||
gen.Write("{0,3},", startTab[16*i+j]); |
||||
gen.WriteLine(); |
||||
} |
||||
gen.WriteLine("\t -1};"); /* pdt */ |
||||
if (ignoreCase) |
||||
gen.Write("\tstatic char valCh; // current input character (for token.val)"); |
||||
CopyFramePart("-->initialization"); |
||||
gen.WriteLine("\t\tignore = new BitArray(charSetSize+1);"); /* pdt */ |
||||
gen.Write("\t\t"); |
||||
if (Tab.ignored == null) gen.Write("ignore[' '] = true;"); |
||||
else { |
||||
j = 0; |
||||
for (i = 0; i < Tab.ignored.Count; i++) |
||||
if (Tab.ignored[i]) { |
||||
gen.Write("ignore[{0}] = true; ", i); |
||||
if (++j % 4 == 0) { gen.WriteLine(); gen.Write("\t\t"); } |
||||
} |
||||
} |
||||
CopyFramePart("-->casing"); |
||||
if (ignoreCase) { |
||||
gen.WriteLine("\t\tvalCh = ch;"); |
||||
gen.Write ("\t\tif (ch != Buffer.EOF) ch = char.ToLower(ch);"); |
||||
} |
||||
CopyFramePart("-->comments"); |
||||
Comment com = Comment.first; i = 0; |
||||
while (com != null) { |
||||
GenComment(com, i); |
||||
com = com.next; i++; |
||||
} |
||||
CopyFramePart("-->literals"); GenLiterals(); |
||||
CopyFramePart("-->scan1"); |
||||
if (Comment.first!=null) { |
||||
gen.Write("\t\tif ("); |
||||
com = Comment.first; i = 0; |
||||
while (com != null) { |
||||
gen.Write(ChCond(com.start[0])); |
||||
gen.Write(" && Comment{0}()", i); |
||||
if (com.next != null) gen.Write(" ||"); |
||||
com = com.next; i++; |
||||
} |
||||
gen.Write(") return NextToken();"); |
||||
} |
||||
if (hasCtxMoves) { gen.WriteLine(); gen.Write("\t\tint apx = 0;"); } /* pdt */ |
||||
CopyFramePart("-->scan2"); |
||||
if (ignoreCase) gen.Write("\t\tbuf.Append(valCh); NextCh();"); |
||||
else gen.Write("\t\tbuf.Append(ch); NextCh();"); |
||||
CopyFramePart("-->scan3"); |
||||
for (State state = firstState.next; state != null; state = state.next) |
||||
WriteState(state); |
||||
CopyFramePart("$$$"); |
||||
/* AW 12-20-02 close namespace, if it exists */ |
||||
if (Tab.nsName != null && Tab.nsName.Length > 0) gen.Write("}"); |
||||
gen.Close(); |
||||
} |
||||
|
||||
public static void Init (string file, string dir) { |
||||
srcName = file; |
||||
srcDir = dir; |
||||
firstState = null; lastState = null; State.lastNr = -1; |
||||
firstState = NewState(); |
||||
Melted.first = null; Comment.first = null; |
||||
ignoreCase = false; |
||||
dirtyDFA = false; |
||||
hasCtxMoves = false; |
||||
} |
||||
|
||||
} // end DFA
|
||||
|
||||
} // end namespace
|
||||
@ -1,785 +0,0 @@
@@ -1,785 +0,0 @@
|
||||
/*---------------------------------------------------------------------- |
||||
Compiler Generator Coco/R, |
||||
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz |
||||
extended by M. Loeberbauer & A. Woess, Univ. of Linz |
||||
with improvements by Pat Terry, Rhodes University |
||||
|
||||
This program is free software; you can redistribute it and/or modify it |
||||
under the terms of the GNU General Public License as published by the |
||||
Free Software Foundation; either version 2, or (at your option) any |
||||
later version. |
||||
|
||||
This program is distributed in the hope that it will be useful, but |
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
||||
for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License along |
||||
with this program; if not, write to the Free Software Foundation, Inc., |
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
||||
|
||||
As an exception, it is allowed to write an extension of Coco/R that is |
||||
used as a plugin in non-free software. |
||||
|
||||
If not otherwise stated, any source code generated by Coco/R (other than |
||||
Coco/R itself) does not fall under the GNU General Public License. |
||||
----------------------------------------------------------------------*/ |
||||
using System.Collections; |
||||
|
||||
using System; |
||||
|
||||
namespace at.jku.ssw.Coco { |
||||
|
||||
|
||||
|
||||
public class Parser { |
||||
const int _EOF = 0; |
||||
const int _ident = 1; |
||||
const int _number = 2; |
||||
const int _string = 3; |
||||
const int _badString = 4; |
||||
const int _char = 5; |
||||
const int maxT = 41; |
||||
|
||||
const bool T = true; |
||||
const bool x = false; |
||||
const int minErrDist = 2; |
||||
|
||||
public static Token t; // last recognized token
|
||||
public static Token la; // lookahead token
|
||||
static int errDist = minErrDist; |
||||
|
||||
const int id = 0; |
||||
const int str = 1; |
||||
|
||||
static bool genScanner; |
||||
static string tokenString; // used in declarations of literal tokens
|
||||
static string noString = "-none-"; // used in declarations of literal tokens
|
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
|
||||
|
||||
static void SynErr (int n) { |
||||
if (errDist >= minErrDist) Errors.SynErr(la.line, la.col, n); |
||||
errDist = 0; |
||||
} |
||||
|
||||
public static void SemErr (string msg) { |
||||
if (errDist >= minErrDist) Errors.Error(t.line, t.col, msg); |
||||
errDist = 0; |
||||
} |
||||
|
||||
static void Get () { |
||||
for (;;) { |
||||
t = la; |
||||
la = Scanner.Scan(); |
||||
if (la.kind <= maxT) { ++errDist; break; } |
||||
if (la.kind == 42) { |
||||
Tab.SetDDT(la.val); |
||||
} |
||||
|
||||
la = t; |
||||
} |
||||
} |
||||
|
||||
static void Expect (int n) { |
||||
if (la.kind==n) Get(); else { SynErr(n); } |
||||
} |
||||
|
||||
static bool StartOf (int s) { |
||||
return set[s, la.kind]; |
||||
} |
||||
|
||||
static void ExpectWeak (int n, int follow) { |
||||
if (la.kind == n) Get(); |
||||
else { |
||||
SynErr(n); |
||||
while (!StartOf(follow)) Get(); |
||||
} |
||||
} |
||||
|
||||
static bool WeakSeparator (int n, int syFol, int repFol) { |
||||
bool[] s = new bool[maxT+1]; |
||||
if (la.kind == n) { Get(); return true; } |
||||
else if (StartOf(repFol)) return false; |
||||
else { |
||||
for (int i=0; i <= maxT; i++) { |
||||
s[i] = set[syFol, i] || set[repFol, i] || set[0, i]; |
||||
} |
||||
SynErr(n); |
||||
while (!s[la.kind]) Get(); |
||||
return StartOf(syFol); |
||||
} |
||||
} |
||||
|
||||
static void Coco() { |
||||
Symbol sym; Graph g, g1, g2; string gramName; |
||||
if (la.kind == 39) { |
||||
UsingDecl(out ParserGen.usingPos); |
||||
} |
||||
Expect(6); |
||||
genScanner = true; Tab.ignored = null; |
||||
Expect(1); |
||||
gramName = t.val; |
||||
int beg = la.pos; |
||||
|
||||
while (StartOf(1)) { |
||||
Get(); |
||||
} |
||||
Tab.semDeclPos = new Position(beg, la.pos-beg, 0); |
||||
if (la.kind == 7) { |
||||
Get(); |
||||
DFA.ignoreCase = true; |
||||
} |
||||
if (la.kind == 8) { |
||||
Get(); |
||||
while (la.kind == 1) { |
||||
SetDecl(); |
||||
} |
||||
} |
||||
if (la.kind == 9) { |
||||
Get(); |
||||
while (la.kind == 1 || la.kind == 3 || la.kind == 5) { |
||||
TokenDecl(Node.t); |
||||
} |
||||
} |
||||
if (la.kind == 10) { |
||||
Get(); |
||||
while (la.kind == 1 || la.kind == 3 || la.kind == 5) { |
||||
TokenDecl(Node.pr); |
||||
} |
||||
} |
||||
while (la.kind == 11) { |
||||
Get(); |
||||
bool nested = false; |
||||
Expect(12); |
||||
TokenExpr(out g1); |
||||
Expect(13); |
||||
TokenExpr(out g2); |
||||
if (la.kind == 14) { |
||||
Get(); |
||||
nested = true; |
||||
} |
||||
new Comment(g1.l, g2.l, nested); |
||||
} |
||||
while (la.kind == 15) { |
||||
Get(); |
||||
Set(out Tab.ignored); |
||||
Tab.ignored[' '] = true; /* ' ' is always ignored */ |
||||
} |
||||
while (!(la.kind == 0 || la.kind == 16)) {SynErr(42); Get();} |
||||
Expect(16); |
||||
if (genScanner) DFA.MakeDeterministic(); |
||||
Graph.DeleteNodes(); |
||||
|
||||
while (la.kind == 1) { |
||||
Get(); |
||||
sym = Symbol.Find(t.val); |
||||
bool undef = sym == null; |
||||
if (undef) sym = new Symbol(Node.nt, t.val, t.line); |
||||
else { |
||||
if (sym.typ == Node.nt) { |
||||
if (sym.graph != null) SemErr("name declared twice"); |
||||
} else SemErr("this symbol kind not allowed on left side of production"); |
||||
sym.line = t.line; |
||||
} |
||||
bool noAttrs = sym.attrPos == null; |
||||
sym.attrPos = null; |
||||
|
||||
if (la.kind == 24) { |
||||
AttrDecl(sym); |
||||
} |
||||
if (!undef) |
||||
if (noAttrs != (sym.attrPos == null)) |
||||
SemErr("attribute mismatch between declaration and use of this symbol"); |
||||
|
||||
if (la.kind == 37) { |
||||
SemText(out sym.semPos); |
||||
} |
||||
ExpectWeak(17, 2); |
||||
Expression(out g); |
||||
sym.graph = g.l; |
||||
Graph.Finish(g); |
||||
|
||||
ExpectWeak(18, 3); |
||||
} |
||||
Expect(19); |
||||
Expect(1); |
||||
if (gramName != t.val) |
||||
SemErr("name does not match grammar name"); |
||||
Tab.gramSy = Symbol.Find(gramName); |
||||
if (Tab.gramSy == null) |
||||
SemErr("missing production for grammar name"); |
||||
else { |
||||
sym = Tab.gramSy; |
||||
if (sym.attrPos != null) |
||||
SemErr("grammar symbol must not have attributes"); |
||||
} |
||||
Tab.noSym = new Symbol(Node.t, "???", 0); // noSym gets highest number
|
||||
Tab.SetupAnys(); |
||||
Tab.RenumberPragmas(); |
||||
if (Tab.ddt[2]) Node.PrintNodes(); |
||||
if (Errors.count == 0) { |
||||
Console.WriteLine("checking"); |
||||
Tab.CompSymbolSets(); |
||||
if (Tab.ddt[7]) Tab.XRef(); |
||||
if (Tab.GrammarOk()) { |
||||
Console.Write("parser"); |
||||
ParserGen.WriteParser(); |
||||
if (genScanner) { |
||||
Console.Write(" + scanner"); |
||||
DFA.WriteScanner(); |
||||
if (Tab.ddt[0]) DFA.PrintStates(); |
||||
} |
||||
Console.WriteLine(" generated"); |
||||
if (Tab.ddt[8]) ParserGen.WriteStatistics(); |
||||
} |
||||
} |
||||
if (Tab.ddt[6]) Tab.PrintSymbolTable(); |
||||
|
||||
Expect(18); |
||||
} |
||||
|
||||
static void UsingDecl(out Position pos) { |
||||
Expect(39); |
||||
int beg = t.pos; |
||||
while (StartOf(4)) { |
||||
Get(); |
||||
} |
||||
Expect(40); |
||||
int end = t.pos; |
||||
while (la.kind == 39) { |
||||
Get(); |
||||
while (StartOf(4)) { |
||||
Get(); |
||||
} |
||||
Expect(40); |
||||
end = t.pos; |
||||
} |
||||
pos = new Position(beg, end - beg + 1, 0); |
||||
} |
||||
|
||||
static void SetDecl() { |
||||
BitArray s; |
||||
Expect(1); |
||||
string name = t.val; |
||||
CharClass c = CharClass.Find(name); |
||||
if (c != null) SemErr("name declared twice"); |
||||
|
||||
Expect(17); |
||||
Set(out s); |
||||
if (Sets.Elements(s) == 0) SemErr("character set must not be empty"); |
||||
c = new CharClass(name, s); |
||||
|
||||
Expect(18); |
||||
} |
||||
|
||||
static void TokenDecl(int typ) { |
||||
string name; int kind; Symbol sym; Graph g; |
||||
Sym(out name, out kind); |
||||
sym = Symbol.Find(name); |
||||
if (sym != null) SemErr("name declared twice"); |
||||
else { |
||||
sym = new Symbol(typ, name, t.line); |
||||
sym.tokenKind = Symbol.fixedToken; |
||||
} |
||||
tokenString = null; |
||||
|
||||
while (!(StartOf(5))) {SynErr(43); Get();} |
||||
if (la.kind == 17) { |
||||
Get(); |
||||
TokenExpr(out g); |
||||
Expect(18); |
||||
if (kind == str) SemErr("a literal must not be declared with a structure"); |
||||
Graph.Finish(g); |
||||
if (tokenString == null || tokenString.Equals(noString)) |
||||
DFA.ConvertToStates(g.l, sym); |
||||
else { // TokenExpr is a single string
|
||||
if (Tab.literals[tokenString] != null) |
||||
SemErr("token string declared twice"); |
||||
Tab.literals[tokenString] = sym; |
||||
DFA.MatchLiteral(tokenString, sym); |
||||
} |
||||
|
||||
} else if (StartOf(6)) { |
||||
if (kind == id) genScanner = false; |
||||
else DFA.MatchLiteral(sym.name, sym); |
||||
|
||||
} else SynErr(44); |
||||
if (la.kind == 37) { |
||||
SemText(out sym.semPos); |
||||
if (typ != Node.pr) SemErr("semantic action not allowed here"); |
||||
} |
||||
} |
||||
|
||||
static void TokenExpr(out Graph g) { |
||||
Graph g2; |
||||
TokenTerm(out g); |
||||
bool first = true; |
||||
while (WeakSeparator(26,7,8) ) { |
||||
TokenTerm(out g2); |
||||
if (first) { Graph.MakeFirstAlt(g); first = false; } |
||||
Graph.MakeAlternative(g, g2); |
||||
|
||||
} |
||||
} |
||||
|
||||
static void Set(out BitArray s) { |
||||
BitArray s2; |
||||
SimSet(out s); |
||||
while (la.kind == 20 || la.kind == 21) { |
||||
if (la.kind == 20) { |
||||
Get(); |
||||
SimSet(out s2); |
||||
s.Or(s2); |
||||
} else { |
||||
Get(); |
||||
SimSet(out s2); |
||||
Sets.Subtract(s, s2); |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void AttrDecl(Symbol sym) { |
||||
Expect(24); |
||||
int beg = la.pos; int col = la.col; |
||||
while (StartOf(9)) { |
||||
// CHANGES BY M.KRUEGER
|
||||
if (la.kind == 24) { |
||||
AttrDecl(sym); |
||||
} else |
||||
// EOC
|
||||
if (StartOf(10)) { |
||||
Get(); |
||||
} else { |
||||
Get(); |
||||
SemErr("bad string in attributes"); |
||||
} |
||||
} |
||||
Expect(25); |
||||
if (t.pos > beg) |
||||
sym.attrPos = new Position(beg, t.pos - beg, col); |
||||
} |
||||
|
||||
static void SemText(out Position pos) { |
||||
Expect(37); |
||||
int beg = la.pos; int col = la.col; |
||||
while (StartOf(11)) { |
||||
if (StartOf(12)) { |
||||
Get(); |
||||
} else if (la.kind == 4) { |
||||
Get(); |
||||
SemErr("bad string in semantic action"); |
||||
} else { |
||||
Get(); |
||||
SemErr("missing end of previous semantic action"); |
||||
} |
||||
} |
||||
Expect(38); |
||||
pos = new Position(beg, t.pos - beg, col); |
||||
} |
||||
|
||||
static void Expression(out Graph g) { |
||||
Graph g2; |
||||
Term(out g); |
||||
bool first = true; |
||||
while (WeakSeparator(26,13,14) ) { |
||||
Term(out g2); |
||||
if (first) { Graph.MakeFirstAlt(g); first = false; } |
||||
Graph.MakeAlternative(g, g2); |
||||
|
||||
} |
||||
} |
||||
|
||||
static void SimSet(out BitArray s) { |
||||
int n1, n2; |
||||
s = new BitArray(CharClass.charSetSize); |
||||
if (la.kind == 1) { |
||||
Get(); |
||||
CharClass c = CharClass.Find(t.val); |
||||
if (c == null) SemErr("undefined name"); else s.Or(c.set); |
||||
|
||||
} else if (la.kind == 3) { |
||||
Get(); |
||||
string name = t.val; |
||||
name = DFA.Unescape(name.Substring(1, name.Length-2)); |
||||
foreach (char ch in name) |
||||
if (DFA.ignoreCase) s[char.ToLower(ch)] = true; |
||||
else s[ch] = true; |
||||
} else if (la.kind == 5) { |
||||
Char(out n1); |
||||
s[n1] = true; |
||||
if (la.kind == 22) { |
||||
Get(); |
||||
Char(out n2); |
||||
for (int i = n1; i <= n2; i++) s[i] = true; |
||||
} |
||||
} else if (la.kind == 23) { |
||||
Get(); |
||||
s = new BitArray(CharClass.charSetSize, true); |
||||
} else SynErr(45); |
||||
} |
||||
|
||||
static void Char(out int n) { |
||||
Expect(5); |
||||
string name = t.val; n = 0; |
||||
name = DFA.Unescape(name.Substring(1, name.Length-2)); |
||||
int max = CharClass.charSetSize; |
||||
if (name.Length == 1 && name[0] <= max-1) n = name[0] % max; |
||||
else SemErr("unacceptable character value"); |
||||
if (DFA.ignoreCase && (char)n >= 'A' && (char)n <= 'Z') n += 32; |
||||
|
||||
} |
||||
|
||||
static void Sym(out string name, out int kind) { |
||||
name = "???"; kind = id; |
||||
if (la.kind == 1) { |
||||
Get(); |
||||
kind = id; name = t.val; |
||||
} else if (la.kind == 3 || la.kind == 5) { |
||||
if (la.kind == 3) { |
||||
Get(); |
||||
name = t.val; |
||||
} else { |
||||
Get(); |
||||
name = "\"" + t.val.Substring(1, t.val.Length-2) + "\""; |
||||
} |
||||
kind = str; |
||||
if (DFA.ignoreCase) name = name.ToLower(); |
||||
if (name.IndexOf(' ') >= 0) |
||||
SemErr("literal tokens must not contain blanks"); |
||||
} else SynErr(46); |
||||
} |
||||
|
||||
static void Term(out Graph g) { |
||||
Graph g2; Node rslv = null; g = null; |
||||
if (StartOf(15)) { |
||||
if (la.kind == 35) { |
||||
rslv = new Node(Node.rslv, null, la.line); |
||||
Resolver(out rslv.pos); |
||||
g = new Graph(rslv); |
||||
} |
||||
Factor(out g2); |
||||
if (rslv != null) Graph.MakeSequence(g, g2); |
||||
else g = g2; |
||||
|
||||
while (StartOf(16)) { |
||||
Factor(out g2); |
||||
Graph.MakeSequence(g, g2); |
||||
} |
||||
} else if (StartOf(17)) { |
||||
g = new Graph(new Node(Node.eps, null, 0)); |
||||
} else SynErr(47); |
||||
if (g == null) // invalid start of Term
|
||||
g = new Graph(new Node(Node.eps, null, 0)); |
||||
|
||||
} |
||||
|
||||
static void Resolver(out Position pos) { |
||||
Expect(35); |
||||
Expect(28); |
||||
int beg = la.pos; int col = la.col; |
||||
Condition(); |
||||
pos = new Position(beg, t.pos - beg, col); |
||||
} |
||||
|
||||
static void Factor(out Graph g) { |
||||
string name; int kind; Position pos; bool weak = false; |
||||
g = null; |
||||
|
||||
switch (la.kind) { |
||||
case 1: case 3: case 5: case 27: { |
||||
if (la.kind == 27) { |
||||
Get(); |
||||
weak = true; |
||||
} |
||||
Sym(out name, out kind); |
||||
Symbol sym = Symbol.Find(name); |
||||
if (sym == null && kind == str) |
||||
sym = Tab.literals[name] as Symbol; |
||||
bool undef = sym == null; |
||||
if (undef) { |
||||
if (kind == id) |
||||
sym = new Symbol(Node.nt, name, 0); // forward nt
|
||||
else if (genScanner) { |
||||
sym = new Symbol(Node.t, name, t.line); |
||||
DFA.MatchLiteral(sym.name, sym); |
||||
} else { // undefined string in production
|
||||
SemErr("undefined string in production"); |
||||
sym = Tab.eofSy; // dummy
|
||||
} |
||||
} |
||||
int typ = sym.typ; |
||||
if (typ != Node.t && typ != Node.nt) |
||||
SemErr("this symbol kind is not allowed in a production"); |
||||
if (weak) |
||||
if (typ == Node.t) typ = Node.wt; |
||||
else SemErr("only terminals may be weak"); |
||||
Node p = new Node(typ, sym, t.line); |
||||
g = new Graph(p); |
||||
|
||||
if (la.kind == 24) { |
||||
Attribs(p); |
||||
if (kind != id) SemErr("a literal must not have attributes"); |
||||
} |
||||
if (undef) |
||||
sym.attrPos = p.pos; // dummy
|
||||
else if ((p.pos == null) != (sym.attrPos == null)) |
||||
SemErr("attribute mismatch between declaration and use of this symbol"); |
||||
|
||||
break; |
||||
} |
||||
case 28: { |
||||
Get(); |
||||
Expression(out g); |
||||
Expect(29); |
||||
break; |
||||
} |
||||
case 30: { |
||||
Get(); |
||||
Expression(out g); |
||||
Expect(31); |
||||
Graph.MakeOption(g); |
||||
break; |
||||
} |
||||
case 32: { |
||||
Get(); |
||||
Expression(out g); |
||||
Expect(33); |
||||
Graph.MakeIteration(g); |
||||
break; |
||||
} |
||||
case 37: { |
||||
SemText(out pos); |
||||
Node p = new Node(Node.sem, null, 0); |
||||
p.pos = pos; |
||||
g = new Graph(p); |
||||
|
||||
break; |
||||
} |
||||
case 23: { |
||||
Get(); |
||||
Node p = new Node(Node.any, null, 0); // p.set is set in Tab.SetupAnys
|
||||
g = new Graph(p); |
||||
|
||||
break; |
||||
} |
||||
case 34: { |
||||
Get(); |
||||
Node p = new Node(Node.sync, null, 0); |
||||
g = new Graph(p); |
||||
|
||||
break; |
||||
} |
||||
default: SynErr(48); break; |
||||
} |
||||
if (g == null) // invalid start of Factor
|
||||
g = new Graph(new Node(Node.eps, null, 0)); |
||||
|
||||
} |
||||
|
||||
static void Attribs(Node p) { |
||||
Expect(24); |
||||
int beg = la.pos; int col = la.col; |
||||
while (StartOf(9)) { |
||||
// CHANGES BY M.KRUEGER
|
||||
if (la.kind == 24) { |
||||
Attribs(p); |
||||
} else |
||||
// EOC
|
||||
if (StartOf(10)) { |
||||
Get(); |
||||
} else { |
||||
Get(); |
||||
SemErr("bad string in attributes"); |
||||
} |
||||
} |
||||
Expect(25); |
||||
if (t.pos > beg) p.pos = new Position(beg, t.pos - beg, col); |
||||
} |
||||
|
||||
static void Condition() { |
||||
while (StartOf(18)) { |
||||
if (la.kind == 28) { |
||||
Get(); |
||||
Condition(); |
||||
} else { |
||||
Get(); |
||||
} |
||||
} |
||||
Expect(29); |
||||
} |
||||
|
||||
static void TokenTerm(out Graph g) { |
||||
Graph g2; |
||||
TokenFactor(out g); |
||||
while (StartOf(7)) { |
||||
TokenFactor(out g2); |
||||
Graph.MakeSequence(g, g2); |
||||
} |
||||
if (la.kind == 36) { |
||||
Get(); |
||||
Expect(28); |
||||
TokenExpr(out g2); |
||||
Graph.SetContextTrans(g2.l); Graph.MakeSequence(g, g2); |
||||
Expect(29); |
||||
} |
||||
} |
||||
|
||||
static void TokenFactor(out Graph g) { |
||||
string name; int kind; |
||||
g = null; |
||||
if (la.kind == 1 || la.kind == 3 || la.kind == 5) { |
||||
Sym(out name, out kind); |
||||
if (kind == id) { |
||||
CharClass c = CharClass.Find(name); |
||||
if (c == null) { |
||||
SemErr("undefined name"); |
||||
c = new CharClass(name, new BitArray(CharClass.charSetSize)); |
||||
} |
||||
Node p = new Node(Node.clas, null, 0); p.val = c.n; |
||||
g = new Graph(p); |
||||
tokenString = noString; |
||||
} else { // str
|
||||
g = Graph.StrToGraph(name); |
||||
if (tokenString == null) tokenString = name; |
||||
else tokenString = noString; |
||||
} |
||||
|
||||
} else if (la.kind == 28) { |
||||
Get(); |
||||
TokenExpr(out g); |
||||
Expect(29); |
||||
} else if (la.kind == 30) { |
||||
Get(); |
||||
TokenExpr(out g); |
||||
Expect(31); |
||||
Graph.MakeOption(g); |
||||
} else if (la.kind == 32) { |
||||
Get(); |
||||
TokenExpr(out g); |
||||
Expect(33); |
||||
Graph.MakeIteration(g); |
||||
} else SynErr(49); |
||||
if (g == null) // invalid start of TokenFactor
|
||||
g = new Graph(new Node(Node.eps, null, 0)); |
||||
} |
||||
|
||||
|
||||
|
||||
public static void Parse() { |
||||
la = new Token(); |
||||
la.val = ""; |
||||
Get(); |
||||
Coco(); |
||||
|
||||
Expect(0); |
||||
} |
||||
|
||||
static bool[,] set = { |
||||
{T,T,x,T, x,T,x,x, x,x,T,T, x,x,x,T, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x}, |
||||
{x,T,T,T, T,T,T,x, x,x,x,x, T,T,T,x, x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,x}, |
||||
{T,T,x,T, x,T,x,x, x,x,T,T, x,x,x,T, T,T,T,x, x,x,x,T, x,x,T,T, T,x,T,x, T,x,T,T, x,T,x,x, x,x,x}, |
||||
{T,T,x,T, x,T,x,x, x,x,T,T, x,x,x,T, T,T,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x}, |
||||
{x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, x,T,x}, |
||||
{T,T,x,T, x,T,x,x, x,x,T,T, x,x,x,T, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x}, |
||||
{x,T,x,T, x,T,x,x, x,x,T,T, x,x,x,T, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x}, |
||||
{x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,T,x, T,x,x,x, x,x,x,x, x,x,x}, |
||||
{x,x,x,x, x,x,x,x, x,x,x,T, x,T,T,T, T,x,T,x, x,x,x,x, x,x,x,x, x,T,x,T, x,T,x,x, x,x,x,x, x,x,x}, |
||||
{x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,x}, |
||||
{x,T,T,T, x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,x}, |
||||
{x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,x,T, T,T,x}, |
||||
{x,T,T,T, x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,x,T, T,T,x}, |
||||
{x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,T, x,x,T,T, T,T,T,T, T,T,T,T, x,T,x,x, x,x,x}, |
||||
{x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,T,x,T, x,T,x,x, x,x,x,x, x,x,x}, |
||||
{x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,T, T,x,T,x, T,x,T,T, x,T,x,x, x,x,x}, |
||||
{x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,T, T,x,T,x, T,x,T,x, x,T,x,x, x,x,x}, |
||||
{x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,T,x, x,T,x,T, x,T,x,x, x,x,x,x, x,x,x}, |
||||
{x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,T,T, T,T,T,T, T,T,T,T, T,T,x} |
||||
|
||||
}; |
||||
} // end Parser
|
||||
|
||||
|
||||
public class Errors { |
||||
public static int count = 0; // number of errors detected
|
||||
public static string errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text
|
||||
|
||||
public static void SynErr (int line, int col, int n) { |
||||
string s; |
||||
switch (n) { |
||||
case 0: s = "EOF expected"; break; |
||||
case 1: s = "ident expected"; break; |
||||
case 2: s = "number expected"; break; |
||||
case 3: s = "string expected"; break; |
||||
case 4: s = "badString expected"; break; |
||||
case 5: s = "char expected"; break; |
||||
case 6: s = "\"COMPILER\" expected"; break; |
||||
case 7: s = "\"IGNORECASE\" expected"; break; |
||||
case 8: s = "\"CHARACTERS\" expected"; break; |
||||
case 9: s = "\"TOKENS\" expected"; break; |
||||
case 10: s = "\"PRAGMAS\" expected"; break; |
||||
case 11: s = "\"COMMENTS\" expected"; break; |
||||
case 12: s = "\"FROM\" expected"; break; |
||||
case 13: s = "\"TO\" expected"; break; |
||||
case 14: s = "\"NESTED\" expected"; break; |
||||
case 15: s = "\"IGNORE\" expected"; break; |
||||
case 16: s = "\"PRODUCTIONS\" expected"; break; |
||||
case 17: s = "\"=\" expected"; break; |
||||
case 18: s = "\".\" expected"; break; |
||||
case 19: s = "\"END\" expected"; break; |
||||
case 20: s = "\"+\" expected"; break; |
||||
case 21: s = "\"-\" expected"; break; |
||||
case 22: s = "\"..\" expected"; break; |
||||
case 23: s = "\"ANY\" expected"; break; |
||||
case 24: s = "\"<\" expected"; break; |
||||
case 25: s = "\">\" expected"; break; |
||||
case 26: s = "\"|\" expected"; break; |
||||
case 27: s = "\"WEAK\" expected"; break; |
||||
case 28: s = "\"(\" expected"; break; |
||||
case 29: s = "\")\" expected"; break; |
||||
case 30: s = "\"[\" expected"; break; |
||||
case 31: s = "\"]\" expected"; break; |
||||
case 32: s = "\"{\" expected"; break; |
||||
case 33: s = "\"}\" expected"; break; |
||||
case 34: s = "\"SYNC\" expected"; break; |
||||
case 35: s = "\"IF\" expected"; break; |
||||
case 36: s = "\"CONTEXT\" expected"; break; |
||||
case 37: s = "\"(.\" expected"; break; |
||||
case 38: s = "\".)\" expected"; break; |
||||
case 39: s = "\"using\" expected"; break; |
||||
case 40: s = "\";\" expected"; break; |
||||
case 41: s = "??? expected"; break; |
||||
case 42: s = "this symbol not expected in Coco"; break; |
||||
case 43: s = "this symbol not expected in TokenDecl"; break; |
||||
case 44: s = "invalid TokenDecl"; break; |
||||
case 45: s = "invalid SimSet"; break; |
||||
case 46: s = "invalid Sym"; break; |
||||
case 47: s = "invalid Term"; break; |
||||
case 48: s = "invalid Factor"; break; |
||||
case 49: s = "invalid TokenFactor"; break; |
||||
|
||||
default: s = "error " + n; break; |
||||
} |
||||
Console.WriteLine(Errors.errMsgFormat, line, col, s); |
||||
count++; |
||||
} |
||||
|
||||
public static void SemErr (int line, int col, int n) { |
||||
Console.WriteLine(errMsgFormat, line, col, ("error " + n)); |
||||
count++; |
||||
} |
||||
|
||||
public static void Error (int line, int col, string s) { |
||||
Console.WriteLine(errMsgFormat, line, col, s); |
||||
count++; |
||||
} |
||||
|
||||
public static void Exception (string s) { |
||||
Console.WriteLine(s); |
||||
System.Environment.Exit(1); |
||||
} |
||||
} // Errors
|
||||
|
||||
} |
||||
@ -1,140 +0,0 @@
@@ -1,140 +0,0 @@
|
||||
/*---------------------------------------------------------------------- |
||||
Compiler Generator Coco/R, |
||||
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz |
||||
extended by M. Loeberbauer & A. Woess, Univ. of Linz |
||||
with improvements by Pat Terry, Rhodes University |
||||
|
||||
This program is free software; you can redistribute it and/or modify it |
||||
under the terms of the GNU General Public License as published by the |
||||
Free Software Foundation; either version 2, or (at your option) any |
||||
later version. |
||||
|
||||
This program is distributed in the hope that it will be useful, but |
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
||||
for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License along |
||||
with this program; if not, write to the Free Software Foundation, Inc., |
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
||||
|
||||
As an exception, it is allowed to write an extension of Coco/R that is |
||||
used as a plugin in non-free software. |
||||
|
||||
If not otherwise stated, any source code generated by Coco/R (other than |
||||
Coco/R itself) does not fall under the GNU General Public License. |
||||
----------------------------------------------------------------------*/ |
||||
-->begin |
||||
using System; |
||||
|
||||
-->namespace |
||||
|
||||
public class Parser { |
||||
-->constants |
||||
const bool T = true; |
||||
const bool x = false; |
||||
const int minErrDist = 2; |
||||
|
||||
public static Token t; // last recognized token |
||||
public static Token la; // lookahead token |
||||
static int errDist = minErrDist; |
||||
|
||||
-->declarations |
||||
|
||||
static void SynErr (int n) { |
||||
if (errDist >= minErrDist) Errors.SynErr(la.line, la.col, n); |
||||
errDist = 0; |
||||
} |
||||
|
||||
public static void SemErr (string msg) { |
||||
if (errDist >= minErrDist) Errors.Error(t.line, t.col, msg); |
||||
errDist = 0; |
||||
} |
||||
|
||||
static void Get () { |
||||
for (;;) { |
||||
t = la; |
||||
la = Scanner.Scan(); |
||||
if (la.kind <= maxT) { ++errDist; break; } |
||||
-->pragmas |
||||
la = t; |
||||
} |
||||
} |
||||
|
||||
static void Expect (int n) { |
||||
if (la.kind==n) Get(); else { SynErr(n); } |
||||
} |
||||
|
||||
static bool StartOf (int s) { |
||||
return set[s, la.kind]; |
||||
} |
||||
|
||||
static void ExpectWeak (int n, int follow) { |
||||
if (la.kind == n) Get(); |
||||
else { |
||||
SynErr(n); |
||||
while (!StartOf(follow)) Get(); |
||||
} |
||||
} |
||||
|
||||
static bool WeakSeparator (int n, int syFol, int repFol) { |
||||
bool[] s = new bool[maxT+1]; |
||||
if (la.kind == n) { Get(); return true; } |
||||
else if (StartOf(repFol)) return false; |
||||
else { |
||||
for (int i=0; i <= maxT; i++) { |
||||
s[i] = set[syFol, i] || set[repFol, i] || set[0, i]; |
||||
} |
||||
SynErr(n); |
||||
while (!s[la.kind]) Get(); |
||||
return StartOf(syFol); |
||||
} |
||||
} |
||||
|
||||
-->productions |
||||
|
||||
public static void Parse() { |
||||
la = new Token(); |
||||
la.val = ""; |
||||
Get(); |
||||
-->parseRoot |
||||
Expect(0); |
||||
} |
||||
|
||||
static bool[,] set = { |
||||
-->initialization |
||||
}; |
||||
} // end Parser |
||||
|
||||
|
||||
public class Errors { |
||||
public static int count = 0; // number of errors detected |
||||
public static string errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text |
||||
|
||||
public static void SynErr (int line, int col, int n) { |
||||
string s; |
||||
switch (n) { |
||||
-->errors |
||||
default: s = "error " + n; break; |
||||
} |
||||
Console.WriteLine(Errors.errMsgFormat, line, col, s); |
||||
count++; |
||||
} |
||||
|
||||
public static void SemErr (int line, int col, int n) { |
||||
Console.WriteLine(errMsgFormat, line, col, ("error " + n)); |
||||
count++; |
||||
} |
||||
|
||||
public static void Error (int line, int col, string s) { |
||||
Console.WriteLine(errMsgFormat, line, col, s); |
||||
count++; |
||||
} |
||||
|
||||
public static void Exception (string s) { |
||||
Console.WriteLine(s); |
||||
System.Environment.Exit(1); |
||||
} |
||||
} // Errors |
||||
|
||||
$$$ |
||||
@ -1,432 +0,0 @@
@@ -1,432 +0,0 @@
|
||||
/*------------------------------------------------------------------------- |
||||
ParserGen.cs -- Generation of the Recursive Descent Parser |
||||
Compiler Generator Coco/R, |
||||
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz |
||||
extended by M. Loeberbauer & A. Woess, Univ. of Linz |
||||
with improvements by Pat Terry, Rhodes University |
||||
|
||||
This program is free software; you can redistribute it and/or modify it |
||||
under the terms of the GNU General Public License as published by the |
||||
Free Software Foundation; either version 2, or (at your option) any |
||||
later version. |
||||
|
||||
This program is distributed in the hope that it will be useful, but |
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
||||
for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License along |
||||
with this program; if not, write to the Free Software Foundation, Inc., |
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
||||
|
||||
As an exception, it is allowed to write an extension of Coco/R that is |
||||
used as a plugin in non-free software. |
||||
|
||||
If not otherwise stated, any source code generated by Coco/R (other than |
||||
Coco/R itself) does not fall under the GNU General Public License. |
||||
-------------------------------------------------------------------------*/ |
||||
using System; |
||||
using System.IO; |
||||
using System.Collections; |
||||
using System.Text; |
||||
|
||||
namespace at.jku.ssw.Coco { |
||||
|
||||
public class ParserGen { |
||||
|
||||
const int maxTerm = 3; // sets of size < maxTerm are enumerated
|
||||
const char CR = '\r'; |
||||
const char LF = '\n'; |
||||
const int EOF = -1; |
||||
|
||||
const int tErr = 0; // error codes
|
||||
const int altErr = 1; |
||||
const int syncErr = 2; |
||||
|
||||
public static Position usingPos; // "using" definitions from the attributed grammar
|
||||
// CHANGES BY M.KRUEGER
|
||||
public static string productionModifiers = String.Empty; |
||||
//EOC
|
||||
|
||||
static int errorNr; // highest parser error number
|
||||
static Symbol curSy; // symbol whose production is currently generated
|
||||
static FileStream fram; // parser frame file
|
||||
static StreamWriter gen; // generated parser source file
|
||||
static StringWriter err; // generated parser error messages
|
||||
static string srcName; // name of attributed grammar file
|
||||
static string srcDir; // directory of attributed grammar file
|
||||
static ArrayList symSet = new ArrayList(); |
||||
|
||||
static void Indent (int n) { |
||||
for (int i = 1; i <= n; i++) gen.Write('\t'); |
||||
} |
||||
|
||||
// AW: use a switch if more than 5 alternatives and none starts with a resolver
|
||||
static bool UseSwitch (Node p) { |
||||
if (p.typ != Node.alt) return false; |
||||
int nAlts = 0; |
||||
while (p != null) { |
||||
++nAlts; |
||||
// must not optimize with switch-statement, if alt uses a resolver expression
|
||||
if (p.sub.typ == Node.rslv) return false; |
||||
p = p.down; |
||||
} |
||||
return nAlts > 5; |
||||
} |
||||
|
||||
static void CopyFramePart (string stop) { |
||||
char startCh = stop[0]; |
||||
int endOfStopString = stop.Length-1; |
||||
int ch = fram.ReadByte(); |
||||
while (ch != EOF) |
||||
if (ch == startCh) { |
||||
int i = 0; |
||||
do { |
||||
if (i == endOfStopString) return; // stop[0..i] found
|
||||
ch = fram.ReadByte(); i++; |
||||
} while (ch == stop[i]); |
||||
// stop[0..i-1] found; continue with last read character
|
||||
gen.Write(stop.Substring(0, i)); |
||||
} else { |
||||
gen.Write((char)ch); ch = fram.ReadByte(); |
||||
} |
||||
Errors.Exception(" -- incomplete or corrupt parser frame file"); |
||||
} |
||||
|
||||
static void CopySourcePart (Position pos, int indent) { |
||||
// Copy text described by pos from atg to gen
|
||||
int ch, nChars, i; |
||||
if (pos != null) { |
||||
Buffer.Pos = pos.beg; ch = Buffer.Read(); nChars = pos.len - 1; |
||||
// CHANGES BY M.KRUEGER (#line pragma generation)
|
||||
gen.WriteLine(); |
||||
gen.WriteLine(String.Format("#line {0} \"{1}\" ", Buffer.CountLines(pos.beg) + 1, Scanner.fileName)); |
||||
// EOC
|
||||
Indent(indent); |
||||
while (nChars >= 0) { |
||||
while (ch == CR || ch == LF) { // eol is either CR or CRLF or LF
|
||||
gen.WriteLine(); Indent(indent); |
||||
if (ch == CR) { ch = Buffer.Read(); nChars--; } // skip CR
|
||||
if (ch == LF) { ch = Buffer.Read(); nChars--; } // skip LF
|
||||
for (i = 1; i <= pos.col && (ch == ' ' || ch == '\t'); i++) { |
||||
// skip blanks at beginning of line
|
||||
ch = Buffer.Read(); nChars--; |
||||
} |
||||
if (i <= pos.col) pos.col = i - 1; // heading TABs => not enough blanks
|
||||
if (nChars < 0) goto done; |
||||
} |
||||
gen.Write((char)ch); |
||||
ch = Buffer.Read(); nChars--; |
||||
} |
||||
done: |
||||
if (indent > 0) gen.WriteLine(); |
||||
} |
||||
} |
||||
|
||||
static void GenErrorMsg (int errTyp, Symbol sym) { |
||||
errorNr++; |
||||
err.Write("\t\t\tcase " + errorNr + ": s = \""); |
||||
switch (errTyp) { |
||||
case tErr: |
||||
if (sym.name[0] == '"') err.Write(DFA.Escape(sym.name) + " expected"); |
||||
else err.Write(sym.name + " expected"); |
||||
break; |
||||
case altErr: err.Write("invalid " + sym.name); break; |
||||
case syncErr: err.Write("this symbol not expected in " + sym.name); break; |
||||
} |
||||
err.WriteLine("\"; break;"); |
||||
} |
||||
|
||||
static int NewCondSet (BitArray s) { |
||||
for (int i = 1; i < symSet.Count; i++) // skip symSet[0] (reserved for union of SYNC sets)
|
||||
if (Sets.Equals(s, (BitArray)symSet[i])) return i; |
||||
symSet.Add(s.Clone()); |
||||
return symSet.Count - 1; |
||||
} |
||||
|
||||
static void GenCond (BitArray s, Node p) { |
||||
if (p.typ == Node.rslv) CopySourcePart(p.pos, 0); |
||||
else { |
||||
int n = Sets.Elements(s); |
||||
if (n == 0) gen.Write("false"); // should never happen
|
||||
else if (n <= maxTerm) |
||||
foreach (Symbol sym in Symbol.terminals) { |
||||
if (s[sym.n]) { |
||||
gen.Write("la.kind == {0}", sym.n); |
||||
--n; |
||||
if (n > 0) gen.Write(" || "); |
||||
} |
||||
} |
||||
else |
||||
gen.Write("StartOf({0})", NewCondSet(s)); |
||||
/* |
||||
if (p.typ == Node.alt) { |
||||
// for { ... | IF ... | ... } or [ ... | IF ... | ... ]
|
||||
// check resolvers in addition to terminal start symbols of alternatives
|
||||
Node q = p; |
||||
while (q != null) { |
||||
if (q.sub.typ == Node.rslv) { |
||||
gen.Write(" || "); |
||||
CopySourcePart(q.sub.pos, 0); |
||||
} |
||||
q = q.down; |
||||
} |
||||
} |
||||
*/ |
||||
} |
||||
} |
||||
|
||||
static void PutCaseLabels (BitArray s) { |
||||
foreach (Symbol sym in Symbol.terminals) |
||||
if (s[sym.n]) gen.Write("case {0}: ", sym.n); |
||||
} |
||||
|
||||
static void GenCode (Node p, int indent, BitArray isChecked) { |
||||
Node p2; |
||||
BitArray s1, s2; |
||||
while (p != null) { |
||||
switch (p.typ) { |
||||
case Node.nt: { |
||||
Indent(indent); |
||||
gen.Write(p.sym.name + "("); |
||||
CopySourcePart(p.pos, 0); |
||||
gen.WriteLine(");"); |
||||
break; |
||||
} |
||||
case Node.t: { |
||||
Indent(indent); |
||||
|
||||
// CHANGES BY M.KRUEGER
|
||||
//if (isChecked[p.sym.n]) gen.WriteLine("Get();");
|
||||
if (isChecked[p.sym.n]) gen.WriteLine("lexer.NextToken();"); |
||||
//EOC
|
||||
else gen.WriteLine("Expect({0});", p.sym.n); |
||||
break; |
||||
} |
||||
case Node.wt: { |
||||
Indent(indent); |
||||
s1 = Tab.Expected(p.next, curSy); |
||||
s1.Or(Tab.allSyncSets); |
||||
gen.WriteLine("ExpectWeak({0}, {1});", p.sym.n, NewCondSet(s1)); |
||||
break; |
||||
} |
||||
case Node.any: { |
||||
Indent(indent); |
||||
// CHANGES BY M.KRUEGER
|
||||
//gen.WriteLine("Get();");
|
||||
gen.WriteLine("lexer.NextToken();"); |
||||
//EOC
|
||||
break; |
||||
} |
||||
case Node.eps: break; // nothing
|
||||
case Node.rslv: break; // nothing
|
||||
case Node.sem: { |
||||
CopySourcePart(p.pos, indent); |
||||
break; |
||||
} |
||||
case Node.sync: { |
||||
Indent(indent); |
||||
GenErrorMsg(syncErr, curSy); |
||||
s1 = (BitArray)p.set.Clone(); |
||||
gen.Write("while (!("); GenCond(s1, p); gen.Write(")) {"); |
||||
// CHANGES BY M.KRUEGER
|
||||
//gen.Write("SynErr({0}); Get();", errorNr);
|
||||
gen.Write("SynErr({0}); lexer.NextToken(); ", errorNr); |
||||
//EOC
|
||||
gen.WriteLine("}"); |
||||
break; |
||||
} |
||||
case Node.alt: { |
||||
s1 = Tab.First(p); |
||||
bool equal = Sets.Equals(s1, isChecked); |
||||
bool useSwitch = UseSwitch(p); |
||||
if (useSwitch) { Indent(indent); gen.WriteLine("switch (la.kind) {"); } |
||||
p2 = p; |
||||
while (p2 != null) { |
||||
s1 = Tab.Expected(p2.sub, curSy); |
||||
Indent(indent); |
||||
if (useSwitch) { |
||||
PutCaseLabels(s1); gen.WriteLine("{"); |
||||
} else if (p2 == p) { |
||||
gen.Write("if ("); GenCond(s1, p2.sub); gen.WriteLine(") {"); |
||||
} else if (p2.down == null && equal) { gen.WriteLine("} else {"); |
||||
} else { |
||||
gen.Write("} else if ("); GenCond(s1, p2.sub); gen.WriteLine(") {"); |
||||
} |
||||
s1.Or(isChecked); |
||||
//if (p2.sub.typ == Node.rslv) GenCode(p2.sub.next, indent + 1, s1);
|
||||
//else GenCode(p2.sub, indent + 1, s1);
|
||||
GenCode(p2.sub, indent + 1, s1); |
||||
if (useSwitch) { |
||||
Indent(indent); gen.WriteLine("\tbreak;"); |
||||
Indent(indent); gen.WriteLine("}"); |
||||
} |
||||
p2 = p2.down; |
||||
} |
||||
Indent(indent); |
||||
if (equal) { |
||||
gen.WriteLine("}"); |
||||
} else { |
||||
GenErrorMsg(altErr, curSy); |
||||
if (useSwitch) { |
||||
gen.WriteLine("default: SynErr({0}); break;", errorNr); |
||||
Indent(indent); gen.WriteLine("}"); |
||||
} else { |
||||
gen.Write("} "); gen.WriteLine("else SynErr({0});", errorNr); |
||||
} |
||||
} |
||||
break; |
||||
} |
||||
case Node.iter: { |
||||
Indent(indent); |
||||
p2 = p.sub; |
||||
gen.Write("while ("); |
||||
if (p2.typ == Node.wt) { |
||||
s1 = Tab.Expected(p2.next, curSy); |
||||
s2 = Tab.Expected(p.next, curSy); |
||||
gen.Write("WeakSeparator({0},{1},{2}) ", p2.sym.n, NewCondSet(s1), NewCondSet(s2)); |
||||
s1 = new BitArray(Symbol.terminals.Count); // for inner structure
|
||||
if (p2.up || p2.next == null) p2 = null; else p2 = p2.next; |
||||
} else { |
||||
s1 = Tab.First(p2); |
||||
GenCond(s1, p2); |
||||
} |
||||
gen.WriteLine(") {"); |
||||
GenCode(p2, indent + 1, s1); |
||||
Indent(indent); gen.WriteLine("}"); |
||||
break; |
||||
} |
||||
case Node.opt: |
||||
//if (p.sub.typ == Node.rslv) s1 = Tab.First(p.sub.next);
|
||||
//else s1 = Tab.First(p.sub);
|
||||
s1 = Tab.First(p.sub); |
||||
Indent(indent); |
||||
gen.Write("if ("); GenCond(s1, p.sub); gen.WriteLine(") {"); |
||||
//if (p.sub.typ == Node.rslv) GenCode(p.sub.next, indent + 1, s1);
|
||||
//else GenCode(p.sub, indent + 1, s1);
|
||||
GenCode(p.sub, indent + 1, s1); |
||||
Indent(indent); gen.WriteLine("}"); |
||||
break; |
||||
} |
||||
if (p.typ != Node.eps && p.typ != Node.sem && p.typ != Node.sync) |
||||
isChecked.SetAll(false); // = new BitArray(Symbol.terminals.Count);
|
||||
if (p.up) break; |
||||
p = p.next; |
||||
} |
||||
} |
||||
|
||||
static void GenTokens() { |
||||
foreach (Symbol sym in Symbol.terminals) { |
||||
if (Char.IsLetter(sym.name[0])) |
||||
gen.WriteLine("\tconst int _{0} = {1};", sym.name, sym.n); |
||||
} |
||||
} |
||||
|
||||
static void GenCodePragmas() { |
||||
foreach (Symbol sym in Symbol.pragmas) { |
||||
gen.WriteLine("\t\t\t\tif (la.kind == {0}) {{", sym.n); |
||||
CopySourcePart(sym.semPos, 4); |
||||
gen.WriteLine("\t\t\t\t}"); |
||||
} |
||||
} |
||||
|
||||
static void GenProductions() { |
||||
foreach (Symbol sym in Symbol.nonterminals) { |
||||
curSy = sym; |
||||
// CHANGES BY M.KRUEGER
|
||||
gen.Write("\t" + productionModifiers + " void {0}(", sym.name); |
||||
// OLD VERSION: gen.Write("\tstatic void {0}(", sym.name);
|
||||
//EOC
|
||||
CopySourcePart(sym.attrPos, 0); |
||||
gen.WriteLine(") {"); |
||||
CopySourcePart(sym.semPos, 2); |
||||
GenCode(sym.graph, 2, new BitArray(Symbol.terminals.Count)); |
||||
gen.WriteLine("\t}"); gen.WriteLine(); |
||||
} |
||||
} |
||||
|
||||
static void InitSets() { |
||||
for (int i = 0; i < symSet.Count; i++) { |
||||
BitArray s = (BitArray)symSet[i]; |
||||
gen.Write("\t\t{"); |
||||
int j = 0; |
||||
foreach (Symbol sym in Symbol.terminals) { |
||||
if (s[sym.n]) gen.Write("T,"); else gen.Write("x,"); |
||||
++j; |
||||
if (j%4 == 0) gen.Write(" "); |
||||
} |
||||
if (i == symSet.Count-1) gen.WriteLine("x}"); else gen.WriteLine("x},"); |
||||
} |
||||
} |
||||
|
||||
static void OpenGen(bool backUp) { /* pdt */ |
||||
try { |
||||
string fn = srcDir + "Parser.cs"; /* pdt */ |
||||
if (File.Exists(fn) && backUp) File.Copy(fn, fn + ".old", true); |
||||
gen = new StreamWriter(new FileStream(fn, FileMode.Create)); /* pdt */ |
||||
} catch (IOException) { |
||||
Errors.Exception("-- Cannot generate parser file"); |
||||
} |
||||
} |
||||
|
||||
public static void WriteParser () { |
||||
symSet.Add(Tab.allSyncSets); |
||||
string fr = srcDir + "Parser.frame"; |
||||
if (!File.Exists(fr)) { |
||||
if (Tab.frameDir != null) fr = Tab.frameDir.Trim() + Path.DirectorySeparatorChar + "Parser.frame"; |
||||
if (!File.Exists(fr)) Errors.Exception("-- Cannot find Parser.frame"); |
||||
} |
||||
try { |
||||
fram = new FileStream(fr, FileMode.Open, FileAccess.Read, FileShare.Read); |
||||
} catch (IOException) { |
||||
Errors.Exception("-- Cannot open Parser.frame."); |
||||
} |
||||
OpenGen(true); /* pdt */ |
||||
err = new StringWriter(); |
||||
foreach (Symbol sym in Symbol.terminals) GenErrorMsg(tErr, sym); |
||||
|
||||
CopyFramePart("-->begin"); |
||||
if (!srcName.ToLower().EndsWith("coco.atg")) { |
||||
gen.Close(); OpenGen(false); /* pdt */ |
||||
} |
||||
if (usingPos != null) {CopySourcePart(usingPos, 0); gen.WriteLine();} |
||||
CopyFramePart("-->namespace"); |
||||
/* AW open namespace, if it exists */ |
||||
if (Tab.nsName != null && Tab.nsName.Length > 0) { |
||||
gen.WriteLine("namespace {0} {{", Tab.nsName); |
||||
gen.WriteLine(); |
||||
} |
||||
CopyFramePart("-->constants"); |
||||
GenTokens(); /* ML 2002/09/07 write the token kinds */ |
||||
gen.WriteLine("\tconst int maxT = {0};", Symbol.terminals.Count-1); |
||||
CopyFramePart("-->declarations"); CopySourcePart(Tab.semDeclPos, 0); |
||||
CopyFramePart("-->pragmas"); GenCodePragmas(); |
||||
CopyFramePart("-->productions"); GenProductions(); |
||||
CopyFramePart("-->parseRoot"); gen.WriteLine("\t\t{0}();", Tab.gramSy.name); |
||||
CopyFramePart("-->initialization"); InitSets(); |
||||
CopyFramePart("-->errors"); gen.Write(err.ToString()); |
||||
CopyFramePart("$$$"); |
||||
/* AW 2002-12-20 close namespace, if it exists */ |
||||
if (Tab.nsName != null && Tab.nsName.Length > 0) gen.Write("}"); |
||||
gen.Close(); |
||||
} |
||||
|
||||
public static void WriteStatistics () { |
||||
Trace.WriteLine(); |
||||
Trace.WriteLine("{0} terminals", Symbol.terminals.Count); |
||||
Trace.WriteLine("{0} symbols", Symbol.terminals.Count + Symbol.pragmas.Count + |
||||
Symbol.nonterminals.Count); |
||||
Trace.WriteLine("{0} nodes", Node.nodes.Count); |
||||
Trace.WriteLine("{0} sets", symSet.Count); |
||||
} |
||||
|
||||
public static void Init (string file, string dir) { |
||||
srcName = file; |
||||
srcDir = dir; |
||||
errorNr = -1; |
||||
usingPos = null; |
||||
} |
||||
|
||||
} // end ParserGen
|
||||
|
||||
} // end namespace
|
||||
@ -1,358 +0,0 @@
@@ -1,358 +0,0 @@
|
||||
/*---------------------------------------------------------------------- |
||||
Compiler Generator Coco/R, |
||||
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz |
||||
extended by M. Loeberbauer & A. Woess, Univ. of Linz |
||||
with improvements by Pat Terry, Rhodes University |
||||
|
||||
This program is free software; you can redistribute it and/or modify it |
||||
under the terms of the GNU General Public License as published by the |
||||
Free Software Foundation; either version 2, or (at your option) any |
||||
later version. |
||||
|
||||
This program is distributed in the hope that it will be useful, but |
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
||||
for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License along |
||||
with this program; if not, write to the Free Software Foundation, Inc., |
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
||||
|
||||
As an exception, it is allowed to write an extension of Coco/R that is |
||||
used as a plugin in non-free software. |
||||
|
||||
If not otherwise stated, any source code generated by Coco/R (other than |
||||
Coco/R itself) does not fall under the GNU General Public License. |
||||
-----------------------------------------------------------------------*/ |
||||
|
||||
using System; |
||||
using System.IO; |
||||
using System.Collections; |
||||
using System.Text; |
||||
|
||||
namespace at.jku.ssw.Coco { |
||||
|
||||
public class Token { |
||||
public int kind; // token kind
|
||||
public int pos; // token position in the source text (starting at 0)
|
||||
public int col; // token column (starting at 0)
|
||||
public int line; // token line (starting at 1)
|
||||
public string val; // token value
|
||||
public Token next; // AW 2003-03-07 Tokens are kept in linked list
|
||||
} |
||||
|
||||
public class Buffer { |
||||
public const char EOF = (char)256; |
||||
static byte[] buf; |
||||
static int bufLen; |
||||
static int pos; |
||||
|
||||
// CHANGES by M.KRUEGER
|
||||
public static int CountLines(int offset) |
||||
{ |
||||
int line = 0; |
||||
for (int i = 0; i <= offset; ++i) { |
||||
if (buf[i] == '\n') { |
||||
++line; |
||||
} |
||||
} |
||||
return line; |
||||
} |
||||
//EOC
|
||||
|
||||
public static void Fill (Stream s) { |
||||
bufLen = (int) s.Length; |
||||
buf = new byte[bufLen]; |
||||
s.Read(buf, 0, bufLen); |
||||
pos = 0; |
||||
} |
||||
|
||||
public static int Read () { |
||||
if (pos < bufLen) return buf[pos++]; |
||||
else return EOF; /* pdt */ |
||||
} |
||||
|
||||
public static int Peek () { |
||||
if (pos < bufLen) return buf[pos]; |
||||
else return EOF; /* pdt */ |
||||
} |
||||
|
||||
/* AW 2003-03-10 moved this from ParserGen.cs */ |
||||
public static string GetString (int beg, int end) { |
||||
StringBuilder s = new StringBuilder(64); |
||||
int oldPos = Buffer.Pos; |
||||
Buffer.Pos = beg; |
||||
while (beg < end) { s.Append((char)Buffer.Read()); beg++; } |
||||
Buffer.Pos = oldPos; |
||||
return s.ToString(); |
||||
} |
||||
|
||||
public static int Pos { |
||||
get { return pos; } |
||||
set { |
||||
if (value < 0) pos = 0; |
||||
else if (value >= bufLen) pos = bufLen; |
||||
else pos = value; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public class Scanner { |
||||
const char EOL = '\n'; |
||||
const int eofSym = 0; /* pdt */ |
||||
const int charSetSize = 256; |
||||
const int maxT = 41; |
||||
const int noSym = 41; |
||||
static short[] start = { |
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||||
0, 0, 11, 0, 10, 0, 0, 5, 29, 20, 0, 14, 0, 15, 28, 0, |
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 27, 17, 13, 18, 0, |
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 0, 22, 0, 0, |
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23, 19, 24, 0, 0, |
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||||
-1}; |
||||
|
||||
|
||||
static Token t; // current token
|
||||
static char ch; // current input character
|
||||
static int pos; // column number of current character
|
||||
static int line; // line number of current character
|
||||
static int lineStart; // start position of current line
|
||||
static int oldEols; // EOLs that appeared in a comment;
|
||||
static BitArray ignore; // set of characters to be ignored by the scanner
|
||||
|
||||
static Token tokens; // the complete input token stream
|
||||
static Token pt; // current peek token
|
||||
|
||||
// CHANGES by M.KRUEGER
|
||||
public static string fileName; |
||||
// EOC
|
||||
|
||||
public static void Init (string fileName) { |
||||
// CHANGES by M.KRUEGER
|
||||
Scanner.fileName = fileName; |
||||
// EOC
|
||||
|
||||
FileStream s = null; |
||||
try { |
||||
s = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); |
||||
Init(s); |
||||
} catch (IOException) { |
||||
Console.WriteLine("--- Cannot open file {0}", fileName); |
||||
System.Environment.Exit(1); |
||||
} finally { |
||||
if (s != null) s.Close(); |
||||
} |
||||
} |
||||
|
||||
public static void Init (Stream s) { |
||||
Buffer.Fill(s); |
||||
pos = -1; line = 1; lineStart = 0; |
||||
oldEols = 0; |
||||
NextCh(); |
||||
ignore = new BitArray(charSetSize+1); |
||||
ignore[9] = true; ignore[10] = true; ignore[13] = true; ignore[32] = true; |
||||
|
||||
//--- AW: fill token list
|
||||
tokens = new Token(); // first token is a dummy
|
||||
Token node = tokens; |
||||
do { |
||||
node.next = NextToken(); |
||||
node = node.next; |
||||
} while (node.kind != eofSym); |
||||
node.next = node; |
||||
node.val = "EOF"; |
||||
t = pt = tokens; |
||||
} |
||||
|
||||
static void NextCh() { |
||||
if (oldEols > 0) { ch = EOL; oldEols--; } |
||||
else { |
||||
ch = (char)Buffer.Read(); pos++; |
||||
// replace isolated '\r' by '\n' in order to make
|
||||
// eol handling uniform across Windows, Unix and Mac
|
||||
if (ch == '\r' && Buffer.Peek() != '\n') ch = EOL; |
||||
if (ch == EOL) { line++; lineStart = pos + 1; } |
||||
} |
||||
|
||||
} |
||||
|
||||
|
||||
static bool Comment0() { |
||||
int level = 1, line0 = line, lineStart0 = lineStart; |
||||
NextCh(); |
||||
if (ch == '*') { |
||||
NextCh(); |
||||
for(;;) { |
||||
if (ch == '*') { |
||||
NextCh(); |
||||
if (ch == '/') { |
||||
level--; |
||||
if (level == 0) { oldEols = line - line0; NextCh(); return true; } |
||||
NextCh(); |
||||
} |
||||
} else if (ch == '/') { |
||||
NextCh(); |
||||
if (ch == '*') { |
||||
level++; NextCh(); |
||||
} |
||||
} else if (ch == Buffer.EOF) return false; |
||||
else NextCh(); |
||||
} |
||||
} else { |
||||
if (ch==EOL) {line--; lineStart = lineStart0;} |
||||
pos = pos - 2; Buffer.Pos = pos+1; NextCh(); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
|
||||
static void CheckLiteral() { |
||||
switch (t.val) { |
||||
case "COMPILER": t.kind = 6; break; |
||||
case "IGNORECASE": t.kind = 7; break; |
||||
case "CHARACTERS": t.kind = 8; break; |
||||
case "TOKENS": t.kind = 9; break; |
||||
case "PRAGMAS": t.kind = 10; break; |
||||
case "COMMENTS": t.kind = 11; break; |
||||
case "FROM": t.kind = 12; break; |
||||
case "TO": t.kind = 13; break; |
||||
case "NESTED": t.kind = 14; break; |
||||
case "IGNORE": t.kind = 15; break; |
||||
case "PRODUCTIONS": t.kind = 16; break; |
||||
case "END": t.kind = 19; break; |
||||
case "ANY": t.kind = 23; break; |
||||
case "WEAK": t.kind = 27; break; |
||||
case "SYNC": t.kind = 34; break; |
||||
case "IF": t.kind = 35; break; |
||||
case "CONTEXT": t.kind = 36; break; |
||||
case "using": t.kind = 39; break; |
||||
default: break; |
||||
} |
||||
} |
||||
|
||||
/* AW Scan() renamed to NextToken() */ |
||||
static Token NextToken() { |
||||
while (ignore[ch]) NextCh(); |
||||
if (ch == '/' && Comment0()) return NextToken(); |
||||
t = new Token(); |
||||
t.pos = pos; t.col = pos - lineStart + 1; t.line = line; |
||||
int state = start[ch]; |
||||
StringBuilder buf = new StringBuilder(16); |
||||
buf.Append(ch); NextCh(); |
||||
|
||||
switch (state) { |
||||
case -1: { t.kind = eofSym; goto done; } // NextCh already done /* pdt */
|
||||
case 0: { t.kind = noSym; goto done; } // NextCh already done
|
||||
case 1: |
||||
if ((ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')) {buf.Append(ch); NextCh(); goto case 1;} |
||||
else {t.kind = 1; t.val = buf.ToString(); CheckLiteral(); return t;} |
||||
case 2: |
||||
if ((ch >= '0' && ch <= '9')) {buf.Append(ch); NextCh(); goto case 2;} |
||||
else {t.kind = 2; goto done;} |
||||
case 3: |
||||
{t.kind = 3; goto done;} |
||||
case 4: |
||||
{t.kind = 4; goto done;} |
||||
case 5: |
||||
if ((ch <= 9 || ch >= 11 && ch <= 12 || ch >= 14 && ch <= '&' || ch >= '(' && ch <= '[' || ch >= ']')) {buf.Append(ch); NextCh(); goto case 6;} |
||||
else if (ch == 92) {buf.Append(ch); NextCh(); goto case 7;} |
||||
else {t.kind = noSym; goto done;} |
||||
case 6: |
||||
if (ch == 39) {buf.Append(ch); NextCh(); goto case 9;} |
||||
else {t.kind = noSym; goto done;} |
||||
case 7: |
||||
if ((ch >= ' ' && ch <= '~')) {buf.Append(ch); NextCh(); goto case 8;} |
||||
else {t.kind = noSym; goto done;} |
||||
case 8: |
||||
if ((ch >= '0' && ch <= '9' || ch >= 'a' && ch <= 'f')) {buf.Append(ch); NextCh(); goto case 8;} |
||||
else if (ch == 39) {buf.Append(ch); NextCh(); goto case 9;} |
||||
else {t.kind = noSym; goto done;} |
||||
case 9: |
||||
{t.kind = 5; goto done;} |
||||
case 10: |
||||
if ((ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')) {buf.Append(ch); NextCh(); goto case 10;} |
||||
else {t.kind = 42; goto done;} |
||||
case 11: |
||||
if ((ch <= 9 || ch >= 11 && ch <= 12 || ch >= 14 && ch <= '!' || ch >= '#' && ch <= '[' || ch >= ']')) {buf.Append(ch); NextCh(); goto case 11;} |
||||
else if ((ch == 10 || ch == 13)) {buf.Append(ch); NextCh(); goto case 4;} |
||||
else if (ch == '"') {buf.Append(ch); NextCh(); goto case 3;} |
||||
else if (ch == 92) {buf.Append(ch); NextCh(); goto case 12;} |
||||
else {t.kind = noSym; goto done;} |
||||
case 12: |
||||
if ((ch >= ' ' && ch <= '~')) {buf.Append(ch); NextCh(); goto case 11;} |
||||
else {t.kind = noSym; goto done;} |
||||
case 13: |
||||
{t.kind = 17; goto done;} |
||||
case 14: |
||||
{t.kind = 20; goto done;} |
||||
case 15: |
||||
{t.kind = 21; goto done;} |
||||
case 16: |
||||
{t.kind = 22; goto done;} |
||||
case 17: |
||||
{t.kind = 24; goto done;} |
||||
case 18: |
||||
{t.kind = 25; goto done;} |
||||
case 19: |
||||
{t.kind = 26; goto done;} |
||||
case 20: |
||||
{t.kind = 29; goto done;} |
||||
case 21: |
||||
{t.kind = 30; goto done;} |
||||
case 22: |
||||
{t.kind = 31; goto done;} |
||||
case 23: |
||||
{t.kind = 32; goto done;} |
||||
case 24: |
||||
{t.kind = 33; goto done;} |
||||
case 25: |
||||
{t.kind = 37; goto done;} |
||||
case 26: |
||||
{t.kind = 38; goto done;} |
||||
case 27: |
||||
{t.kind = 40; goto done;} |
||||
case 28: |
||||
if (ch == '.') {buf.Append(ch); NextCh(); goto case 16;} |
||||
else if (ch == ')') {buf.Append(ch); NextCh(); goto case 26;} |
||||
else {t.kind = 18; goto done;} |
||||
case 29: |
||||
if (ch == '.') {buf.Append(ch); NextCh(); goto case 25;} |
||||
else {t.kind = 28; goto done;} |
||||
|
||||
} |
||||
done: |
||||
t.val = buf.ToString(); |
||||
return t; |
||||
} |
||||
|
||||
/* AW 2003-03-07 get the next token, move on and synch peek token with current */ |
||||
public static Token Scan () { |
||||
t = pt = t.next; |
||||
return t; |
||||
} |
||||
|
||||
/* AW 2003-03-07 get the next token, ignore pragmas */ |
||||
public static Token Peek () { |
||||
do { // skip pragmas while peeking
|
||||
pt = pt.next; |
||||
} while (pt.kind > maxT); |
||||
return pt; |
||||
} |
||||
|
||||
/* AW 2003-03-11 to make sure peek start at current scan position */ |
||||
public static void ResetPeek () { pt = t; } |
||||
|
||||
} // end Scanner
|
||||
|
||||
} |
||||
@ -1,202 +0,0 @@
@@ -1,202 +0,0 @@
|
||||
/*---------------------------------------------------------------------- |
||||
Compiler Generator Coco/R, |
||||
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz |
||||
extended by M. Loeberbauer & A. Woess, Univ. of Linz |
||||
with improvements by Pat Terry, Rhodes University |
||||
|
||||
This program is free software; you can redistribute it and/or modify it |
||||
under the terms of the GNU General Public License as published by the |
||||
Free Software Foundation; either version 2, or (at your option) any |
||||
later version. |
||||
|
||||
This program is distributed in the hope that it will be useful, but |
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
||||
for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License along |
||||
with this program; if not, write to the Free Software Foundation, Inc., |
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
||||
|
||||
As an exception, it is allowed to write an extension of Coco/R that is |
||||
used as a plugin in non-free software. |
||||
|
||||
If not otherwise stated, any source code generated by Coco/R (other than |
||||
Coco/R itself) does not fall under the GNU General Public License. |
||||
-----------------------------------------------------------------------*/ |
||||
-->begin |
||||
using System; |
||||
using System.IO; |
||||
using System.Collections; |
||||
using System.Text; |
||||
|
||||
-->namespace |
||||
|
||||
public class Token { |
||||
public int kind; // token kind |
||||
public int pos; // token position in the source text (starting at 0) |
||||
public int col; // token column (starting at 0) |
||||
public int line; // token line (starting at 1) |
||||
public string val; // token value |
||||
public Token next; // AW 2003-03-07 Tokens are kept in linked list |
||||
} |
||||
|
||||
public class Buffer { |
||||
public const char EOF = (char)256; |
||||
static byte[] buf; |
||||
static int bufLen; |
||||
static int pos; |
||||
// CHANGES by M.KRUEGER |
||||
public static int CountLines(int offset) |
||||
{ |
||||
int line = 0; |
||||
for (int i = 0; i <= offset; ++i) { |
||||
if (buf[i] == '\n') { |
||||
++line; |
||||
} |
||||
} |
||||
return line; |
||||
} |
||||
//EOC |
||||
public static void Fill (Stream s) { |
||||
bufLen = (int) s.Length; |
||||
buf = new byte[bufLen]; |
||||
s.Read(buf, 0, bufLen); |
||||
pos = 0; |
||||
} |
||||
|
||||
public static int Read () { |
||||
if (pos < bufLen) return buf[pos++]; |
||||
else return EOF; /* pdt */ |
||||
} |
||||
|
||||
public static int Peek () { |
||||
if (pos < bufLen) return buf[pos]; |
||||
else return EOF; /* pdt */ |
||||
} |
||||
|
||||
/* AW 2003-03-10 moved this from ParserGen.cs */ |
||||
public static string GetString (int beg, int end) { |
||||
StringBuilder s = new StringBuilder(64); |
||||
int oldPos = Buffer.Pos; |
||||
Buffer.Pos = beg; |
||||
while (beg < end) { s.Append((char)Buffer.Read()); beg++; } |
||||
Buffer.Pos = oldPos; |
||||
return s.ToString(); |
||||
} |
||||
|
||||
public static int Pos { |
||||
get { return pos; } |
||||
set { |
||||
if (value < 0) pos = 0; |
||||
else if (value >= bufLen) pos = bufLen; |
||||
else pos = value; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public class Scanner { |
||||
const char EOL = '\n'; |
||||
const int eofSym = 0; /* pdt */ |
||||
-->declarations |
||||
|
||||
static Token t; // current token |
||||
static char ch; // current input character |
||||
static int pos; // column number of current character |
||||
static int line; // line number of current character |
||||
static int lineStart; // start position of current line |
||||
static int oldEols; // EOLs that appeared in a comment; |
||||
static BitArray ignore; // set of characters to be ignored by the scanner |
||||
|
||||
static Token tokens; // the complete input token stream |
||||
static Token pt; // current peek token |
||||
|
||||
public static void Init (string fileName) { |
||||
FileStream s = null; |
||||
try { |
||||
s = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); |
||||
Init(s); |
||||
} catch (IOException) { |
||||
Console.WriteLine("--- Cannot open file {0}", fileName); |
||||
System.Environment.Exit(1); |
||||
} finally { |
||||
if (s != null) s.Close(); |
||||
} |
||||
} |
||||
|
||||
public static void Init (Stream s) { |
||||
Buffer.Fill(s); |
||||
pos = -1; line = 1; lineStart = 0; |
||||
oldEols = 0; |
||||
NextCh(); |
||||
-->initialization |
||||
//--- AW: fill token list |
||||
tokens = new Token(); // first token is a dummy |
||||
Token node = tokens; |
||||
do { |
||||
node.next = NextToken(); |
||||
node = node.next; |
||||
} while (node.kind != eofSym); |
||||
node.next = node; |
||||
node.val = "EOF"; |
||||
t = pt = tokens; |
||||
} |
||||
|
||||
static void NextCh() { |
||||
if (oldEols > 0) { ch = EOL; oldEols--; } |
||||
else { |
||||
ch = (char)Buffer.Read(); pos++; |
||||
// replace isolated '\r' by '\n' in order to make |
||||
// eol handling uniform across Windows, Unix and Mac |
||||
if (ch == '\r' && Buffer.Peek() != '\n') ch = EOL; |
||||
if (ch == EOL) { line++; lineStart = pos + 1; } |
||||
} |
||||
-->casing |
||||
} |
||||
|
||||
-->comments |
||||
|
||||
static void CheckLiteral() { |
||||
-->literals |
||||
} |
||||
|
||||
/* AW Scan() renamed to NextToken() */ |
||||
static Token NextToken() { |
||||
while (ignore[ch]) NextCh(); |
||||
-->scan1 |
||||
t = new Token(); |
||||
t.pos = pos; t.col = pos - lineStart + 1; t.line = line; |
||||
int state = start[ch]; |
||||
StringBuilder buf = new StringBuilder(16); |
||||
-->scan2 |
||||
|
||||
switch (state) { |
||||
case -1: { t.kind = eofSym; goto done; } // NextCh already done /* pdt */ |
||||
case 0: { t.kind = noSym; goto done; } // NextCh already done |
||||
-->scan3 |
||||
} |
||||
done: |
||||
t.val = buf.ToString(); |
||||
return t; |
||||
} |
||||
|
||||
/* AW 2003-03-07 get the next token, move on and synch peek token with current */ |
||||
public static Token Scan () { |
||||
t = pt = t.next; |
||||
return t; |
||||
} |
||||
|
||||
/* AW 2003-03-07 get the next token, ignore pragmas */ |
||||
public static Token Peek () { |
||||
do { // skip pragmas while peeking |
||||
pt = pt.next; |
||||
} while (pt.kind > maxT); |
||||
return pt; |
||||
} |
||||
|
||||
/* AW 2003-03-11 to make sure peek start at current scan position */ |
||||
public static void ResetPeek () { pt = t; } |
||||
|
||||
} // end Scanner |
||||
|
||||
$$$ |
||||
@ -1,53 +0,0 @@
@@ -1,53 +0,0 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup> |
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
||||
<ProductVersion>8.0.40607</ProductVersion> |
||||
<SchemaVersion>2.0</SchemaVersion> |
||||
<ProjectGuid>{b87ee2f4-80bd-476a-8d49-a0bb415b6021}</ProjectGuid> |
||||
<RootNamespace>NewProject</RootNamespace> |
||||
<AssemblyName>SharpCoco</AssemblyName> |
||||
<OutputTarget>Exe</OutputTarget> |
||||
<WarningLevel>4</WarningLevel> |
||||
<NoStdLib>False</NoStdLib> |
||||
<NoConfig>False</NoConfig> |
||||
<RunPostBuildEvent>OnSuccessfulBuild</RunPostBuildEvent> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
||||
<DebugSymbols>True</DebugSymbols> |
||||
<Optimize>True</Optimize> |
||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks> |
||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> |
||||
<OutputPath>..\bin\Debug\</OutputPath> |
||||
<TreatWarningsAsErrors>False</TreatWarningsAsErrors> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
||||
<DebugSymbols>True</DebugSymbols> |
||||
<Optimize>True</Optimize> |
||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks> |
||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> |
||||
<OutputPath>..\bin\Release\</OutputPath> |
||||
<TreatWarningsAsErrors>False</TreatWarningsAsErrors> |
||||
</PropertyGroup> |
||||
<ItemGroup> |
||||
<Reference Include="System" /> |
||||
<Reference Include="System.Data" /> |
||||
<Reference Include="System.Drawing" /> |
||||
<Reference Include="System.Windows.Forms" /> |
||||
<Reference Include="System.Xml" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Compile Include="Coco.cs" /> |
||||
<Compile Include="AssemblyInfo.cs" /> |
||||
<Compile Include="DFA.cs" /> |
||||
<Compile Include="Parser.cs" /> |
||||
<Compile Include="Scanner.cs" /> |
||||
<Compile Include="Tab.cs" /> |
||||
<Compile Include="Trace.cs" /> |
||||
<Compile Include="ParserGen.cs" /> |
||||
<None Include="Parser.frame" /> |
||||
<None Include="Scanner.frame" /> |
||||
<None Include="Coco.atg" /> |
||||
</ItemGroup> |
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" /> |
||||
</Project> |
||||
@ -1,6 +0,0 @@
@@ -1,6 +0,0 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
||||
<StartArguments>CS.ATG</StartArguments> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " /> |
||||
</Project> |
||||
File diff suppressed because it is too large
Load Diff
@ -1,69 +0,0 @@
@@ -1,69 +0,0 @@
|
||||
/*------------------------------------------------------------------------- |
||||
Trace.cs -- Trace Output Class |
||||
Compiler Generator Coco/R, |
||||
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz |
||||
extended by M. Loeberbauer & A. Woess, Univ. of Linz |
||||
with improvements by Pat Terry, Rhodes University |
||||
|
||||
This program is free software; you can redistribute it and/or modify it |
||||
under the terms of the GNU General Public License as published by the |
||||
Free Software Foundation; either version 2, or (at your option) any |
||||
later version. |
||||
|
||||
This program is distributed in the hope that it will be useful, but |
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
||||
for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License along |
||||
with this program; if not, write to the Free Software Foundation, Inc., |
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
||||
|
||||
As an exception, it is allowed to write an extension of Coco/R that is |
||||
used as a plugin in non-free software. |
||||
|
||||
If not otherwise stated, any source code generated by Coco/R (other than |
||||
Coco/R itself) does not fall under the GNU General Public License. |
||||
-------------------------------------------------------------------------*/ |
||||
using System; |
||||
using System.IO; |
||||
|
||||
namespace at.jku.ssw.Coco { |
||||
|
||||
class Trace { |
||||
static string fileName; /* pdt */ |
||||
static StreamWriter trace; |
||||
|
||||
public static void Init (String dir) { |
||||
fileName = dir + "trace.txt"; /* pdt */ |
||||
try { |
||||
trace = new StreamWriter(new FileStream(fileName, FileMode.Create)); |
||||
} catch (IOException) { |
||||
Errors.Exception("-- could not open " + fileName); |
||||
} |
||||
} |
||||
|
||||
public static void Write (string s) { trace.Write(s); } |
||||
|
||||
public static void Write (string s, params object[] args) { |
||||
trace.Write(s, args); |
||||
} |
||||
|
||||
public static void WriteLine (string s) { trace.WriteLine(s); } |
||||
|
||||
public static void WriteLine (string s, params object[] args) { |
||||
trace.WriteLine(s, args); |
||||
} |
||||
|
||||
public static void WriteLine () { trace.WriteLine(); } |
||||
|
||||
public static void Close () { /* pdt */ |
||||
trace.Close(); |
||||
FileInfo f = new FileInfo(fileName); |
||||
if (f.Length == 0) f.Delete(); |
||||
else Console.WriteLine("trace output is in " + fileName); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue