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