📄 coco.atg
字号:
/* ------------------------------------------------------------------------
* Coco.ATG
* Attributed grammer of Coco/R
* by H. Moessenboeck, Univ. of Linz
* extended by
* M. Loeberbauer & A. Woess, Univ. of Linz
* ------------------------------------------------------------------------*/
using System.Collections;
using System.Text;
COMPILER Coco
const int id = 0;
const int str = 1;
static bool genScanner;
/*-------------------------------------------------------------------------*/
CHARACTERS
letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".
digit = "0123456789".
cr = '\r'.
lf = '\n'.
tab = '\t'.
stringCh = ANY - '"' - '\\' - cr - lf.
charCh = ANY - '\'' - '\\' - cr - lf.
printable = '\u0020' .. '\u007e'.
hex = "0123456789abcdef".
IGNORE cr + lf + tab
TOKENS
ident = letter { letter | digit }.
number = digit { digit }.
string = '"' { stringCh | '\\' printable } '"'.
badString = '"' { stringCh | '\\' printable } (cr | lf).
char = '\'' ( charCh | '\\' printable { hex } ) '\''.
PRAGMAS
ddtSym = '$' { digit | letter }. (. Tab.SetDDT(la.val); .)
COMMENTS FROM "/*" TO "*/" NESTED
/*-------------------------------------------------------------------------*/
PRODUCTIONS
Coco (. Symbol sym; Graph g; string gramName; .)
=
[ UsingDecl<out ParserGen.usingPos> ]
"COMPILER" (. int gramLine = t.line;
genScanner = true;
bool ok = true;
Tab.ignored = null;
.)
ident (. gramName = t.val;
int beg = la.pos;
.)
{ ANY } (. Tab.semDeclPos = new Position(beg, la.pos-beg, 0); .)
{ Declaration }
SYNC
"PRODUCTIONS" (. if (genScanner) DFA.MakeDeterministic();
Graph.DeleteNodes();
.)
{ ident (. sym = Symbol.Find(t.val);
bool undef = sym == null;
if (undef) sym = new Symbol(Node.nt, t.val, t.line);
else {
if (sym.typ == Node.nt) {
if (sym.graph != null) SemErr("name declared twice");
} else SemErr("this symbol kind not allowed on left side of production");
sym.line = t.line;
}
bool noAttrs = sym.attrPos == null;
sym.attrPos = null;
.)
[ AttrDecl<sym> ] (. if (!undef)
if (noAttrs != (sym.attrPos == null))
SemErr("attribute mismatch between declaration and use of this symbol");
.)
[ SemText<out sym.semPos> ] WEAK
'='
Expression<out g> (. sym.graph = g.l;
Graph.Finish(g);
.)
WEAK
'.'
}
"END" ident (. if (gramName != t.val)
SemErr("name does not match grammar name");
Tab.gramSy = Symbol.Find(gramName);
if (Tab.gramSy == null)
SemErr("missing production for grammar name");
else {
sym = Tab.gramSy;
if (sym.attrPos != null)
SemErr("grammar symbol must not have attributes");
}
Tab.noSym = new Symbol(Node.t, "???", 0); // noSym gets highest number
Tab.SetupAnys();
Tab.RenumberPragmas();
if (Tab.ddt[2]) Node.PrintNodes();
if (Errors.count == 0) {
Console.WriteLine("checking");
Tab.CompSymbolSets();
ok = ok && Tab.GrammarOk();
if (Tab.ddt[7]) Tab.XRef();
if (ok) {
Console.Write("parser");
ParserGen.WriteParser();
if (genScanner) {
Console.Write(" + scanner");
DFA.WriteScanner();
if (Tab.ddt[0]) DFA.PrintStates();
}
Console.WriteLine(" generated");
if (Tab.ddt[8]) ParserGen.WriteStatistics();
}
}
if (Tab.ddt[6]) Tab.PrintSymbolTable();
.)
'.'
.
/*------------------------------------------------------------------------------------*/
Declaration (. Graph g1, g2; bool nested = false; .)
=
"CHARACTERS" { SetDecl }
| "TOKENS" { TokenDecl<Node.t> }
| "PRAGMAS" { TokenDecl<Node.pr> }
| "COMMENTS"
"FROM" TokenExpr<out g1>
"TO" TokenExpr<out g2>
( "NESTED" (. nested = true; .)
| (. nested = false; .)
) (. new Comment(g1.l, g2.l, nested); .)
| "IGNORE" Set<out Tab.ignored> (. Tab.ignored[' '] = true; /* ' ' is always ignored */
if (Tab.ignored[0]) SemErr("may not ignore \'\\0\'"); .)
| "TOKENNAMES" (. Symbol.tokenNames = new Hashtable(); .)
{ ( string | ident ) (. string key = t.val; .)
"=" ident (. string val = t.val; Symbol.tokenNames.Add(key, val); .)
}
.
/*------------------------------------------------------------------------------------*/
SetDecl (. BitArray s; .)
=
ident (. string name = t.val;
CharClass c = CharClass.Find(name);
if (c != null) SemErr("name declared twice");
.)
'=' Set<out s> (. if (Sets.Elements(s) == 0) SemErr("character set must not be empty");
c = new CharClass(name, s);
.)
'.'
.
/*------------------------------------------------------------------------------------*/
Set<out BitArray s> (. BitArray s2; .)
=
SimSet<out s>
{ '+' SimSet<out s2> (. s.Or(s2); .)
| '-' SimSet<out s2> (. Sets.Subtract(s, s2); .)
}
.
/*------------------------------------------------------------------------------------*/
SimSet<out BitArray s> (. int n1, n2; .)
= (. s = new BitArray(CharClass.charSetSize); .)
( ident (. CharClass c = CharClass.Find(t.val);
if (c == null) SemErr("undefined name"); else s.Or(c.set);
.)
| string (. string name = t.val;
name = DFA.Unescape(name.Substring(1, name.Length-2));
foreach (char ch in name) s[ch] = true;
.)
| Char<out n1> (. s[n1] = true; .)
[ ".." Char<out n2> (. for (int i = n1; i <= n2; i++) s[i] = true; .)
]
| "ANY" (. s = new BitArray(CharClass.charSetSize, true);
s[0] = false;
.)
)
.
/*--------------------------------------------------------------------------------------*/
Char<out int n>
=
char (. string name = t.val;
name = DFA.Unescape(name.Substring(1, name.Length-2));
int max = CharClass.charSetSize;
if (name.Length != 1 || name[0] > max-1) SemErr("unacceptable character value");
n = name[0] % max;
.)
.
/*------------------------------------------------------------------------------------*/
TokenDecl<int typ> (. string name; int kind; Symbol sym; Graph g; .)
=
Sym<out name, out kind> (. sym = Symbol.Find(name);
if (sym != null) SemErr("name declared twice");
else {
sym = new Symbol(typ, name, t.line);
sym.tokenKind = Symbol.classToken;
}
.)
SYNC
( '=' TokenExpr<out g> '.' (. if (kind != id) SemErr("a literal must not be declared with a structure");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -