⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.cs

📁 c#源代码
💻 CS
📖 第 1 页 / 共 2 页
字号:
/*----------------------------------------------------------------------
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.
----------------------------------------------------------------------*/
using System.Collections;

using System;

namespace at.jku.ssw.Coco {



public class Parser {
	const int _EOF = 0;
	const int _ident = 1;
	const int _number = 2;
	const int _string = 3;
	const int _badString = 4;
	const int _char = 5;
	const int maxT = 41;

	const bool T = true;
	const bool x = false;
	const int minErrDist = 2;

	public static Token t;    // last recognized token
	public static Token la;   // lookahead token
	static int errDist = minErrDist;

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

/*-------------------------------------------------------------------------*/



	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; }
				if (la.kind == 42) {
				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, g1, g2; string gramName; 
		if (la.kind == 39) {
			UsingDecl(out ParserGen.usingPos);
		}
		Expect(6);
		genScanner = 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); 
		if (la.kind == 7) {
			Get();
			DFA.ignoreCase = true; 
		}
		if (la.kind == 8) {
			Get();
			while (la.kind == 1) {
				SetDecl();
			}
		}
		if (la.kind == 9) {
			Get();
			while (la.kind == 1 || la.kind == 3 || la.kind == 5) {
				TokenDecl(Node.t);
			}
		}
		if (la.kind == 10) {
			Get();
			while (la.kind == 1 || la.kind == 3 || la.kind == 5) {
				TokenDecl(Node.pr);
			}
		}
		while (la.kind == 11) {
			Get();
			bool nested = false; 
			Expect(12);
			TokenExpr(out g1);
			Expect(13);
			TokenExpr(out g2);
			if (la.kind == 14) {
				Get();
				nested = true; 
			}
			new Comment(g1.l, g2.l, nested); 
		}
		while (la.kind == 15) {
			Get();
			Set(out Tab.ignored);
			Tab.ignored[' '] = true; /* ' ' is always ignored */ 
		}
		while (!(la.kind == 0 || la.kind == 16)) {SynErr(42); Get();}
		Expect(16);
		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 == 37) {
				SemText(out sym.semPos);
			}
			ExpectWeak(17, 2);
			Expression(out g);
			sym.graph = g.l;
			Graph.Finish(g);
			
			ExpectWeak(18, 3);
		}
		Expect(19);
		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();
		  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();
		
		Expect(18);
	}

	static void UsingDecl(out Position pos) {
		Expect(39);
		int beg = t.pos; 
		while (StartOf(4)) {
			Get();
		}
		Expect(40);
		int end = t.pos; 
		while (la.kind == 39) {
			Get();
			while (StartOf(4)) {
				Get();
			}
			Expect(40);
			end = t.pos; 
		}
		pos = new Position(beg, end - beg + 1, 0); 
	}

	static void SetDecl() {
		BitArray s; 
		Expect(1);
		string name = t.val;
		CharClass c = CharClass.Find(name);
		if (c != null) SemErr("name declared twice");
		
		Expect(17);
		Set(out s);
		if (Sets.Elements(s) == 0) SemErr("character set must not be empty");
		c = new CharClass(name, s);
		
		Expect(18);
	}

	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.fixedToken;
		}
		tokenString = null;
		
		while (!(StartOf(5))) {SynErr(43); Get();}
		if (la.kind == 17) {
			Get();
			TokenExpr(out g);
			Expect(18);
			if (kind == str) SemErr("a literal must not be declared with a structure");
			Graph.Finish(g);
			if (tokenString == null || tokenString.Equals(noString))
			  DFA.ConvertToStates(g.l, sym);
			else { // TokenExpr is a single string
			  if (Tab.literals[tokenString] != null)
			    SemErr("token string declared twice");
			  Tab.literals[tokenString] = sym;
			  DFA.MatchLiteral(tokenString, sym);
			}
			
		} else if (StartOf(6)) {
			if (kind == id) genScanner = false;
			else DFA.MatchLiteral(sym.name, sym);
			
		} else SynErr(44);
		if (la.kind == 37) {
			SemText(out sym.semPos);
			if (typ != Node.pr) SemErr("semantic action not allowed here"); 
		}
	}

	static void TokenExpr(out Graph g) {
		Graph g2; 
		TokenTerm(out g);
		bool first = true; 
		while (WeakSeparator(26,7,8) ) {
			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();
				SimSet(out s2);
				Sets.Subtract(s, s2); 
			}
		}
	}

	static void AttrDecl(Symbol sym) {
		Expect(24);
		int beg = la.pos; int col = la.col; 
		while (StartOf(9)) {
			// CHANGES BY M.KRUEGER
			if (la.kind == 24) {
				AttrDecl(sym);
			} else 
			// EOC
			if (StartOf(10)) {
				Get();
			} else {
				Get();
				SemErr("bad string in attributes"); 
			}
		}
		Expect(25);
		if (t.pos > beg)
		 sym.attrPos = new Position(beg, t.pos - beg, col); 
	}

	static void SemText(out Position pos) {
		Expect(37);
		int beg = la.pos; int col = la.col; 
		while (StartOf(11)) {
			if (StartOf(12)) {
				Get();
			} else if (la.kind == 4) {
				Get();
				SemErr("bad string in semantic action"); 
			} else {
				Get();
				SemErr("missing end of previous semantic action"); 
			}
		}
		Expect(38);
		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,13,14) ) {
			Term(out g2);
			if (first) { Graph.MakeFirstAlt(g); first = false; }
			Graph.MakeAlternative(g, g2);
			
		}
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -