parser.cs
来自「全功能c#编译器」· CS 代码 · 共 765 行 · 第 1/2 页
CS
765 行
using System.Collections;
using System.Text;
using System;
using System.Reflection;
namespace at.jku.ssw.Coco {
public class Parser {
const int maxT = 42;
const bool T = true;
const bool x = false;
const int minErrDist = 2;
const string errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text
static Token t; // last recognized token
static Token la; // lookahead token
static int errDist = minErrDist;
const int id = 0;
const int str = 1;
static bool genScanner;
/*-------------------------------------------------------------------------*/
static void SynErr (int n) {
if (errDist >= minErrDist) Errors.SynErr(la.line, la.col, n);
errDist = 0;
}
public static void SemErr (string msg) {
if (errDist >= minErrDist) Errors.Error(t.line, t.col, msg);
errDist = 0;
}
static void Get () {
for (;;) {
t = la;
la = Scanner.Scan();
if (la.kind <= maxT) { ++errDist; break; } /* ML return changed to break */
if (la.kind == 43) {
Tab.SetDDT(la.val);
}
la = t;
}
}
static void Expect (int n) {
if (la.kind==n) Get(); else { SynErr(n); }
}
static bool StartOf (int s) {
return set[s, la.kind];
}
static void ExpectWeak (int n, int follow) {
if (la.kind == n) Get();
else {
SynErr(n);
while (!StartOf(follow)) Get();
}
}
static bool WeakSeparator (int n, int syFol, int repFol) {
bool[] s = new bool[maxT+1];
if (la.kind == n) { Get(); return true; }
else if (StartOf(repFol)) return false;
else {
for (int i=0; i <= maxT; i++) {
s[i] = set[syFol, i] || set[repFol, i] || set[0, i];
}
SynErr(n);
while (!s[la.kind]) Get();
return StartOf(syFol);
}
}
static void Coco() {
Symbol sym; Graph g; string gramName;
if (la.kind == 40) {
UsingDecl(out ParserGen.usingPos);
}
Expect(6);
int gramLine = t.line;
genScanner = true;
bool ok = true;
Tab.ignored = null;
Expect(1);
gramName = t.val;
int beg = la.pos;
while (StartOf(1)) {
Get();
}
Tab.semDeclPos = new Position(beg, la.pos-beg, 0);
while (StartOf(2)) {
Declaration();
}
while (!(la.kind == 0 || la.kind == 7)) {SynErr(43); Get();}
Expect(7);
if (genScanner) DFA.MakeDeterministic();
Graph.DeleteNodes();
while (la.kind == 1) {
Get();
sym = Symbol.Find(t.val);
bool undef = sym == null;
if (undef) sym = new Symbol(Node.nt, t.val, t.line);
else {
if (sym.typ == Node.nt) {
if (sym.graph != null) SemErr("name declared twice");
} else SemErr("this symbol kind not allowed on left side of production");
sym.line = t.line;
}
bool noAttrs = sym.attrPos == null;
sym.attrPos = null;
if (la.kind == 24) {
AttrDecl(sym);
}
if (!undef)
if (noAttrs != (sym.attrPos == null))
SemErr("attribute mismatch between declaration and use of this symbol");
if (la.kind == 38) {
SemText(out sym.semPos);
}
ExpectWeak(8, 3);
Expression(out g);
sym.graph = g.l;
Graph.Finish(g);
ExpectWeak(9, 4);
}
Expect(10);
Expect(1);
if (gramName != t.val)
SemErr("name does not match grammar name");
Tab.gramSy = Symbol.Find(gramName);
if (Tab.gramSy == null)
SemErr("missing production for grammar name");
else {
sym = Tab.gramSy;
if (sym.attrPos != null)
SemErr("grammar symbol must not have attributes");
}
Tab.noSym = new Symbol(Node.t, "???", 0); // noSym gets highest number
Tab.SetupAnys();
Tab.RenumberPragmas();
if (Tab.ddt[2]) Node.PrintNodes();
if (Errors.count == 0) {
Console.WriteLine("checking");
Tab.CompSymbolSets();
ok = ok && Tab.GrammarOk();
if (Tab.ddt[7]) Tab.XRef();
if (ok) {
Console.Write("parser");
ParserGen.WriteParser();
if (genScanner) {
Console.Write(" + scanner");
DFA.WriteScanner();
if (Tab.ddt[0]) DFA.PrintStates();
}
Console.WriteLine(" generated");
if (Tab.ddt[8]) ParserGen.WriteStatistics();
}
}
if (Tab.ddt[6]) Tab.PrintSymbolTable();
Expect(9);
}
static void UsingDecl(out Position pos) {
Expect(40);
int beg = t.pos;
while (StartOf(5)) {
Get();
}
Expect(41);
int end = t.pos;
while (la.kind == 40) {
Get();
while (StartOf(5)) {
Get();
}
Expect(41);
end = t.pos;
}
pos = new Position(beg, end - beg + 1, 0);
}
static void Declaration() {
Graph g1, g2; bool nested = false;
switch (la.kind) {
case 11: {
Get();
while (la.kind == 1) {
SetDecl();
}
break;
}
case 12: {
Get();
while (la.kind == 1 || la.kind == 3 || la.kind == 5) {
TokenDecl(Node.t);
}
break;
}
case 13: {
Get();
while (la.kind == 1 || la.kind == 3 || la.kind == 5) {
TokenDecl(Node.pr);
}
break;
}
case 14: {
Get();
Expect(15);
TokenExpr(out g1);
Expect(16);
TokenExpr(out g2);
if (la.kind == 17) {
Get();
nested = true;
} else if (StartOf(6)) {
nested = false;
} else SynErr(44);
new Comment(g1.l, g2.l, nested);
break;
}
case 18: {
Get();
Set(out Tab.ignored);
Tab.ignored[' '] = true; /* ' ' is always ignored */
if (Tab.ignored[0]) SemErr("may not ignore \'\\0\'");
break;
}
case 19: {
Get();
Symbol.tokenNames = new Hashtable();
while (la.kind == 1 || la.kind == 3) {
if (la.kind == 3) {
Get();
} else {
Get();
}
string key = t.val;
Expect(8);
Expect(1);
string val = t.val; Symbol.tokenNames.Add(key, val);
}
break;
}
default: SynErr(45); break;
}
}
static void AttrDecl(Symbol sym) {
Expect(24);
int beg = la.pos; int col = la.col;
while (StartOf(7)) {
if (la.kind == 24) {
AttrDecl(sym);
} else if (StartOf(8)) {
Get();
} else {
Get();
SemErr("bad string in semantic action");
}
}
Expect(25);
sym.attrPos = new Position(beg, t.pos - beg, col);
}
static void SemText(out Position pos) {
Expect(38);
int beg = la.pos; int col = la.col;
while (StartOf(9)) {
if (StartOf(10)) {
Get();
} else if (la.kind == 4) {
Get();
SemErr("bad string in semantic action");
} else {
Get();
SemErr("missing end of previous semantic action");
}
}
Expect(39);
pos = new Position(beg, t.pos - beg, col);
}
static void Expression(out Graph g) {
Graph g2;
Term(out g);
bool first = true;
while (WeakSeparator(26,11,12) ) {
Term(out g2);
if (first) { Graph.MakeFirstAlt(g); first = false; }
Graph.MakeAlternative(g, g2);
}
}
static void SetDecl() {
BitArray s;
Expect(1);
string name = t.val;
CharClass c = CharClass.Find(name);
if (c != null) SemErr("name declared twice");
Expect(8);
Set(out s);
if (Sets.Elements(s) == 0) SemErr("character set must not be empty");
c = new CharClass(name, s);
Expect(9);
}
static void TokenDecl(int typ) {
string name; int kind; Symbol sym; Graph g;
Sym(out name, out kind);
sym = Symbol.Find(name);
if (sym != null) SemErr("name declared twice");
else {
sym = new Symbol(typ, name, t.line);
sym.tokenKind = Symbol.classToken;
}
while (!(StartOf(13))) {SynErr(46); Get();}
if (la.kind == 8) {
Get();
TokenExpr(out g);
Expect(9);
if (kind != id) SemErr("a literal must not be declared with a structure");
Graph.Finish(g);
DFA.ConvertToStates(g.l, sym);
} else if (la.kind == 9) {
Get();
if (typ != Node.rslv) SemErr("resolver is only allowed in RESOLVERS section");
} else if (StartOf(14)) {
if (kind == id) genScanner = false;
else DFA.MatchLiteral(sym);
} else SynErr(47);
if (la.kind == 38) {
SemText(out sym.semPos);
if (typ == Node.t) SemErr("semantic action not allowed here");
} else if (StartOf(15)) {
if (typ == Node.rslv) SemErr("resolvers must have a semantic action");
} else SynErr(48);
}
static void TokenExpr(out Graph g) {
Graph g2;
TokenTerm(out g);
bool first = true;
while (WeakSeparator(26,16,17) ) {
TokenTerm(out g2);
if (first) { Graph.MakeFirstAlt(g); first = false; }
Graph.MakeAlternative(g, g2);
}
}
static void Set(out BitArray s) {
BitArray s2;
SimSet(out s);
while (la.kind == 20 || la.kind == 21) {
if (la.kind == 20) {
Get();
SimSet(out s2);
s.Or(s2);
} else {
Get();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?