📄 parser.java
字号:
package Coco;
import java.util.*;
class Parser {
private static final int maxT = 43;
private static final int maxP = 44;
private static final boolean T = true;
private static final boolean x = false;
private static final int minErrDist = 2;
private static int errDist = minErrDist;
static Token token; // last recognized token
static Token t; // lookahead token
private static final int ident = 0;
private static final int string = 1;
private static boolean genScanner = true, ignoreCase = false, genNames = false;
private static void MatchLiteral(int sp) {
// store string either as token or as literal
Symbol sym, sym1;
int matchedSp;
sym = Tab.Sym(sp);
matchedSp = DFA.MatchedDFA(sym.name, sp);
if (matchedSp == Tab.noSym) sym.struct = Tab.classToken;
else {
sym1 = Tab.Sym(matchedSp); sym1.struct = Tab.classLitToken;
sym.struct = Tab.litToken;
}
}
private static void SetCtx(int p) {
// set transition code to contextTrans
GraphNode n;
while (p > 0) {
n = Tab.Node(p);
if (n.typ == Tab.chr || n.typ == Tab.clas) {
n.p2 = Tab.contextTrans;
} else if (n.typ == Tab.opt || n.typ == Tab.iter) {
SetCtx(n.p1);
} else if (n.typ == Tab.alt) {
SetCtx(n.p1); SetCtx(n.p2);
}
p = n.next;
}
}
private static void SetDDT(String s) {
char ch;
for (int i = 1; i < s.length(); i++) {
ch = s.charAt(i);
if (Character.isDigit(ch)) Tab.ddt[Character.digit(ch, 10)] = true;
}
}
private static String FixString(String s) {
if (ignoreCase) s = s.toUpperCase();
char[] a = s.toCharArray();
int len = a.length;
if (len == 2) SemError(29);
boolean dbl = false, spaces = false;
for (int i = 0; i < len-1; i++)
if (a[i] == '"') dbl = true; else if (a[i] <= ' ') spaces = true;
if (!dbl) {a[0] = '"'; a[len-1] = '"';}
if (spaces) SemError(24);
return new String(a, 0, len);
}
/*-------------------------------------------------------------------------*/
static void Error(int n) {
if (errDist >= minErrDist) Scanner.err.ParsErr(n, t.line, t.col);
errDist = 0;
}
static void SemError(int n) {
if (errDist >= minErrDist) Scanner.err.SemErr(n, token.line, token.col);
errDist = 0;
}
static boolean Successful() {
return Scanner.err.count == 0;
}
static String LexString() {
return token.str;
}
static String LexName() {
return token.val;
}
static String LookAheadString() {
return t.str;
}
static String LookAheadName() {
return t.val;
}
private static void Get() {
for (;;) {
token = t;
t = Scanner.Scan();
if (t.kind <= maxT) {errDist++; return;}
if (t.kind == 44) {
SetDDT(t.val);
}
t = token;
}
}
private static void Expect(int n) {
if (t.kind == n) Get(); else Error(n);
}
private static boolean StartOf(int s) {
return set[s][t.kind];
}
private static void ExpectWeak(int n, int follow) {
if (t.kind == n) Get();
else {
Error(n);
while (!StartOf(follow)) Get();
}
}
private static boolean WeakSeparator(int n, int syFol, int repFol) {
boolean[] s = new boolean[maxT+1];
if (t.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];
}
Error(n);
while (!s[t.kind]) Get();
return StartOf(syFol);
}
}
private static void AttrRest1(GraphNode n) {
int beg, col;
beg = t.pos; col = t.col;
while (StartOf(1)) {
if (StartOf(2)) {
Get();
} else {
Get();
SemError(2);
}
}
Expect(34);
if (token.pos > beg) {
n.pos = new Position();
n.pos.beg = beg; n.pos.col = col;
n.pos.len = token.pos - beg;
}
}
private static void AttrRest(GraphNode n) {
int beg, col;
beg = t.pos; col = t.col;
while (StartOf(3)) {
if (StartOf(4)) {
Get();
} else {
Get();
SemError(2);
}
}
Expect(32);
if (token.pos > beg) {
n.pos = new Position();
n.pos.beg = beg; n.pos.col = col;
n.pos.len = token.pos - beg;
}
}
private static Graph TokenFactor() {
Graph g;
String name; int kind, c; SymInfo s;
g = new Graph();
if (t.kind == 1 || t.kind == 2) {
s = Symbol();
if (s.kind == ident) {
c = Tab.ClassWithName(s.name);
if (c < 0) {
SemError(15);
c = Tab.NewClass(s.name, new BitSet());
}
g.l = Tab.NewNode(Tab.clas, c, 0);
g.r = g.l;
} else /*string*/ g = Tab.StrToGraph(s.name);
} else if (t.kind == 25) {
Get();
g = TokenExpr();
Expect(26);
} else if (t.kind == 29) {
Get();
g = TokenExpr();
Expect(30);
g = Tab.Option(g);
} else if (t.kind == 37) {
Get();
g = TokenExpr();
Expect(38);
g = Tab.Iteration(g);
} else Error(44);
return g;
}
private static Graph TokenTerm() {
Graph g;
Graph g2;
g = TokenFactor();
while (StartOf(5)) {
g2 = TokenFactor();
g = Tab.Sequence(g, g2);
}
if (t.kind == 40) {
Get();
Expect(25);
g2 = TokenExpr();
SetCtx(g2.l); g = Tab.Sequence(g, g2);
Expect(26);
}
return g;
}
private static void Attribs1(GraphNode n) {
int beg, col;
Expect(33);
if (t.kind == 28) {
Get();
beg = t.pos;
while (StartOf(6)) {
if (StartOf(7)) {
Get();
} else {
Get();
SemError(2);
}
}
n.retVar = ParserGen.GetString(beg, t.pos);
if (t.kind == 31) {
Get();
AttrRest1(n);
} else if (t.kind == 34) {
Get();
} else Error(45);
} else if (StartOf(8)) {
AttrRest1(n);
} else Error(46);
}
private static void Attribs(GraphNode n) {
int beg, col;
Expect(27);
if (t.kind == 28) {
Get();
beg = t.pos;
while (StartOf(9)) {
if (StartOf(10)) {
Get();
} else {
Get();
SemError(2);
}
}
n.retVar = ParserGen.GetString(beg, t.pos);
if (t.kind == 31) {
Get();
AttrRest(n);
} else if (t.kind == 32) {
Get();
} else Error(47);
} else if (StartOf(8)) {
AttrRest(n);
} else Error(48);
}
private static Graph Factor() {
Graph g;
GraphNode n;
SymInfo s;
Symbol sym;
Position pos;
BitSet set;
int sp, typ;
boolean undef, weak = false;
g = new Graph(); weak = false;
switch (t.kind) {
case 1: case 2: case 36: {
if (t.kind == 36) {
Get();
weak = true;
}
s = Symbol();
sp = Tab.FindSym(s.name); undef = sp == Tab.noSym;
if (undef) {
if (s.kind == ident)
sp = Tab.NewSym(Tab.nt, s.name, 0); // forward nt
else if (genScanner) {
sp = Tab.NewSym(Tab.t, s.name, token.line);
MatchLiteral(sp);
} else { // undefined string in production
SemError(6); sp = 0;
}
}
sym = Tab.Sym(sp); typ = sym.typ;
if (typ != Tab.t && typ != Tab.nt) SemError(4);
if (weak)
if (sym.typ == Tab.t) typ = Tab.wt; else SemError(23);
g.l = Tab.NewNode(typ, sp, token.line); g.r = g.l;
n = Tab.Node(g.l);
if (t.kind == 27 || t.kind == 33) {
if (t.kind == 27) {
Attribs(n);
} else {
Attribs1(n);
}
if (typ != Tab.nt) SemError(3);
}
if (undef) {
sym.attrPos = n.pos; sym.retVar = n.retVar; // dummies
} else
if (n.pos != null && sym.attrPos == null
|| n.retVar != null && sym.retVar == null
|| n.pos == null && sym.attrPos != null
|| n.retVar == null && sym.retVar != null) SemError(5);
break;
}
case 25: {
Get();
g = Expression();
Expect(26);
break;
}
case 29: {
Get();
g = Expression();
Expect(30);
g = Tab.Option(g);
break;
}
case 37: {
Get();
g = Expression();
Expect(38);
g = Tab.Iteration(g);
break;
}
case 41: {
pos = SemText();
g.l = Tab.NewNode(Tab.sem, 0, 0);
g.r = g.l;
n = Tab.Node(g.l); n.pos = pos;
break;
}
case 23: {
Get();
set = Sets.FullSet(Tab.maxTerminals);
set.clear(Tab.eofSy);
g.l = Tab.NewNode(Tab.any, Tab.NewSet(set), 0);
g.r = g.l;
break;
}
case 39: {
Get();
g.l = Tab.NewNode(Tab.sync, 0, 0);
g.r = g.l;
break;
}
default: Error(49);
}
return g;
}
private static Graph Term() {
Graph g;
Graph g2;
g = null;
if (StartOf(11)) {
g = Factor();
while (StartOf(11)) {
g2 = Factor();
g = Tab.Sequence(g, g2);
}
} else if (StartOf(12)) {
g = new Graph();
g.l = Tab.NewNode(Tab.eps, 0, 0);
g.r = g.l;
} else Error(50);
return g;
}
private static SymInfo Symbol() {
SymInfo s;
s = new SymInfo();
if (t.kind == 1) {
Get();
s.kind = ident;
} else if (t.kind == 2) {
Get();
s.kind = string;
} else Error(51);
s.name = token.val;
if (s.kind == string) s.name = FixString(s.name);
return s;
}
private static int SingleChar() {
int n;
Expect(24);
Expect(25);
Expect(4);
n = Integer.parseInt(token.val, 10);
if (n > 127) SemError(18); n %= 128;
if (ignoreCase && n >= 'a' && n <= 'z') n -= 32;
Expect(26);
return n;
}
private static BitSet SimSet() {
BitSet s;
String name; int c, n1, n2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -