📄 coco.atg
字号:
/*-------------------------------------------------------------------------
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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -