Click here to Skip to main content
Click here to Skip to main content
Articles » Languages » C# » General » Downloads
 
Add your own
alternative version

Coco Custom Tool for Visual Studio.NET

, 29 Oct 2005
Use the award winning Coco compiler's compiler directly from within Visual Studio
vscoco.zip
vsCoco
bin
VsCoco.dll
vsCoco.tlb
vsCocoRegistration.exe
Calculator
App.ico
Calc.atg
Calculator.csproj.user
Calculator.suo
VsCoCo
vsCoco.png
Coco
Coco.atg
Parser.frame
Scanner.frame
CustomToolGenerator
vsCoco
VsCoco.csproj.user
vsCocoRegistration
reg.ico
Thumbs.db
vsCocoRegistration.csproj.user
// Compiled by vsCoco on 29/10/2005 11:38:56
/*----------------------------------------------------------------------
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.
----------------------------------------------------------------------*/

//------------------------------------------------------------------------------
// <autogenerated>
//     This code was generated by COCO from Parser.frame.
//     Changes to this file may cause incorrect behavior and will be lost if 
//     the code is regenerated.
// </autogenerated>
//------------------------------------------------------------------------------

using System;
using System.IO;
using System.Collections;

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 int _ddtSym = 42;

		const bool T = true;
		const bool x = false;
		const int minErrDist = 2;
		
		public Scanner scanner;
		public Errors  errors;

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

const int id = 0;
	const int str = 1;
	
	public TextWriter trace;    // other Coco objects referenced in this ATG
	public Tab tab;
	public DFA dfa;
	public ParserGen pgen;

	bool   genScanner;
	string tokenString;         // used in declarations of literal tokens
	string noString = "-none-"; // used in declarations of literal tokens

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


		public Parser(Scanner scanner) {
			this.scanner = scanner;
			errors = new Errors(scanner);
		}

		public Parser(System.IO.Stream str) {
			scanner = new Scanner(str);
			errors = new Errors(scanner);
		}
		
		public Parser(string source) {
			MemoryStream memIn = new MemoryStream();
			byte[] b=System.Text.Encoding.ASCII.GetBytes(source);
			memIn.Write(b,0,b.Length);
			memIn.Seek(0,0);
			this.scanner = new Scanner(memIn);
			errors = new Errors(scanner);
		}

		void SynErr (int n) {
			if (errDist >= minErrDist) errors.SynErr(la.line, la.col, n);
			errDist = 0;
		}

		public void SemErr (string msg) {
			if (errDist >= minErrDist) errors.Error(t.line, t.col, msg);
			errDist = 0;
		}
		
		void Get () {
			for (;;) {
				t = la;
				la = scanner.Scan();
				if (la.kind <= maxT) { ++errDist; break; }
				if (la.kind == 42) {
				tab.SetDDT(la.val); 
				}

				la = t;
			}
		}
		
		void Expect (int n) {
			if (la.kind==n) Get(); else { SynErr(n); }
		}
		
		bool StartOf (int s) {
			return set[s, la.kind];
		}
		
		void ExpectWeak (int n, int follow) {
			if (la.kind == n) Get();
			else {
				SynErr(n);
				while (!StartOf(follow)) Get();
			}
		}
		
		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);
			}
		}
		
	void Coco() {
		Symbol sym; Graph g, g1, g2; string gramName; BitArray s; 
		if (la.kind == 39) {
			UsingDecl(out pgen.usingPos);
		}
		Expect(6);
		genScanner = true; 
		tab.ignored = new BitArray(CharClass.charSetSize); 
		Expect(1);
		gramName = t.val;
		int beg = la.pos; 
		
		while (StartOf(1)) {
			Get();
		}
		tab.semDeclPos = new Position(beg, la.pos-beg,0, 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; 
			}
			dfa.NewComment(g1.l, g2.l, nested); 
		}
		while (la.kind == 15) {
			Get();
			Set(out s);
			tab.ignored.Or(s); 
		}
		while (!(la.kind == 0 || la.kind == 16)) {SynErr(42); Get();}
		Expect(16);
		if (genScanner) dfa.MakeDeterministic();
		tab.DeleteNodes();
		
		while (la.kind == 1) {
			Get();
			sym = tab.FindSym(t.val);
			bool undef = sym == null;
			if (undef) sym = tab.NewSym(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;
			tab.Finish(g);
			
			ExpectWeak(18, 3);
		}
		Expect(19);
		Expect(1);
		if (gramName != t.val)
		 SemErr("name does not match grammar name");
		tab.gramSy = tab.FindSym(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 = tab.NewSym(Node.t, "???", 0); // noSym gets highest number
		tab.SetupAnys();
		tab.RenumberPragmas();
		if (tab.ddt[2]) tab.PrintNodes();
		if (errors.count == 0) {
		  scanner.WriteLine("");
		  scanner.WriteLine("------ Checking grammar...");
		  scanner.WriteLine("");
		  tab.CompSymbolSets();
		  if (tab.ddt[7]) tab.XRef();
		  if (tab.GrammarOk()) {
		    scanner.WriteLine("");
		    scanner.WriteLine("------ Generating parser...");
		    scanner.WriteLine("");
		pgen.WriteParser();
		                           if (genScanner) {
		                             scanner.WriteLine("");
		scanner.WriteLine("------ Generating scanner...");
		                              scanner.WriteLine("");
		dfa.WriteScanner();
		                              if (tab.ddt[0]) dfa.PrintStates();
		                            }
		                            scanner.WriteLine("");
		                            scanner.WriteLine("------ Compilation completed.");
		                            scanner.WriteLine("");
		                            if (tab.ddt[8]) pgen.WriteStatistics();
		                          }
		                        }
		                        if (tab.ddt[6]) tab.PrintSymbolTable();
		                      
		Expect(18);
	}

	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, 0); 
	}

	void SetDecl() {
		BitArray s; 
		Expect(1);
		string name = t.val;
		CharClass c = tab.FindCharClass(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");
		tab.NewCharClass(name, s);
		
		Expect(18);
	}

	void TokenDecl(int typ) {
		string name; int kind; Symbol sym; Graph g; 
		Sym(out name, out kind);
		sym = tab.FindSym(name);
		if (sym != null) SemErr("name declared twice");
		else {
		  sym = tab.NewSym(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");
			tab.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"); 
		}
	}

	void TokenExpr(out Graph g) {
		Graph g2; 
		TokenTerm(out g);
		bool first = true; 
		while (WeakSeparator(26,7,8) ) {
			TokenTerm(out g2);
			if (first) { tab.MakeFirstAlt(g); first = false; }
			tab.MakeAlternative(g, g2);
			
		}
	}

	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); 
			}
		}
	}

	void AttrDecl(Symbol sym) {
		Expect(24);
		int beg = la.pos; int lin = la.line; int col = la.col; 
		while (StartOf(9)) {
			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, lin, col); 
	}

	void SemText(out Position pos) {
		Expect(37);
		int beg = la.pos; int lin = la.line; 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, lin, col); 
	}

	void Expression(out Graph g) {
		Graph g2; 
		Term(out g);
		bool first = true; 
		while (WeakSeparator(26,13,14) ) {
			Term(out g2);
			if (first) { tab.MakeFirstAlt(g); first = false; }
			tab.MakeAlternative(g, g2);
			
		}
	}

	void SimSet(out BitArray s) {
		int n1, n2; 
		s = new BitArray(CharClass.charSetSize); 
		if (la.kind == 1) {
			Get();
			CharClass c = tab.FindCharClass(t.val);
			if (c == null) SemErr("undefined name"); else s.Or(c.set);
			
		} else if (la.kind == 3) {
			Get();
			string name = t.val;
			name = tab.Unescape(name.Substring(1, name.Length-2));
			foreach (char ch in name)
			  if (dfa.ignoreCase) s[char.ToLower(ch)] = true;
			  else s[ch] = true; 
		} else if (la.kind == 5) {
			Char(out n1);
			s[n1] = true; 
			if (la.kind == 22) {
				Get();
				Char(out n2);
				for (int i = n1; i <= n2; i++) s[i] = true; 
			}
		} else if (la.kind == 23) {
			Get();
			s = new BitArray(CharClass.charSetSize, true); 
		} else SynErr(45);
	}

	void Char(out int n) {
		Expect(5);
		string name = t.val; n = 0;
		name = tab.Unescape(name.Substring(1, name.Length-2));
		int max = CharClass.charSetSize;
		if (name.Length == 1 && name[0] <= max-1) n = name[0] % max;
		else SemErr("unacceptable character value");
		if (dfa.ignoreCase && (char)n >= 'A' && (char)n <= 'Z') n += 32;
		
	}

	void Sym(out string name, out int kind) {
		name = "???"; kind = id; 
		if (la.kind == 1) {
			Get();
			kind = id; name = t.val; 
		} else if (la.kind == 3 || la.kind == 5) {
			if (la.kind == 3) {
				Get();
				name = t.val; 
			} else {
				Get();
				name = "\"" + t.val.Substring(1, t.val.Length-2) + "\""; 
			}
			kind = str;
			if (dfa.ignoreCase) name = name.ToLower();
			if (name.IndexOf(' ') >= 0)
			  SemErr("literal tokens must not contain blanks"); 
		} else SynErr(46);
	}

	void Term(out Graph g) {
		Graph g2; Node rslv = null; g = null; 
		if (StartOf(15)) {
			if (la.kind == 35) {
				rslv = tab.NewNode(Node.rslv, null, la.line); 
				Resolver(out rslv.pos);
				g = new Graph(rslv); 
			}
			Factor(out g2);
			if (rslv != null) tab.MakeSequence(g, g2);
			else g = g2;
			
			while (StartOf(16)) {
				Factor(out g2);
				tab.MakeSequence(g, g2); 
			}
		} else if (StartOf(17)) {
			g = new Graph(tab.NewNode(Node.eps, null, 0)); 
		} else SynErr(47);
		if (g == null) // invalid start of Term
		 g = new Graph(tab.NewNode(Node.eps, null, 0));
		
	}

	void Resolver(out Position pos) {
		Expect(35);
		Expect(28);
		int beg = la.pos; int lin = la.line; int col = la.col; 
		Condition();
		pos = new Position(beg, t.pos - beg, lin, col); 
	}

	void Factor(out Graph g) {
		string name; int kind; Position pos; bool weak = false; 
		g = null;
		
		switch (la.kind) {
		case 1: case 3: case 5: case 27: {
			if (la.kind == 27) {
				Get();
				weak = true; 
			}
			Sym(out name, out kind);
			Symbol sym = tab.FindSym(name);
			if (sym == null && kind == str)
			  sym = tab.literals[name] as Symbol;
			bool undef = sym == null;
			if (undef) {
			  if (kind == id)
			    sym = tab.NewSym(Node.nt, name, 0);  // forward nt
			  else if (genScanner) { 
			    sym = tab.NewSym(Node.t, name, t.line);
			    dfa.MatchLiteral(sym.name, sym);
			  } else {  // undefined string in production
			    SemErr("undefined string in production");
			    sym = tab.eofSy;  // dummy
			  }
			}
			int typ = sym.typ;
			if (typ != Node.t && typ != Node.nt)
			  SemErr("this symbol kind is not allowed in a production");
			if (weak)
			  if (typ == Node.t) typ = Node.wt;
			  else SemErr("only terminals may be weak");
			Node p = tab.NewNode(typ, sym, t.line);
			g = new Graph(p);
			
			if (la.kind == 24) {
				Attribs(p);
				if (kind != id) SemErr("a literal must not have attributes"); 
			}
			if (undef)
			 sym.attrPos = p.pos;  // dummy
			else if ((p.pos == null) != (sym.attrPos == null))
			  SemErr("attribute mismatch between declaration and use of this symbol");
			
			break;
		}
		case 28: {
			Get();
			Expression(out g);
			Expect(29);
			break;
		}
		case 30: {
			Get();
			Expression(out g);
			Expect(31);
			tab.MakeOption(g); 
			break;
		}
		case 32: {
			Get();
			Expression(out g);
			Expect(33);
			tab.MakeIteration(g); 
			break;
		}
		case 37: {
			SemText(out pos);
			Node p = tab.NewNode(Node.sem, null, 0);
			p.pos = pos;
			g = new Graph(p);
			
			break;
		}
		case 23: {
			Get();
			Node p = tab.NewNode(Node.any, null, 0);  // p.set is set in tab.SetupAnys
			g = new Graph(p);
			
			break;
		}
		case 34: {
			Get();
			Node p = tab.NewNode(Node.sync, null, 0);
			g = new Graph(p);
			
			break;
		}
		default: SynErr(48); break;
		}
		if (g == null) // invalid start of Factor
		 g = new Graph(tab.NewNode(Node.eps, null, 0));
		
	}

	void Attribs(Node p) {
		Expect(24);
		int beg = la.pos; int lin = la.line; int col = la.col; 
		while (StartOf(9)) {
			if (StartOf(10)) {
				Get();
			} else {
				Get();
				SemErr("bad string in attributes"); 
			}
		}
		Expect(25);
		if (t.pos > beg) p.pos = new Position(beg, t.pos - beg, lin, col); 
	}

	void Condition() {
		while (StartOf(18)) {
			if (la.kind == 28) {
				Get();
				Condition();
			} else {
				Get();
			}
		}
		Expect(29);
	}

	void TokenTerm(out Graph g) {
		Graph g2; 
		TokenFactor(out g);
		while (StartOf(7)) {
			TokenFactor(out g2);
			tab.MakeSequence(g, g2); 
		}
		if (la.kind == 36) {
			Get();
			Expect(28);
			TokenExpr(out g2);
			tab.SetContextTrans(g2.l); dfa.hasCtxMoves = true;
			tab.MakeSequence(g, g2); 
			Expect(29);
		}
	}

	void TokenFactor(out Graph g) {
		string name; int kind; 
		g = null; 
		if (la.kind == 1 || la.kind == 3 || la.kind == 5) {
			Sym(out name, out kind);
			if (kind == id) {
			 CharClass c = tab.FindCharClass(name);
			 if (c == null) {
			   SemErr("undefined name");
			   c = tab.NewCharClass(name, new BitArray(CharClass.charSetSize));
			 }
			 Node p = tab.NewNode(Node.clas, null, 0); p.val = c.n;
			 g = new Graph(p);
			 tokenString = noString;
			} else { // str
			  g = tab.StrToGraph(name);
			  if (tokenString == null) tokenString = name;
			  else tokenString = noString;
			}
			
		} else if (la.kind == 28) {
			Get();
			TokenExpr(out g);
			Expect(29);
		} else if (la.kind == 30) {
			Get();
			TokenExpr(out g);
			Expect(31);
			tab.MakeOption(g); 
		} else if (la.kind == 32) {
			Get();
			TokenExpr(out g);
			Expect(33);
			tab.MakeIteration(g); 
		} else SynErr(49);
		if (g == null) // invalid start of TokenFactor
		 g = new Graph(tab.NewNode(Node.eps, null, 0)); 
	}


		public void Parse() {
			la = new Token();
			la.val = "";		
			Get();
		Coco();

		Expect(0);
		}
		
		bool[,] set = {
		{T,T,x,T, x,T,x,x, x,x,T,T, x,x,x,T, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x},
		{x,T,T,T, T,T,T,x, x,x,x,x, T,T,T,x, x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,x},
		{T,T,x,T, x,T,x,x, x,x,T,T, x,x,x,T, T,T,T,x, x,x,x,T, x,x,T,T, T,x,T,x, T,x,T,T, x,T,x,x, x,x,x},
		{T,T,x,T, x,T,x,x, x,x,T,T, x,x,x,T, T,T,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x},
		{x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, x,T,x},
		{T,T,x,T, x,T,x,x, x,x,T,T, x,x,x,T, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x},
		{x,T,x,T, x,T,x,x, x,x,T,T, x,x,x,T, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x},
		{x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,T,x, T,x,x,x, x,x,x,x, x,x,x},
		{x,x,x,x, x,x,x,x, x,x,x,T, x,T,T,T, T,x,T,x, x,x,x,x, x,x,x,x, x,T,x,T, x,T,x,x, x,x,x,x, x,x,x},
		{x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,x},
		{x,T,T,T, x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,x},
		{x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,x,T, T,T,x},
		{x,T,T,T, x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,x,T, T,T,x},
		{x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,T, x,x,T,T, T,T,T,T, T,T,T,T, x,T,x,x, x,x,x},
		{x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,T,x,T, x,T,x,x, x,x,x,x, x,x,x},
		{x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,T, T,x,T,x, T,x,T,T, x,T,x,x, x,x,x},
		{x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,T, T,x,T,x, T,x,T,x, x,T,x,x, x,x,x},
		{x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,T,x, x,T,x,T, x,T,x,x, x,x,x,x, x,x,x},
		{x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,T,T, T,T,T,T, T,T,T,T, T,T,x}

		};
	} // end Parser


	public class Errors {
		public int count = 0;                                    // number of errors detected
		public string errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text
		private Scanner scanner;

		public Errors(Scanner scanner)
		{
			this.scanner=scanner;
		}
		
		public void SynErr (int line, int col, int n) {
			string s;
			switch (n) {
			case 0: s = "EOF expected"; break;
			case 1: s = "ident expected"; break;
			case 2: s = "number expected"; break;
			case 3: s = "string expected"; break;
			case 4: s = "badString expected"; break;
			case 5: s = "char expected"; break;
			case 6: s = "\"COMPILER\" expected"; break;
			case 7: s = "\"IGNORECASE\" expected"; break;
			case 8: s = "\"CHARACTERS\" expected"; break;
			case 9: s = "\"TOKENS\" expected"; break;
			case 10: s = "\"PRAGMAS\" expected"; break;
			case 11: s = "\"COMMENTS\" expected"; break;
			case 12: s = "\"FROM\" expected"; break;
			case 13: s = "\"TO\" expected"; break;
			case 14: s = "\"NESTED\" expected"; break;
			case 15: s = "\"IGNORE\" expected"; break;
			case 16: s = "\"PRODUCTIONS\" expected"; break;
			case 17: s = "\"=\" expected"; break;
			case 18: s = "\".\" expected"; break;
			case 19: s = "\"END\" expected"; break;
			case 20: s = "\"+\" expected"; break;
			case 21: s = "\"-\" expected"; break;
			case 22: s = "\"..\" expected"; break;
			case 23: s = "\"ANY\" expected"; break;
			case 24: s = "\"<\" expected"; break;
			case 25: s = "\">\" expected"; break;
			case 26: s = "\"|\" expected"; break;
			case 27: s = "\"WEAK\" expected"; break;
			case 28: s = "\"(\" expected"; break;
			case 29: s = "\")\" expected"; break;
			case 30: s = "\"[\" expected"; break;
			case 31: s = "\"]\" expected"; break;
			case 32: s = "\"{\" expected"; break;
			case 33: s = "\"}\" expected"; break;
			case 34: s = "\"SYNC\" expected"; break;
			case 35: s = "\"IF\" expected"; break;
			case 36: s = "\"CONTEXT\" expected"; break;
			case 37: s = "\"(.\" expected"; break;
			case 38: s = "\".)\" expected"; break;
			case 39: s = "\"using\" expected"; break;
			case 40: s = "\";\" expected"; break;
			case 41: s = "??? expected"; break;
			case 42: s = "this symbol not expected in Coco"; break;
			case 43: s = "this symbol not expected in TokenDecl"; break;
			case 44: s = "invalid TokenDecl"; break;
			case 45: s = "invalid SimSet"; break;
			case 46: s = "invalid Sym"; break;
			case 47: s = "invalid Term"; break;
			case 48: s = "invalid Factor"; break;
			case 49: s = "invalid TokenFactor"; break;

				default: s = "error " + n; break;
			}
			Error(line, col, s);
		}

		public virtual void Error (int lin, int col, string err) {
			scanner.WriteError(errMsgFormat,scanner.srcFile,lin,col,err);
			count++;
		}

	} // Errors

}/*----------------------------------------------------------------------
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.
-----------------------------------------------------------------------*/

//------------------------------------------------------------------------------
// <autogenerated>
//     This code was generated by COCO from Scanner.frame.
//     Changes to this file may cause incorrect behavior and will be lost if 
//     the code is regenerated.
// </autogenerated>
//------------------------------------------------------------------------------

namespace at.jku.ssw.Coco {

	public class Token {
		public int kind;    // token kind
		public int pos;     // token position in the source text (starting at 0)
		public int col;     // token column (starting at 0)
		public int line;    // token line (starting at 1)
		public string val;  // token value
		public Token next;  // ML 2005-03-11 Tokens are kept in linked list
	}

	public class Buffer {
		public const char EOF = (char)256;
		const int MAX_BUFFER_LENGTH = 64 * 1024; // 64KB
		byte[] buf;         // input buffer
		int bufStart;       // position of first byte in buffer relative to input stream
		int bufLen;         // length of buffer
		int fileLen;        // length of input stream
		int pos;            // current position in buffer
		Stream stream;      // input stream (seekable)
		bool isUserStream;  // was the stream opened by the user?
		
		public Buffer (Stream s, bool isUserStream) {
			stream = s; this.isUserStream = isUserStream;
			fileLen = bufLen = (int) s.Length;
			if (stream.CanSeek && bufLen > MAX_BUFFER_LENGTH) bufLen = MAX_BUFFER_LENGTH;
			buf = new byte[bufLen];
			bufStart = Int32.MaxValue; // nothing in the buffer so far
			Pos = 0; // setup buffer to position 0 (start)
			if (bufLen == fileLen) Close();
		}
		
		~Buffer() { Close(); }
		
		void Close() {
			if (!isUserStream && stream != null) {
				stream.Close();
				stream = null;
			}
		}
		
		public int Read () {
			if (pos < bufLen) {
				return buf[pos++];
			} else if (Pos < fileLen) {
				Pos = Pos; // shift buffer start to Pos
				return buf[pos++];
			} else {
				return EOF;
			}
		}

		public int Peek () {
			if (pos < bufLen) {
				return buf[pos];
			} else if (Pos < fileLen) {
				Pos = Pos; // shift buffer start to Pos
				return buf[pos];
			} else {
				return EOF;
			}
		}
		
		public string GetString (int beg, int end) {
			int len = end - beg;
			char[] buf = new char[len];
			int oldPos = Pos;
			Pos = beg;
			for (int i = 0; i < len; i++) buf[i] = (char) Read();
			Pos = oldPos;
			return new String(buf);
		}

		public int Pos {
			get { return pos + bufStart; }
			set {
				if (value < 0) value = 0; 
				else if (value > fileLen) value = fileLen;
				if (value >= bufStart && value < bufStart + bufLen) { // already in buffer
					pos = value - bufStart;
				} else if (stream != null) { // must be swapped in
					stream.Seek(value, SeekOrigin.Begin);
					bufLen = stream.Read(buf, 0, buf.Length);
					bufStart = value; pos = 0;
				} else {
					pos = fileLen - bufStart; // make Pos return fileLen
				}
			}
		}
	}

	public class Scanner {
		const char EOL = '\n';
		const int eofSym = 0; /* pdt */
	const int charSetSize = 256;
	const int maxT = 41;
	const int noSym = 41;
	short[] start = {
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	  0,  0, 11,  0, 10,  0,  0,  5, 29, 20,  0, 14,  0, 15, 28,  0,
	  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  0, 27, 17, 13, 18,  0,
	  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
	  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 21,  0, 22,  0,  0,
	  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
	  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 23, 19, 24,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	  -1};


		public Buffer buffer; // scanner buffer
		public string srcFile;
		
		Token t;          // current token
		char ch;          // current input character
		int pos;          // column number of current character
		int line;         // line number of current character
		int lineStart;    // start position of current line
		int oldEols;      // EOLs that appeared in a comment;
		BitArray ignore;  // set of characters to be ignored by the scanner
		Token tokens;     // list of tokens already peeked (first token is a dummy)
		Token pt;         // current peek token
		
		char[] tval = new char[128]; // text of current token
		int tlen;         // length of current token
		
		public Scanner (string fileName) {
			srcFile=fileName;
			try {
				Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
				buffer = new Buffer(stream, false);
				Init();
			} catch (IOException) {
				throw new Exception(String.Format("--- Cannot open file {0}", fileName));
			}
		}
		
		public Scanner (Stream s) {
			buffer = new Buffer(s, true);
			Init();
		}
		
		public virtual void WriteLine(string s) 
		{
			Console.WriteLine(s);
		}
		
		public virtual void Write(string s) 
		{
			Console.Write(s);
		}
		
		public virtual void WriteError(string fmt,string file, int lin, int col, string err)
		{
			Console.WriteLine(string.Format(fmt,new object[] {file, lin, col, err}));
		}

		
		void Init() {
			pos = -1; line = 1; lineStart = 0;
			oldEols = 0;
			NextCh();
			ignore = new BitArray(charSetSize+1);
			ignore[' '] = true;  // blanks are always white space
		ignore[9] = true; ignore[10] = true; ignore[13] = true; 
			pt = tokens = new Token();  // first token is a dummy
		}
		
		void NextCh() {
			if (oldEols > 0) { ch = EOL; oldEols--; } 
			else {
				ch = (char)buffer.Read(); pos++;
				// replace isolated '\r' by '\n' in order to make
				// eol handling uniform across Windows, Unix and Mac
				if (ch == '\r' && buffer.Peek() != '\n') ch = EOL;
				if (ch == EOL) { line++; lineStart = pos + 1; }
			}

		}

		void AddCh() {
			if (tlen >= tval.Length) {
				char[] newBuf = new char[2 * tval.Length];
				Array.Copy(tval, 0, newBuf, 0, tval.Length);
				tval = newBuf;
			}
		tval[tlen++] = ch;
			NextCh();
		}



	bool Comment0() {
		int level = 1, line0 = line, lineStart0 = lineStart;
		NextCh();
		if (ch == '/') {
			NextCh();
			for(;;) {
				if (ch == 13) {
					NextCh();
					if (ch == 10) {
						level--;
						if (level == 0) { oldEols = line - line0; NextCh(); return true; }
						NextCh();
					}
				} else if (ch == Buffer.EOF) return false;
				else NextCh();
			}
		} else {
			if (ch==EOL) {line--; lineStart = lineStart0;}
			pos = pos - 2; buffer.Pos = pos+1; NextCh();
		}
		return false;
	}

	bool Comment1() {
		int level = 1, line0 = line, lineStart0 = lineStart;
		NextCh();
		if (ch == '*') {
			NextCh();
			for(;;) {
				if (ch == '*') {
					NextCh();
					if (ch == '/') {
						level--;
						if (level == 0) { oldEols = line - line0; NextCh(); return true; }
						NextCh();
					}
				} else if (ch == '/') {
					NextCh();
					if (ch == '*') {
						level++; NextCh();
					}
				} else if (ch == Buffer.EOF) return false;
				else NextCh();
			}
		} else {
			if (ch==EOL) {line--; lineStart = lineStart0;}
			pos = pos - 2; buffer.Pos = pos+1; NextCh();
		}
		return false;
	}


		void CheckLiteral() {
		switch (t.val) {
			case "COMPILER": t.kind = 6; break;
			case "IGNORECASE": t.kind = 7; break;
			case "CHARACTERS": t.kind = 8; break;
			case "TOKENS": t.kind = 9; break;
			case "PRAGMAS": t.kind = 10; break;
			case "COMMENTS": t.kind = 11; break;
			case "FROM": t.kind = 12; break;
			case "TO": t.kind = 13; break;
			case "NESTED": t.kind = 14; break;
			case "IGNORE": t.kind = 15; break;
			case "PRODUCTIONS": t.kind = 16; break;
			case "END": t.kind = 19; break;
			case "ANY": t.kind = 23; break;
			case "WEAK": t.kind = 27; break;
			case "SYNC": t.kind = 34; break;
			case "IF": t.kind = 35; break;
			case "CONTEXT": t.kind = 36; break;
			case "using": t.kind = 39; break;
			default: break;
		}
		}

		Token NextToken() {
			while (ignore[ch]) NextCh();
		if (ch == '/' && Comment0() ||ch == '/' && Comment1()) return NextToken();
			t = new Token();
			t.pos = pos; t.col = pos - lineStart + 1; t.line = line; 
			int state = start[ch];
			tlen = 0; AddCh();
			
			switch (state) {
				case -1: { t.kind = eofSym; break; } // NextCh already done
				case 0: { t.kind = noSym; break; }   // NextCh already done
			case 1:
				if ((ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')) {AddCh(); goto case 1;}
				else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
			case 2:
				if ((ch >= '0' && ch <= '9')) {AddCh(); goto case 2;}
				else {t.kind = 2; break;}
			case 3:
				{t.kind = 3; break;}
			case 4:
				{t.kind = 4; break;}
			case 5:
				if ((ch <= 9 || ch >= 11 && ch <= 12 || ch >= 14 && ch <= '&' || ch >= '(' && ch <= '[' || ch >= ']' && ch <= 255)) {AddCh(); goto case 6;}
				else if (ch == 92) {AddCh(); goto case 7;}
				else {t.kind = noSym; break;}
			case 6:
				if (ch == 39) {AddCh(); goto case 9;}
				else {t.kind = noSym; break;}
			case 7:
				if ((ch >= ' ' && ch <= '~')) {AddCh(); goto case 8;}
				else {t.kind = noSym; break;}
			case 8:
				if ((ch >= '0' && ch <= '9' || ch >= 'a' && ch <= 'f')) {AddCh(); goto case 8;}
				else if (ch == 39) {AddCh(); goto case 9;}
				else {t.kind = noSym; break;}
			case 9:
				{t.kind = 5; break;}
			case 10:
				if ((ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')) {AddCh(); goto case 10;}
				else {t.kind = 42; break;}
			case 11:
				if ((ch <= 9 || ch >= 11 && ch <= 12 || ch >= 14 && ch <= '!' || ch >= '#' && ch <= '[' || ch >= ']' && ch <= 255)) {AddCh(); goto case 11;}
				else if ((ch == 10 || ch == 13)) {AddCh(); goto case 4;}
				else if (ch == '"') {AddCh(); goto case 3;}
				else if (ch == 92) {AddCh(); goto case 12;}
				else {t.kind = noSym; break;}
			case 12:
				if ((ch >= ' ' && ch <= '~')) {AddCh(); goto case 11;}
				else {t.kind = noSym; break;}
			case 13:
				{t.kind = 17; break;}
			case 14:
				{t.kind = 20; break;}
			case 15:
				{t.kind = 21; break;}
			case 16:
				{t.kind = 22; break;}
			case 17:
				{t.kind = 24; break;}
			case 18:
				{t.kind = 25; break;}
			case 19:
				{t.kind = 26; break;}
			case 20:
				{t.kind = 29; break;}
			case 21:
				{t.kind = 30; break;}
			case 22:
				{t.kind = 31; break;}
			case 23:
				{t.kind = 32; break;}
			case 24:
				{t.kind = 33; break;}
			case 25:
				{t.kind = 37; break;}
			case 26:
				{t.kind = 38; break;}
			case 27:
				{t.kind = 40; break;}
			case 28:
				if (ch == '.') {AddCh(); goto case 16;}
				else if (ch == ')') {AddCh(); goto case 26;}
				else {t.kind = 18; break;}
			case 29:
				if (ch == '.') {AddCh(); goto case 25;}
				else {t.kind = 28; break;}

			}
			t.val = new String(tval, 0, tlen);
			return t;
		}
		
		// get the next token (possibly a token already seen during peeking)
		public Token Scan () {
			if (tokens.next == null) {
				return NextToken();
			} else {
				pt = tokens = tokens.next;
				return tokens;
			}
		}

		// peek for the next token, ignore pragmas
		public Token Peek () {
			if (pt.next == null) {
				do {
					pt = pt.next = NextToken();
				} while (pt.kind > maxT); // skip pragmas
			} else {
				do {
					pt = pt.next;
				} while (pt.kind > maxT);
			}
			return pt;
		}
		
		// make sure that peeking starts at the current scan position
		public void ResetPeek () { pt = tokens; }

	} // end Scanner

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Pascal Ganaye
Software Developer (Senior)
United Kingdom United Kingdom
I am a French programmer.
These days I spend most of my time with the .NET framework, JavaScript and html.

| Advertise | Privacy | Mobile
Web01 | 2.8.140827.1 | Last Updated 29 Oct 2005
Article Copyright 2005 by Pascal Ganaye
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid