public void Action(Expansion e) { if (e is RJustName) { RJustName jn = (RJustName)e; RegularExpression rexp; if (!CSharpCCGlobals.named_tokens_table.TryGetValue(jn.Label, out rexp)) { CSharpCCErrors.SemanticError(e, "Undefined lexical token name \"" + jn.Label + "\"."); } else if (jn == root && !jn.TokenProductionContext.IsExplicit && rexp.IsPrivate) { CSharpCCErrors.SemanticError(e, "Token name \"" + jn.Label + "\" refers to a private " + "(with a #) regular expression."); } else if (jn == root && !jn.TokenProductionContext.IsExplicit && rexp.TokenProductionContext.Kind != TokenProduction.TOKEN) { CSharpCCErrors.SemanticError(e, "Token name \"" + jn.Label + "\" refers to a non-token " + "(SKIP, MORE, IGNORE_IN_BNF) regular expression."); } else { jn.Ordinal = rexp.Ordinal; jn.RegularExpression = rexp; } } }
public override Nfa GenerateNfa(bool ignoreCase) { if (!transformed) { if (Options.getIgnoreCase() || ignoreCase) { ToCaseNeutral(); SortDescriptors(); } if (Negated) { RemoveNegation(); // This also sorts the list } else { SortDescriptors(); } } if (descriptors.Count == 0 && !Negated) { CSharpCCErrors.SemanticError(this, "Empty character set is not allowed as it will not match any character."); return(new Nfa()); } transformed = true; Nfa retVal = new Nfa(); NfaState startState = retVal.Start; NfaState finalState = retVal.End; int i; for (i = 0; i < descriptors.Count; i++) { if (descriptors[i] is SingleCharacter) { startState.AddChar(((SingleCharacter)descriptors[i]).Character); } else // if (descriptors.get(i) instanceof CharacterRange) { CharacterRange cr = (CharacterRange)descriptors[i]; if (cr.Left == cr.Right) { startState.AddChar(cr.Left); } else { startState.AddRange(cr.Left, cr.Right); } } } startState.next = finalState; return(retVal); }
public CharacterRange(char left, char right) { if (left > right) { CSharpCCErrors.SemanticError(this, "Invalid range : \"" + (int)left + "\" - \"" + (int)right + "\". First character shoud be less than or equal to the second one in a range."); } Left = left; Right = right; }
private static void GenerateFile(string fileName, string templateName, IDictionary <string, object> options, string[] optionNames) { try { string file = Path.Combine(Options.getOutputDirectory().FullName, fileName); OutputFile outputFile = new OutputFile(file, typeof(CSharpFiles).Assembly.GetName().Version.ToString(), optionNames); if (!outputFile.needToWrite) { return; } TextWriter ostr = outputFile.GetTextWriter(); bool nsFound = false; if (CSharpCCGlobals.cu_to_insertion_point_1.Count != 0 && CSharpCCGlobals.cu_to_insertion_point_1[0].kind == CSharpCCParserConstants.NAMESPACE) { for (int i = 1; i < CSharpCCGlobals.cu_to_insertion_point_1.Count; i++) { if (CSharpCCGlobals.cu_to_insertion_point_1[i].kind == CSharpCCParserConstants.SEMICOLON) { CSharpCCGlobals.cline = CSharpCCGlobals.cu_to_insertion_point_1[0].beginLine; CSharpCCGlobals.ccol = CSharpCCGlobals.cu_to_insertion_point_1[0].beginColumn; for (int j = 0; j <= i - 1; j++) { CSharpCCGlobals.PrintToken(CSharpCCGlobals.cu_to_insertion_point_1[j], ostr); } nsFound = true; ostr.WriteLine("{"); ostr.WriteLine(); ostr.WriteLine(); break; } } } CSharpFileGenetor generator = new CSharpFileGenetor(templateName, options); generator.Generate(ostr); if (nsFound) { ostr.WriteLine("}"); } ostr.Close(); } catch (IOException e) { Console.Error.WriteLine("Failed to create " + fileName + ": " + e.Message); CSharpCCErrors.SemanticError("Could not open file " + fileName + " for writing."); throw new InvalidOperationException(); } }
public void Action(Expansion e) { if (e is NonTerminal) { NonTerminal nt = (NonTerminal)e; NormalProduction prod; if (!CSharpCCGlobals.production_table.TryGetValue(nt.Name, out prod)) { CSharpCCErrors.SemanticError(e, "Non-terminal " + nt.Name + " has not been defined."); } else { nt.Production = prod; nt.Production.Parents.Add(nt); } } }
private static bool prodWalk(NormalProduction prod) { prod.WalkStatus = -1; for (int i = 0; i < prod.LeIndex; i++) { if (prod.LeftExpansions[i].WalkStatus == -1) { prod.LeftExpansions[i].WalkStatus = -2; loopString = prod.Lhs + "... --> " + prod.LeftExpansions[i].Lhs + "..."; if (prod.WalkStatus == -2) { prod.WalkStatus = 1; CSharpCCErrors.SemanticError(prod, "Left recursion detected: \"" + loopString + "\""); return(false); } else { prod.WalkStatus = 1; return(true); } } else if (prod.LeftExpansions[i].WalkStatus == 0) { if (prodWalk(prod.LeftExpansions[i])) { loopString = prod.Lhs + "... --> " + loopString; if (prod.WalkStatus == -2) { prod.WalkStatus = 1; CSharpCCErrors.SemanticError(prod, "Left recursion detected: \"" + loopString + "\""); return(false); } else { prod.WalkStatus = 1; return(true); } } } } prod.WalkStatus = 1; return(false); }
public static void CreateOutputDir(string outputDir) { if (!Directory.Exists(outputDir)) { CSharpCCErrors.Warning("Output directory \"" + outputDir + "\" does not exist. Creating the directory."); if (Directory.CreateDirectory(outputDir) == null) { CSharpCCErrors.SemanticError("Cannot create the output directory : " + outputDir); return; } } /* * TODO: * if (!outputDir.canWrite()) * { * CSharpCCErrors.SemanticError("Cannot write to the output output directory : \"" + outputDir + "\""); * return; * } */ }
public void Action(Expansion e) { if (e is OneOrMore) { if (Semanticize.EmptyExpansionExists(((OneOrMore)e).Expansion)) { CSharpCCErrors.SemanticError(e, "Expansion within \"(...)+\" can be matched by empty string."); } } else if (e is ZeroOrMore) { if (Semanticize.EmptyExpansionExists(((ZeroOrMore)e).Expansion)) { CSharpCCErrors.SemanticError(e, "Expansion within \"(...)*\" can be matched by empty string."); } } else if (e is ZeroOrOne) { if (Semanticize.EmptyExpansionExists(((ZeroOrOne)e).Expansion)) { CSharpCCErrors.SemanticError(e, "Expansion within \"(...)?\" can be matched by empty string."); } } }
public static void start() { Token t = null; if (CSharpCCErrors.ErrorCount != 0) { throw new MetaParseException(); } if (Options.getBuildParser()) { try { ostr = new StreamWriter( new BufferedStream( new FileStream(Path.Combine(Options.getOutputDirectory().FullName, CSharpCCGlobals.cu_name + ".cs"), FileMode.OpenOrCreate, FileAccess.Write), 8192)); } catch (IOException e) { CSharpCCErrors.SemanticError("Could not open file " + CSharpCCGlobals.cu_name + ".cs for writing."); throw new InvalidOperationException(); } IList <string> tn = new List <string>(CSharpCCGlobals.ToolNames); tn.Add(CSharpCCGlobals.ToolName); ostr.WriteLine("// " + CSharpCCGlobals.GetIdString(tn, CSharpCCGlobals.cu_name + ".cs")); bool implementsExists = false; bool namespaceInserted = false, namespaceFound = false; if (CSharpCCGlobals.cu_to_insertion_point_1.Count != 0) { CSharpCCGlobals.PrintTokenSetup(CSharpCCGlobals.cu_to_insertion_point_1[0]); CSharpCCGlobals.ccol = 1; foreach (Token token in CSharpCCGlobals.cu_to_insertion_point_1) { t = token; if (t.kind == CSharpCCParserConstants.COLON) { implementsExists = true; } else if (t.kind == CSharpCCParserConstants.CLASS) { implementsExists = false; } if (t.kind == CSharpCCParserConstants.NAMESPACE) { namespaceFound = true; } if (t.kind == CSharpCCParserConstants.SEMICOLON) { if (namespaceFound) { namespaceFound = false; namespaceInserted = true; ostr.WriteLine(" {"); } else { CSharpCCGlobals.PrintToken(t, ostr); } } else { CSharpCCGlobals.PrintToken(t, ostr); } } } ostr.Write(" : "); ostr.Write(CSharpCCGlobals.cu_name + "Constants "); if (implementsExists) { ostr.Write(", "); } if (CSharpCCGlobals.cu_to_insertion_point_2.Count != 0) { CSharpCCGlobals.PrintTokenSetup(CSharpCCGlobals.cu_to_insertion_point_2[0]); foreach (Token token in CSharpCCGlobals.cu_to_insertion_point_2) { t = token; CSharpCCGlobals.PrintToken(t, ostr); } } ostr.WriteLine(""); ostr.WriteLine(""); ParseEngine.build(ostr); if (Options.getStatic()) { ostr.WriteLine(" private static bool cc_initialized_once = false;"); } if (Options.getUserTokenManager()) { ostr.WriteLine(" /** User defined Token Manager. */"); ostr.WriteLine(" public " + CSharpCCGlobals.staticOpt() + " ITokenManager tokenSource;"); } else { ostr.WriteLine(" /** Generated Token Manager. */"); ostr.WriteLine(" public " + CSharpCCGlobals.staticOpt() + " " + CSharpCCGlobals.cu_name + "TokenManager tokenSource;"); if (!Options.getUserCharStream()) { if (Options.getUnicodeEscape()) { ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "UnicodeCharStream cc_inputStream;"); } else { ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "SimpleCharStream cc_inputStream;"); } } } ostr.WriteLine(" /// <summary>Current token.</summary>"); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "public Token token;"); ostr.WriteLine(" /// <summary> Next token.</summary>"); ostr.WriteLine(" public " + CSharpCCGlobals.staticOpt() + "Token cc_nt;"); if (!Options.getCacheTokens()) { ostr.WriteLine(" private " + CSharpCCGlobals.staticOpt() + "int cc_ntKind;"); } if (CSharpCCGlobals.cc2index != 0) { ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private Token cc_scanpos, cc_lastpos;"); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private int cc_la;"); if (CSharpCCGlobals.lookaheadNeeded) { ostr.WriteLine(" /** Whether we are looking ahead. */"); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private bool cc_lookingAhead = false;"); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private bool cc_semLA;"); } } if (Options.getErrorReporting()) { ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private int cc_gen;"); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + " private readonly int[] cc_la1 = new int[" + CSharpCCGlobals.maskindex + "];"); int tokenMaskSize = (CSharpCCGlobals.tokenCount - 1) / 32 + 1; for (int i = 0; i < tokenMaskSize; i++) { ostr.WriteLine(" static private int[] cc_la1_" + i + ";"); } ostr.WriteLine(" static " + CSharpCCGlobals.cu_name + "() { "); for (int i = 0; i < tokenMaskSize; i++) { ostr.WriteLine(" cc_la1_init_" + i + "();"); } ostr.WriteLine(" }"); for (int i = 0; i < tokenMaskSize; i++) { ostr.WriteLine(" private static void cc_la1_init_" + i + "() {"); ostr.Write(" cc_la1_" + i + " = new int[] {"); foreach (int[] tokenMask in CSharpCCGlobals.maskVals) { ostr.Write(tokenMask[i] + ","); } ostr.WriteLine("};"); ostr.WriteLine(" }"); } } if (CSharpCCGlobals.cc2index != 0 && Options.getErrorReporting()) { ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "readonly private CCCalls[] cc_2_rtns = new CCCalls[" + CSharpCCGlobals.cc2index + "];"); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private bool cc_rescan = false;"); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private int cc_gc = 0;"); } ostr.WriteLine(""); if (!Options.getUserTokenManager()) { if (Options.getUserCharStream()) { ostr.WriteLine(" /// Constructor with user supplied ICharStream."); ostr.WriteLine(" public " + CSharpCCGlobals.cu_name + "(ICharStream stream) {"); if (Options.getStatic()) { ostr.WriteLine(" if (cc_initialized_once) {"); ostr.WriteLine(" Console.Out.WriteLine(\"ERROR: Second call to constructor of static parser. \");"); ostr.WriteLine(" Console.Out.WriteLine(\" You must either use ReInit() " + "or set the CSharpCC option STATIC to false\");"); ostr.WriteLine(" Console.Out.WriteLine(\" during parser generation.\");"); ostr.WriteLine(" throw new InvalidOperationException();"); ostr.WriteLine(" }"); ostr.WriteLine(" cc_initialized_once = true;"); } if (Options.getTokenManagerUsesParser() && !Options.getStatic()) { ostr.WriteLine(" tokenSource = new " + CSharpCCGlobals.cu_name + "TokenManager(this, stream);"); } else { ostr.WriteLine(" tokenSource = new " + CSharpCCGlobals.cu_name + "TokenManager(stream);"); } ostr.WriteLine(" token = new Token();"); if (Options.getCacheTokens()) { ostr.WriteLine(" token.Next = cc_nt = tokenSource.GetNextToken();"); } else { ostr.WriteLine(" cc_ntKind = -1;"); } if (Options.getErrorReporting()) { ostr.WriteLine(" cc_gen = 0;"); ostr.WriteLine(" for (int i = 0; i < " + CSharpCCGlobals.maskindex + "; i++) cc_la1[i] = -1;"); if (CSharpCCGlobals.cc2index != 0) { ostr.WriteLine(" for (int i = 0; i < cc_2_rtns.Length; i++) cc_2_rtns[i] = new CCCalls();"); } } ostr.WriteLine(" }"); ostr.WriteLine(""); ostr.WriteLine(" /** Reinitialise. */"); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "public void ReInit(ICharStream stream) {"); ostr.WriteLine(" tokenSource.ReInit(stream);"); ostr.WriteLine(" token = new Token();"); if (Options.getCacheTokens()) { ostr.WriteLine(" token.Next = cc_nt = tokenSource.GetNextToken();"); } else { ostr.WriteLine(" cc_ntKind = -1;"); } if (CSharpCCGlobals.lookaheadNeeded) { ostr.WriteLine(" cc_lookingAhead = false;"); } if (CSharpCCGlobals.TreeGenerated) { ostr.WriteLine(" ccTree.Reset();"); } if (Options.getErrorReporting()) { ostr.WriteLine(" cc_gen = 0;"); ostr.WriteLine(" for (int i = 0; i < " + CSharpCCGlobals.maskindex + "; i++) cc_la1[i] = -1;"); if (CSharpCCGlobals.cc2index != 0) { ostr.WriteLine(" for (int i = 0; i < cc_2_rtns.Length; i++) cc_2_rtns[i] = new CCCalls();"); } } ostr.WriteLine(" }"); } else { ostr.WriteLine(" /// Constructor with Stream."); ostr.WriteLine(" public " + CSharpCCGlobals.cu_name + "(System.IO.Stream stream)"); ostr.WriteLine(" : this(stream, null) {"); ostr.WriteLine(" }"); ostr.WriteLine(" /// Constructor with Stream and supplied encoding"); ostr.WriteLine(" public " + CSharpCCGlobals.cu_name + "(System.IO.Stream stream, System.Text.Encoding encoding) {"); if (Options.getStatic()) { ostr.WriteLine(" if (cc_initialized_once) {"); ostr.WriteLine(" Console.Out.WriteLine(\"ERROR: Second call to constructor of static parser. \");"); ostr.WriteLine(" Console.Out.WriteLine(\" You must either use ReInit() or " + "set the CSharpCC option STATIC to false\");"); ostr.WriteLine(" Console.Out.WriteLine(\" during parser generation.\");"); ostr.WriteLine(" throw new InvalidOperationException();"); ostr.WriteLine(" }"); ostr.WriteLine(" cc_initialized_once = true;"); } if (Options.getUnicodeEscape()) { ostr.WriteLine(" cc_inputStream = new UnicodeCharStream(stream, encoding, 1, 1);"); } else { ostr.WriteLine(" cc_inputStream = new SimpleCharStream(stream, encoding, 1, 1);"); } if (Options.getTokenManagerUsesParser() && !Options.getStatic()) { ostr.WriteLine(" tokenSource = new " + CSharpCCGlobals.cu_name + "TokenManager(this, cc_inputStream);"); } else { ostr.WriteLine(" tokenSource = new " + CSharpCCGlobals.cu_name + "TokenManager(cc_inputStream);"); } ostr.WriteLine(" token = new Token();"); if (Options.getCacheTokens()) { ostr.WriteLine(" token.Next = cc_nt = tokenSource.GetNextToken();"); } else { ostr.WriteLine(" cc_ntKind = -1;"); } if (Options.getErrorReporting()) { ostr.WriteLine(" cc_gen = 0;"); ostr.WriteLine(" for (int i = 0; i < " + CSharpCCGlobals.maskindex + "; i++) cc_la1[i] = -1;"); if (CSharpCCGlobals.cc2index != 0) { ostr.WriteLine(" for (int i = 0; i < cc_2_rtns.Length; i++) cc_2_rtns[i] = new CCCalls();"); } } ostr.WriteLine(" }"); ostr.WriteLine(""); ostr.WriteLine(" /// Reinitialise."); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "public void ReInit(System.IO.Stream stream) {"); ostr.WriteLine(" ReInit(stream, null);"); ostr.WriteLine(" }"); ostr.WriteLine(" /// Reinitialise."); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "public void ReInit(System.IO.Stream stream, System.Text.Encoding encoding) {"); ostr.WriteLine(" cc_inputStream.ReInit(stream, encoding, 1, 1);"); ostr.WriteLine(" tokenSource.ReInit(cc_inputStream);"); ostr.WriteLine(" token = new Token();"); if (Options.getCacheTokens()) { ostr.WriteLine(" token.Next = cc_nt = tokenSource.GetNextToken();"); } else { ostr.WriteLine(" cc_ntKind = -1;"); } if (CSharpCCGlobals.TreeGenerated) { ostr.WriteLine(" ccTree.Reset();"); } if (Options.getErrorReporting()) { ostr.WriteLine(" cc_gen = 0;"); ostr.WriteLine(" for (int i = 0; i < " + CSharpCCGlobals.maskindex + "; i++) cc_la1[i] = -1;"); if (CSharpCCGlobals.cc2index != 0) { ostr.WriteLine(" for (int i = 0; i < cc_2_rtns.Length; i++) cc_2_rtns[i] = new CCCalls();"); } } ostr.WriteLine(" }"); ostr.WriteLine(""); ostr.WriteLine(" /// Constructor."); ostr.WriteLine(" public " + CSharpCCGlobals.cu_name + "(System.IO.TextReader reader) {"); if (Options.getStatic()) { ostr.WriteLine(" if (cc_initialized_once) {"); ostr.WriteLine(" Console.Out.WriteLine(\"ERROR: Second call to constructor of static parser. \");"); ostr.WriteLine(" Console.Out.WriteLine(\" You must either use ReInit() or " + "set the CSharpCC option STATIC to false\");"); ostr.WriteLine(" Console.Out.WriteLine(\" during parser generation.\");"); ostr.WriteLine(" throw new InvalidOperationException();"); ostr.WriteLine(" }"); ostr.WriteLine(" cc_initialized_once = true;"); } if (Options.getUnicodeEscape()) { ostr.WriteLine(" cc_inputStream = new UnicodeCharStream(reader, 1, 1);"); } else { ostr.WriteLine(" cc_inputStream = new SimpleCharStream(reader, 1, 1);"); } if (Options.getTokenManagerUsesParser() && !Options.getStatic()) { ostr.WriteLine(" tokenSource = new " + CSharpCCGlobals.cu_name + "TokenManager(this, cc_inputStream);"); } else { ostr.WriteLine(" tokenSource = new " + CSharpCCGlobals.cu_name + "TokenManager(cc_inputStream);"); } ostr.WriteLine(" token = new Token();"); if (Options.getCacheTokens()) { ostr.WriteLine(" token.Next = cc_nt = tokenSource.GetNextToken();"); } else { ostr.WriteLine(" cc_ntKind = -1;"); } if (Options.getErrorReporting()) { ostr.WriteLine(" cc_gen = 0;"); ostr.WriteLine(" for (int i = 0; i < " + CSharpCCGlobals.maskindex + "; i++) cc_la1[i] = -1;"); if (CSharpCCGlobals.cc2index != 0) { ostr.WriteLine(" for (int i = 0; i < cc_2_rtns.Length; i++) cc_2_rtns[i] = new CCCalls();"); } } ostr.WriteLine(" }"); ostr.WriteLine(""); ostr.WriteLine(" /// Reinitialise."); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "public void ReInit(System.IO.TextReader reader) {"); if (Options.getUnicodeEscape()) { ostr.WriteLine(" cc_inputStream.ReInit(reader, 1, 1);"); } else { ostr.WriteLine(" cc_inputStream.ReInit(reader, 1, 1);"); } ostr.WriteLine(" tokenSource.ReInit(cc_inputStream);"); ostr.WriteLine(" token = new Token();"); if (Options.getCacheTokens()) { ostr.WriteLine(" token.next = cc_nt = tokenSource.GetNextToken();"); } else { ostr.WriteLine(" cc_ntKind = -1;"); } if (CSharpCCGlobals.TreeGenerated) { ostr.WriteLine(" ccTree.Reset();"); } if (Options.getErrorReporting()) { ostr.WriteLine(" cc_gen = 0;"); ostr.WriteLine(" for (int i = 0; i < " + CSharpCCGlobals.maskindex + "; i++) cc_la1[i] = -1;"); if (CSharpCCGlobals.cc2index != 0) { ostr.WriteLine(" for (int i = 0; i < cc_2_rtns.Length; i++) cc_2_rtns[i] = new CCCalls();"); } } ostr.WriteLine(" }"); } } ostr.WriteLine(""); if (Options.getUserTokenManager()) { ostr.WriteLine(" /** Constructor with user supplied Token Manager. */"); ostr.WriteLine(" public " + CSharpCCGlobals.cu_name + "(ITokenManager tm) {"); } else { ostr.WriteLine(" /** Constructor with generated Token Manager. */"); ostr.WriteLine(" public " + CSharpCCGlobals.cu_name + "(" + CSharpCCGlobals.cu_name + "TokenManager tm) {"); } if (Options.getStatic()) { ostr.WriteLine(" if (cc_initialized_once) {"); ostr.WriteLine(" Console.Out.WriteLine(\"ERROR: Second call to constructor of static parser. \");"); ostr.WriteLine(" Console.Out.WriteLine(\" You must either use ReInit() or " + "set the JavaCC option STATIC to false\");"); ostr.WriteLine(" Console.Out.WriteLine(\" during parser generation.\");"); ostr.WriteLine(" throw new InvalidOperationException();"); ostr.WriteLine(" }"); ostr.WriteLine(" cc_initialized_once = true;"); } ostr.WriteLine(" tokenSource = tm;"); ostr.WriteLine(" token = new Token();"); if (Options.getCacheTokens()) { ostr.WriteLine(" token.Next = cc_nt = tokenSource.GetNextToken();"); } else { ostr.WriteLine(" cc_ntKind = -1;"); } if (Options.getErrorReporting()) { ostr.WriteLine(" cc_gen = 0;"); ostr.WriteLine(" for (int i = 0; i < " + CSharpCCGlobals.maskindex + "; i++) cc_la1[i] = -1;"); if (CSharpCCGlobals.cc2index != 0) { ostr.WriteLine(" for (int i = 0; i < cc_2_rtns.Length; i++) cc_2_rtns[i] = new CCCalls();"); } } ostr.WriteLine(" }"); ostr.WriteLine(""); if (Options.getUserTokenManager()) { ostr.WriteLine(" /** Reinitialise. */"); ostr.WriteLine(" public void ReInit(ITokenManager tm) {"); } else { ostr.WriteLine(" /** Reinitialise. */"); ostr.WriteLine(" public void ReInit(" + CSharpCCGlobals.cu_name + "TokenManager tm) {"); } ostr.WriteLine(" tokenSource = tm;"); ostr.WriteLine(" token = new Token();"); if (Options.getCacheTokens()) { ostr.WriteLine(" token.next = cc_nt = tokenSource.GetNextToken();"); } else { ostr.WriteLine(" cc_ntKind = -1;"); } if (CSharpCCGlobals.TreeGenerated) { ostr.WriteLine(" ccTree.reset();"); } if (Options.getErrorReporting()) { ostr.WriteLine(" cc_gen = 0;"); ostr.WriteLine(" for (int i = 0; i < " + CSharpCCGlobals.maskindex + "; i++) cc_la1[i] = -1;"); if (CSharpCCGlobals.cc2index != 0) { ostr.WriteLine(" for (int i = 0; i < cc_2_rtns.length; i++) cc_2_rtns[i] = new CCCalls();"); } } ostr.WriteLine(" }"); ostr.WriteLine(""); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private Token cc_consume_token(int kind) {"); if (Options.getCacheTokens()) { ostr.WriteLine(" Token oldToken = token;"); ostr.WriteLine(" if ((token = cc_nt).Next != null) cc_nt = cc_nt.Next;"); ostr.WriteLine(" else cc_nt = cc_nt.Next = tokenSource.GetNextToken();"); } else { ostr.WriteLine(" Token oldToken;"); ostr.WriteLine(" if ((oldToken = token).Next != null) token = token.Next;"); ostr.WriteLine(" else token = token.Next = tokenSource.GetNextToken();"); ostr.WriteLine(" cc_ntKind = -1;"); } ostr.WriteLine(" if (token.Kind == kind) {"); if (Options.getErrorReporting()) { ostr.WriteLine(" cc_gen++;"); if (CSharpCCGlobals.cc2index != 0) { ostr.WriteLine(" if (++cc_gc > 100) {"); ostr.WriteLine(" cc_gc = 0;"); ostr.WriteLine(" for (int i = 0; i < cc_2_rtns.length; i++) {"); ostr.WriteLine(" CCCalls c = cc_2_rtns[i];"); ostr.WriteLine(" while (c != null) {"); ostr.WriteLine(" if (c.gen < cc_gen) c.first = null;"); ostr.WriteLine(" c = c.next;"); ostr.WriteLine(" }"); ostr.WriteLine(" }"); ostr.WriteLine(" }"); } } if (Options.getDebugParser()) { ostr.WriteLine(" trace_token(token, \"\");"); } ostr.WriteLine(" return token;"); ostr.WriteLine(" }"); if (Options.getCacheTokens()) { ostr.WriteLine(" cc_nt = token;"); } ostr.WriteLine(" token = oldToken;"); if (Options.getErrorReporting()) { ostr.WriteLine(" cc_kind = kind;"); } ostr.WriteLine(" throw GenerateParseException();"); ostr.WriteLine(" }"); ostr.WriteLine(""); if (CSharpCCGlobals.cc2index != 0) { ostr.WriteLine(" private sealed class LookaheadSuccess : System.Exception { }"); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "readonly private LookaheadSuccess cc_ls = new LookaheadSuccess();"); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private bool cc_scan_token(int kind) {"); ostr.WriteLine(" if (cc_scanpos == cc_lastpos) {"); ostr.WriteLine(" cc_la--;"); ostr.WriteLine(" if (cc_scanpos.Next == null) {"); ostr.WriteLine(" cc_lastpos = cc_scanpos = cc_scanpos.Next = tokenSource.GetNextToken();"); ostr.WriteLine(" } else {"); ostr.WriteLine(" cc_lastpos = cc_scanpos = cc_scanpos.Next;"); ostr.WriteLine(" }"); ostr.WriteLine(" } else {"); ostr.WriteLine(" cc_scanpos = cc_scanpos.Next;"); ostr.WriteLine(" }"); if (Options.getErrorReporting()) { ostr.WriteLine(" if (cc_rescan) {"); ostr.WriteLine(" int i = 0; Token tok = token;"); ostr.WriteLine(" while (tok != null && tok != cc_scanpos) { i++; tok = tok.next; }"); ostr.WriteLine(" if (tok != null) cc_add_error_token(kind, i);"); if (Options.getDebugLookahead()) { ostr.WriteLine(" } else {"); ostr.WriteLine(" trace_scan(cc_scanpos, kind);"); } ostr.WriteLine(" }"); } else if (Options.getDebugLookahead()) { ostr.WriteLine(" trace_scan(cc_scanpos, kind);"); } ostr.WriteLine(" if (cc_scanpos.kind != kind) return true;"); ostr.WriteLine(" if (cc_la == 0 && cc_scanpos == cc_lastpos) throw cc_ls;"); ostr.WriteLine(" return false;"); ostr.WriteLine(" }"); ostr.WriteLine(""); } ostr.WriteLine(""); ostr.WriteLine("/** Get the next Token. */"); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + " public Token GetNextToken() {"); if (Options.getCacheTokens()) { ostr.WriteLine(" if ((token = cc_nt).Next != null) cc_nt = cc_nt.next;"); ostr.WriteLine(" else cc_nt = cc_nt.Next = tokenSource.GetNextToken();"); } else { ostr.WriteLine(" if (token.Next != null) token = token.Next;"); ostr.WriteLine(" else token = token.Next = tokenSource.GetNextToken();"); ostr.WriteLine(" cc_ntKind = -1;"); } if (Options.getErrorReporting()) { ostr.WriteLine(" cc_gen++;"); } if (Options.getDebugParser()) { ostr.WriteLine(" trace_token(token, \" (in GetNextToken)\");"); } ostr.WriteLine(" return token;"); ostr.WriteLine(" }"); ostr.WriteLine(""); ostr.WriteLine("/** Get the specific Token. */"); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + " public Token GetToken(int index) {"); if (CSharpCCGlobals.lookaheadNeeded) { ostr.WriteLine(" Token t = cc_lookingAhead ? cc_scanpos : token;"); } else { ostr.WriteLine(" Token t = token;"); } ostr.WriteLine(" for (int i = 0; i < index; i++) {"); ostr.WriteLine(" if (t.Next != null) t = t.Next;"); ostr.WriteLine(" else t = t.Next = tokenSource.GetNextToken();"); ostr.WriteLine(" }"); ostr.WriteLine(" return t;"); ostr.WriteLine(" }"); ostr.WriteLine(""); if (!Options.getCacheTokens()) { ostr.WriteLine(" private " + CSharpCCGlobals.staticOpt() + "int cc_ntk() {"); ostr.WriteLine(" if ((cc_nt=token.Next) == null)"); ostr.WriteLine(" return (cc_ntKind = (token.Next = tokenSource.GetNextToken()).Kind);"); ostr.WriteLine(" else"); ostr.WriteLine(" return (cc_ntKind = cc_nt.Kind);"); ostr.WriteLine(" }"); ostr.WriteLine(""); } if (Options.getErrorReporting()) { if (!Options.getGenerateGenerics()) { ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private System.Collections.IList cc_expentries = new System.Collections.ArrayList();"); } else { ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private System.Collections.Generic.IList<int[]> cc_expentries = new System.Collections.Generic.List<int[]>();"); } ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private int[] cc_expentry;"); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private int cc_kind = -1;"); if (CSharpCCGlobals.cc2index != 0) { ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private int[] cc_lasttokens = new int[100];"); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private int cc_endpos;"); ostr.WriteLine(""); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private void cc_add_error_token(int kind, int pos) {"); ostr.WriteLine(" if (pos >= 100) return;"); ostr.WriteLine(" if (pos == cc_endpos + 1) {"); ostr.WriteLine(" cc_lasttokens[cc_endpos++] = kind;"); ostr.WriteLine(" } else if (cc_endpos != 0) {"); ostr.WriteLine(" cc_expentry = new int[cc_endpos];"); ostr.WriteLine(" for (int i = 0; i < cc_endpos; i++) {"); ostr.WriteLine(" cc_expentry[i] = cc_lasttokens[i];"); ostr.WriteLine(" }"); ostr.WriteLine(" foreach (int[] oldentry in cc_expentries) {"); ostr.WriteLine(" if (oldentry.length == cc_expentry.length) {"); ostr.WriteLine(" for (int i = 0; i < cc_expentry.length; i++) {"); ostr.WriteLine(" if (oldentry[i] != cc_expentry[i]) {"); ostr.WriteLine(" goto cc_entries_loop;"); ostr.WriteLine(" }"); ostr.WriteLine(" }"); ostr.WriteLine(" cc_expentries.add(cc_expentry);"); ostr.WriteLine(" goto cc_entries_loop;"); ostr.WriteLine(" }"); ostr.WriteLine(" }"); ostr.WriteLine(" cc_entries_loop:;"); ostr.WriteLine(" if (pos != 0) cc_lasttokens[(cc_endpos = pos) - 1] = kind;"); ostr.WriteLine(" }"); ostr.WriteLine(" }"); } ostr.WriteLine(""); ostr.WriteLine(" /** Generate ParseException. */"); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "public ParseException GenerateParseException() {"); ostr.WriteLine(" cc_expentries.Clear();"); ostr.WriteLine(" bool[] la1tokens = new bool[" + CSharpCCGlobals.tokenCount + "];"); ostr.WriteLine(" if (cc_kind >= 0) {"); ostr.WriteLine(" la1tokens[cc_kind] = true;"); ostr.WriteLine(" cc_kind = -1;"); ostr.WriteLine(" }"); ostr.WriteLine(" for (int i = 0; i < " + CSharpCCGlobals.maskindex + "; i++) {"); ostr.WriteLine(" if (cc_la1[i] == cc_gen) {"); ostr.WriteLine(" for (int j = 0; j < 32; j++) {"); for (int i = 0; i < (CSharpCCGlobals.tokenCount - 1) / 32 + 1; i++) { ostr.WriteLine(" if ((cc_la1_" + i + "[i] & (1<<j)) != 0) {"); ostr.Write(" la1tokens["); if (i != 0) { ostr.Write((32 * i) + "+"); } ostr.WriteLine("j] = true;"); ostr.WriteLine(" }"); } ostr.WriteLine(" }"); ostr.WriteLine(" }"); ostr.WriteLine(" }"); ostr.WriteLine(" for (int i = 0; i < " + CSharpCCGlobals.tokenCount + "; i++) {"); ostr.WriteLine(" if (la1tokens[i]) {"); ostr.WriteLine(" cc_expentry = new int[1];"); ostr.WriteLine(" cc_expentry[0] = i;"); ostr.WriteLine(" cc_expentries.Add(cc_expentry);"); ostr.WriteLine(" }"); ostr.WriteLine(" }"); if (CSharpCCGlobals.cc2index != 0) { ostr.WriteLine(" cc_endpos = 0;"); ostr.WriteLine(" cc_rescan_token();"); ostr.WriteLine(" cc_add_error_token(0, 0);"); } ostr.WriteLine(" int[][] exptokseq = new int[cc_expentries.Count][];"); ostr.WriteLine(" for (int i = 0; i < cc_expentries.Count; i++) {"); if (!Options.getGenerateGenerics()) { ostr.WriteLine(" exptokseq[i] = (int[])cc_expentries[i];"); } else { ostr.WriteLine(" exptokseq[i] = cc_expentries[i];"); } ostr.WriteLine(" }"); ostr.WriteLine(" return new ParseException(token, exptokseq, TokenImage);"); ostr.WriteLine(" }"); } else { ostr.WriteLine(" /** Generate ParseException. */"); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "public ParseException GenerateParseException() {"); ostr.WriteLine(" Token errortok = token.Next;"); if (Options.getKeepLineColumn()) { ostr.WriteLine(" int line = errortok.BeginLine, column = errortok.BeginColumn;"); } ostr.WriteLine(" string mess = (errortok.Kind == 0) ? TokenImage[0] : errortok.Image;"); if (Options.getKeepLineColumn()) { ostr.WriteLine(" return new ParseException(" + "\"Parse error at line \" + line + \", column \" + column + \". " + "Encountered: \" + mess);"); } else { ostr.WriteLine(" return new ParseException(\"Parse error at <unknown location>. " + "Encountered: \" + mess);"); } ostr.WriteLine(" }"); } ostr.WriteLine(""); if (Options.getDebugParser()) { ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private int trace_indent = 0;"); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private bool trace_enabled = true;"); ostr.WriteLine(""); ostr.WriteLine("/** Enable tracing. */"); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + " public void enable_tracing() {"); ostr.WriteLine(" trace_enabled = true;"); ostr.WriteLine(" }"); ostr.WriteLine(""); ostr.WriteLine("/** Disable tracing. */"); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + " public void disable_tracing() {"); ostr.WriteLine(" trace_enabled = false;"); ostr.WriteLine(" }"); ostr.WriteLine(""); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private void trace_call(string s) {"); ostr.WriteLine(" if (trace_enabled) {"); ostr.WriteLine(" for (int i = 0; i < trace_indent; i++) { Console.Out.Write(\" \"); }"); ostr.WriteLine(" Console.Out.WriteLine(\"Call: \" + s);"); ostr.WriteLine(" }"); ostr.WriteLine(" trace_indent = trace_indent + 2;"); ostr.WriteLine(" }"); ostr.WriteLine(""); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private void trace_return(string s) {"); ostr.WriteLine(" trace_indent = trace_indent - 2;"); ostr.WriteLine(" if (trace_enabled) {"); ostr.WriteLine(" for (int i = 0; i < trace_indent; i++) { Console.Out.Write(\" \"); }"); ostr.WriteLine(" Console.Out.WriteLine(\"Return: \" + s);"); ostr.WriteLine(" }"); ostr.WriteLine(" }"); ostr.WriteLine(""); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private void trace_token(Token t, string loc) {"); ostr.WriteLine(" if (trace_enabled) {"); ostr.WriteLine(" for (int i = 0; i < trace_indent; i++) { Console.Out.Write(\" \"); }"); ostr.WriteLine(" Console.Out.Write(\"Consumed token: <\" + tokenImage[t.Kind]);"); ostr.WriteLine(" if (t.Kind != 0 && !tokenImage[t.Kind].Equals(\"\\\"\" + t.Image + \"\\\"\")) {"); ostr.WriteLine(" Console.Out.Write(\": \\\"\" + t.Image + \"\\\"\");"); ostr.WriteLine(" }"); ostr.WriteLine(" Console.Out.WriteLine(\" at line \" + t.BeginLine + " + "\" column \" + t.BeginColumn + \">\" + loc);"); ostr.WriteLine(" }"); ostr.WriteLine(" }"); ostr.WriteLine(""); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private void trace_scan(Token t1, int t2) {"); ostr.WriteLine(" if (trace_enabled) {"); ostr.WriteLine(" for (int i = 0; i < trace_indent; i++) { Console.Out.Write(\" \"); }"); ostr.WriteLine(" Console.Out.Write(\"Visited token: <\" + tokenImage[t1.kind]);"); ostr.WriteLine(" if (t1.Kind != 0 && !tokenImage[t1.Kind].Equals(\"\\\"\" + t1.Image + \"\\\"\")) {"); ostr.WriteLine(" Console.Out.Write(\": \\\"\" + t1.Image + \"\\\"\");"); ostr.WriteLine(" }"); ostr.WriteLine(" Console.Out.WriteLine(\" at line \" + t1.BeginLine + \"" + " column \" + t1.BeginColumn + \">; Expected token: <\" + tokenImage[t2] + \">\");"); ostr.WriteLine(" }"); ostr.WriteLine(" }"); ostr.WriteLine(""); } else { ostr.WriteLine(" /** Enable tracing. */"); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "public void enable_tracing() {"); ostr.WriteLine(" }"); ostr.WriteLine(""); ostr.WriteLine(" /** Disable tracing. */"); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "public void disable_tracing() {"); ostr.WriteLine(" }"); ostr.WriteLine(""); } if (CSharpCCGlobals.cc2index != 0 && Options.getErrorReporting()) { ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private void cc_rescan_token() {"); ostr.WriteLine(" cc_rescan = true;"); ostr.WriteLine(" for (int i = 0; i < " + CSharpCCGlobals.cc2index + "; i++) {"); ostr.WriteLine(" try {"); ostr.WriteLine(" CCCalls p = cc_2_rtns[i];"); ostr.WriteLine(" do {"); ostr.WriteLine(" if (p.gen > cc_gen) {"); ostr.WriteLine(" cc_la = p.arg; cc_lastpos = cc_scanpos = p.first;"); ostr.WriteLine(" switch (i) {"); for (int i = 0; i < CSharpCCGlobals.cc2index; i++) { ostr.WriteLine(" case " + i + ": cc_3_" + (i + 1) + "(); break;"); } ostr.WriteLine(" }"); ostr.WriteLine(" }"); ostr.WriteLine(" p = p.next;"); ostr.WriteLine(" } while (p != null);"); ostr.WriteLine(" } catch(LookaheadSuccess) { }"); ostr.WriteLine(" }"); ostr.WriteLine(" cc_rescan = false;"); ostr.WriteLine(" }"); ostr.WriteLine(""); ostr.WriteLine(" " + CSharpCCGlobals.staticOpt() + "private void cc_save(int index, int xla) {"); ostr.WriteLine(" CCCalls p = cc_2_rtns[index];"); ostr.WriteLine(" while (p.gen > cc_gen) {"); ostr.WriteLine(" if (p.next == null) { p = p.next = new CCCalls(); break; }"); ostr.WriteLine(" p = p.next;"); ostr.WriteLine(" }"); ostr.WriteLine(" p.gen = cc_gen + xla - cc_la; p.first = token; p.arg = xla;"); ostr.WriteLine(" }"); ostr.WriteLine(""); } if (CSharpCCGlobals.cc2index != 0 && Options.getErrorReporting()) { ostr.WriteLine(" sealed class CCCalls {"); ostr.WriteLine(" public int gen;"); ostr.WriteLine(" public Token first;"); ostr.WriteLine(" public int arg;"); ostr.WriteLine(" public CCCalls next;"); ostr.WriteLine(" }"); ostr.WriteLine(""); } if (CSharpCCGlobals.cu_from_insertion_point_2.Count != 0) { CSharpCCGlobals.PrintTokenSetup(CSharpCCGlobals.cu_from_insertion_point_2[0]); CSharpCCGlobals.ccol = 1; foreach (Token token in CSharpCCGlobals.cu_from_insertion_point_2) { t = token; CSharpCCGlobals.PrintToken(t, ostr); } CSharpCCGlobals.PrintTrailingComments(t, ostr); } ostr.WriteLine(""); if (namespaceInserted) { ostr.WriteLine("}"); } ostr.Close(); } // matches "if (Options.getBuildParser())" }
public static void start() { Token t = null; keepLineCol = Options.getKeepLineColumn(); if (CSharpCCErrors.ErrorCount != 0) { throw new MetaParseException(); } CSharpFiles.GenerateTokenManagerError(); CSharpFiles.GenerateParseException(); CSharpFiles.GenerateToken(); if (Options.getUserTokenManager()) { CSharpFiles.GenerateITokenManager(); } else if (Options.getUserCharStream()) { CSharpFiles.GenerateICharStream(); } else { if (Options.getUnicodeEscape()) { CSharpFiles.GenerateUnicodeCharStream(); } else { CSharpFiles.GenerateSimpleCharStream(); } } try { ostr = new StreamWriter( new BufferedStream( new FileStream(Path.Combine(Options.getOutputDirectory().FullName, CSharpCCGlobals.cu_name + "Constants.cs"), FileMode.OpenOrCreate, FileAccess.Write), 8192)); } catch (IOException) { CSharpCCErrors.SemanticError("Could not open file " + CSharpCCGlobals.cu_name + "Constants.cs for writing."); throw new InvalidOperationException(); } List <string> tn = new List <string>(CSharpCCGlobals.ToolNames); tn.Add(CSharpCCGlobals.ToolName); ostr.WriteLine("/* " + CSharpCCGlobals.GetIdString(tn, CSharpCCGlobals.cu_name + "Constants.cs") + " */"); bool namespaceInserted = false; if (CSharpCCGlobals.cu_to_insertion_point_1.Count != 0 && CSharpCCGlobals.cu_to_insertion_point_1[0].kind == CSharpCCParserConstants.NAMESPACE) { namespaceInserted = true; for (int i = 1; i < CSharpCCGlobals.cu_to_insertion_point_1.Count; i++) { if (CSharpCCGlobals.cu_to_insertion_point_1[i].kind == CSharpCCParserConstants.SEMICOLON) { CSharpCCGlobals.PrintTokenSetup(CSharpCCGlobals.cu_to_insertion_point_1[0]); for (int j = 0; j <= i; j++) { t = (CSharpCCGlobals.cu_to_insertion_point_1[j]); if (t.kind != CSharpCCParserConstants.SEMICOLON) { CSharpCCGlobals.PrintToken(t, ostr); } } CSharpCCGlobals.PrintTrailingComments(t, ostr); break; } } ostr.WriteLine("{"); } ostr.WriteLine(""); ostr.WriteLine("/// <summary>"); ostr.WriteLine("/// Token literal values and constants."); ostr.WriteLine("/// <summary>"); if (Options.getSupportClassVisibilityPublic()) { ostr.Write("public "); } ostr.WriteLine("class " + CSharpCCGlobals.cu_name + "Constants {"); ostr.WriteLine(""); ostr.WriteLine(" /// <summary> End of File</summary>"); ostr.WriteLine(" public const int EOF = 0;"); foreach (RegularExpression re in CSharpCCGlobals.ordered_named_tokens) { ostr.WriteLine(" /// <summary>RegularExpression Id.</summary>"); ostr.WriteLine(" public const int " + re.Label + " = " + re.Ordinal + ";"); } ostr.WriteLine(""); if (!Options.getUserTokenManager() && Options.getBuildTokenManager()) { for (int i = 0; i < LexGen.lexStateName.Length; i++) { ostr.WriteLine(" /// <summary>Lexical state.</summary>"); ostr.WriteLine(" public const int " + LexGen.lexStateName[i] + " = " + i + ";"); } ostr.WriteLine(""); } ostr.WriteLine(" /// <summary>Literal token values.</summary>"); ostr.WriteLine(" public static readonly string[] TokenImage = {"); ostr.WriteLine(" \"<EOF>\","); foreach (TokenProduction tp in CSharpCCGlobals.rexprlist) { IList <RegExprSpec> respecs = tp.RegexSpecs; foreach (RegExprSpec res in respecs) { RegularExpression re = res.RegularExpression; if (re is RStringLiteral) { ostr.WriteLine(" \"\\\"" + CSharpCCGlobals.AddEscapes(CSharpCCGlobals.AddEscapes(((RStringLiteral)re).Image)) + "\\\"\","); } else if (!re.Label.Equals("")) { ostr.WriteLine(" \"<" + re.Label + ">\","); } else { if (re.TokenProductionContext.Kind == TokenProduction.TOKEN) { CSharpCCErrors.Warning(re, "Consider giving this non-string token a label for better error reporting."); } ostr.WriteLine(" \"<token of kind " + re.Ordinal + ">\","); } } } ostr.WriteLine(" };"); ostr.WriteLine(""); ostr.WriteLine("}"); if (namespaceInserted) { ostr.WriteLine("}"); } ostr.Close(); }
private static bool rexpWalk(RegularExpression rexp) { if (rexp is RJustName) { RJustName jn = (RJustName)rexp; if (jn.RegularExpression.WalkStatus == -1) { jn.RegularExpression.WalkStatus = -2; loopString = "..." + jn.RegularExpression.Label + "..."; // Note: Only the regexpr's of RJustName nodes and the top leve // regexpr's can have labels. Hence it is only in these cases that // the labels are checked for to be added to the loopString. return(true); } else if (jn.RegularExpression.WalkStatus == 0) { jn.RegularExpression.WalkStatus = -1; if (rexpWalk(jn.RegularExpression)) { loopString = "..." + jn.RegularExpression.Label + "... --> " + loopString; if (jn.RegularExpression.WalkStatus == -2) { jn.RegularExpression.WalkStatus = 1; CSharpCCErrors.SemanticError(jn.RegularExpression, "Loop in regular expression detected: \"" + loopString + "\""); return(false); } else { jn.RegularExpression.WalkStatus = 1; return(true); } } else { jn.RegularExpression.WalkStatus = 1; return(false); } } } else if (rexp is RChoice) { foreach (var choice in ((RChoice)rexp).Choices) { if (rexpWalk(choice)) { return(true); } } return(false); } else if (rexp is RSequence) { foreach (var unit in ((RSequence)rexp).Units) { if (rexpWalk(unit)) { return(true); } } return(false); } else if (rexp is ROneOrMore) { return(rexpWalk(((ROneOrMore)rexp).RegularExpression)); } else if (rexp is RZeroOrMore) { return(rexpWalk(((RZeroOrMore)rexp).RegularExpression)); } else if (rexp is RZeroOrOne) { return(rexpWalk(((RZeroOrOne)rexp).RegularExpression)); } else if (rexp is RRepetitionRange) { return(rexpWalk(((RRepetitionRange)rexp).RegularExpression)); } return(false); }
public static void start() { if (CSharpCCErrors.ErrorCount != 0) { throw new MetaParseException(); } if (Options.getLookahead() > 1 && !Options.getForceLaCheck() && Options.getSanityCheck()) { CSharpCCErrors.Warning("Lookahead adequacy checking not being performed since option LOOKAHEAD " + "is more than 1. Set option FORCE_LA_CHECK to true to force checking."); } /* * The following walks the entire parse tree to convert all LOOKAHEAD's * that are not at choice points (but at beginning of sequences) and converts * them to trivial choices. This way, their semantic lookahead specification * can be evaluated during other lookahead evaluations. */ foreach (var production in CSharpCCGlobals.bnfproductions) { ExpansionTreeWalker.PostOrderWalk(production.Expansion, new LookaheadFixer()); } /* * The following loop populates "production_table" */ foreach (var p in CSharpCCGlobals.bnfproductions) { if (CSharpCCGlobals.production_table.ContainsKey(p.Lhs)) { CSharpCCErrors.SemanticError(p, p.Lhs + " occurs on the left hand side of more than one production."); } else { CSharpCCGlobals.production_table[p.Lhs] = p; } } /* * The following walks the entire parse tree to make sure that all * non-terminals on RHS's are defined on the LHS. */ foreach (var production in CSharpCCGlobals.bnfproductions) { ExpansionTreeWalker.PreOrderWalk(production.Expansion, new ProductionDefinedChecker()); } /* * The following loop ensures that all target lexical states are * defined. Also piggybacking on this loop is the detection of * <EOF> and <name> in token productions. After reporting an * error, these entries are removed. Also checked are definitions * on inline private regular expressions. * This loop works slightly differently when USER_TOKEN_MANAGER * is set to true. In this case, <name> occurrences are OK, while * regular expression specs generate a warning. */ foreach (var tp in CSharpCCGlobals.rexprlist) { IList <RegExprSpec> respecs = tp.RegexSpecs; foreach (var res in respecs) { if (res.NextState != null) { if (!CSharpCCGlobals.lexstate_S2I.ContainsKey(res.NextState)) { CSharpCCErrors.SemanticError(res.NextStateToken, "Lexical state \"" + res.NextState + "\" has not been defined."); } } if (res.RegularExpression is REndOfFile) { //CSharpCCErrors.SemanticError(res.RegularExpression, "Badly placed <EOF>."); if (tp.LexStates != null) { CSharpCCErrors.SemanticError(res.RegularExpression, "EOF action/state change must be specified for all states, " + "i.e., <*>TOKEN:."); } if (tp.Kind != TokenProduction.TOKEN) { CSharpCCErrors.SemanticError(res.RegularExpression, "EOF action/state change can be specified only in a " + "TOKEN specification."); } if (CSharpCCGlobals.nextStateForEof != null || CSharpCCGlobals.actForEof != null) { CSharpCCErrors.SemanticError(res.RegularExpression, "Duplicate action/state change specification for <EOF>."); } CSharpCCGlobals.actForEof = res.Action; CSharpCCGlobals.nextStateForEof = res.NextState; prepareToRemove(respecs, res); } else if (tp.IsExplicit && Options.getUserTokenManager()) { CSharpCCErrors.Warning(res.RegularExpression, "Ignoring regular expression specification since " + "option USER_TOKEN_MANAGER has been set to true."); } else if (tp.IsExplicit && !Options.getUserTokenManager() && res.RegularExpression is RJustName) { CSharpCCErrors.Warning(res.RegularExpression, "Ignoring free-standing regular expression reference. " + "If you really want this, you must give it a different label as <NEWLABEL:<" + res.RegularExpression.Label + ">>."); prepareToRemove(respecs, res); } else if (!tp.IsExplicit && res.RegularExpression.IsPrivate) { CSharpCCErrors.SemanticError(res.RegularExpression, "Private (#) regular expression cannot be defined within " + "grammar productions."); } } } removePreparedItems(); /* * The following loop inserts all names of regular expressions into * "named_tokens_table" and "ordered_named_tokens". * Duplications are flagged as errors. */ foreach (var tp in CSharpCCGlobals.rexprlist) { IList <RegExprSpec> respecs = tp.RegexSpecs; foreach (var res in respecs) { if (!(res.RegularExpression is RJustName) && !String.IsNullOrEmpty(res.RegularExpression.Label)) { string s = res.RegularExpression.Label; if (CSharpCCGlobals.named_tokens_table.ContainsKey(s)) { CSharpCCErrors.SemanticError(res.RegularExpression, "Multiply defined lexical token name \"" + s + "\"."); } else { CSharpCCGlobals.named_tokens_table[s] = res.RegularExpression; CSharpCCGlobals.ordered_named_tokens.Add(res.RegularExpression); } if (CSharpCCGlobals.lexstate_S2I.ContainsKey(s)) { CSharpCCErrors.SemanticError(res.RegularExpression, "Lexical token name \"" + s + "\" is the same as " + "that of a lexical state."); } } } } /* * The following code merges multiple uses of the same string in the same * lexical state and produces error messages when there are multiple * explicit occurrences (outside the BNF) of the string in the same * lexical state, or when within BNF occurrences of a string are duplicates * of those that occur as non-TOKEN's (SKIP, MORE, SPECIAL_TOKEN) or private * regular expressions. While doing this, this code also numbers all * regular expressions (by setting their ordinal values), and populates the * table "names_of_tokens". */ CSharpCCGlobals.tokenCount = 1; foreach (var tp in CSharpCCGlobals.rexprlist) { IList <RegExprSpec> respecs = tp.RegexSpecs; if (tp.LexStates == null) { tp.LexStates = new String[CSharpCCGlobals.lexstate_I2S.Count]; int i = 0; foreach (var value in CSharpCCGlobals.lexstate_I2S.Values) { tp.LexStates[i++] = value; } } var table = new IDictionary <string, IDictionary <string, RegularExpression> > [tp.LexStates.Length]; for (int i = 0; i < tp.LexStates.Length; i++) { IDictionary <string, IDictionary <string, RegularExpression> > toSet; if (CSharpCCGlobals.simple_tokens_table.TryGetValue(tp.LexStates[i], out toSet)) { table[i] = toSet; } else { table[i] = null; } } foreach (var res in respecs) { if (res.RegularExpression is RStringLiteral) { RStringLiteral sl = (RStringLiteral)res.RegularExpression; // This loop performs the checks and actions with respect to each lexical state. for (int i = 0; i < table.Length; i++) { // Get table of all case variants of "sl.Image" into table2. IDictionary <string, RegularExpression> table2; if (!table[i].TryGetValue(sl.Image.ToUpper(), out table2)) { // There are no case variants of "sl.Image" earlier than the current one. // So go ahead and insert this item. if (sl.Ordinal == 0) { sl.Ordinal = CSharpCCGlobals.tokenCount++; } table2 = new Dictionary <string, RegularExpression>(); table2[sl.Image] = sl; table[i][sl.Image.ToUpper()] = table2; } else if (hasIgnoreCase(table2, sl.Image)) { // hasIgnoreCase sets "other" if it is found. // Since IGNORE_CASE version exists, current one is useless and bad. if (!sl.TokenProductionContext.IsExplicit) { // inline BNF string is used earlier with an IGNORE_CASE. CSharpCCErrors.SemanticError(sl, "String \"" + sl.Image + "\" can never be matched " + "due to presence of more general (IGNORE_CASE) regular expression " + "at line " + other.Line + ", column " + other.Column + "."); } else { // give the standard error message. CSharpCCErrors.SemanticError(sl, "Duplicate definition of string token \"" + sl.Image + "\" " + "can never be matched."); } } else if (sl.TokenProductionContext.IgnoreCase) { // This has to be explicit. A warning needs to be given with respect // to all previous strings. String pos = ""; int count = 0; foreach (var rexp in table2.Values) { if (count != 0) { pos += ","; } pos += " line " + rexp.Line; count++; } if (count == 1) { CSharpCCErrors.Warning(sl, "String with IGNORE_CASE is partially superceded by string at" + pos + "."); } else { CSharpCCErrors.Warning(sl, "String with IGNORE_CASE is partially superceded by strings at" + pos + "."); } // This entry is legitimate. So insert it. if (sl.Ordinal == 0) { sl.Ordinal = CSharpCCGlobals.tokenCount++; } table2[sl.Image] = sl; // The above "put" may override an existing entry (that is not IGNORE_CASE) and that's // the desired behavior. } else { // The rest of the cases do not involve IGNORE_CASE. RegularExpression re; if (!table2.TryGetValue(sl.Image, out re)) { if (sl.Ordinal == 0) { sl.Ordinal = CSharpCCGlobals.tokenCount++; } table2[sl.Image] = sl; } else if (tp.IsExplicit) { // This is an error even if the first occurrence was implicit. if (tp.LexStates[i].Equals("DEFAULT")) { CSharpCCErrors.SemanticError(sl, "Duplicate definition of string token \"" + sl.Image + "\"."); } else { CSharpCCErrors.SemanticError(sl, "Duplicate definition of string token \"" + sl.Image + "\" in lexical state \"" + tp.LexStates[i] + "\"."); } } else if (re.TokenProductionContext.Kind != TokenProduction.TOKEN) { CSharpCCErrors.SemanticError(sl, "String token \"" + sl.Image + "\" has been defined as a \"" + TokenProduction.kindImage[re.TokenProductionContext.Kind] + "\" token."); } else if (re.IsPrivate) { CSharpCCErrors.SemanticError(sl, "String token \"" + sl.Image + "\" has been defined as a private regular expression."); } else { // This is now a legitimate reference to an existing RStringLiteral. // So we assign it a number and take it out of "rexprlist". // Therefore, if all is OK (no errors), then there will be only unequal // string literals in each lexical state. Note that the only way // this can be legal is if this is a string declared inline within the // BNF. Hence, it belongs to only one lexical state - namely "DEFAULT". sl.Ordinal = re.Ordinal; prepareToRemove(respecs, res); } } } } else if (!(res.RegularExpression is RJustName)) { res.RegularExpression.Ordinal = CSharpCCGlobals.tokenCount++; } if (!(res.RegularExpression is RJustName) && !String.IsNullOrEmpty(res.RegularExpression.Label)) { CSharpCCGlobals.names_of_tokens[res.RegularExpression.Ordinal] = res.RegularExpression.Label; } if (!(res.RegularExpression is RJustName)) { CSharpCCGlobals.rexps_of_tokens[res.RegularExpression.Ordinal] = res.RegularExpression; } } } removePreparedItems(); /* * The following code performs a tree walk on all regular expressions * attaching links to "RJustName"s. Error messages are given if * undeclared names are used, or if "RJustNames" refer to private * regular expressions or to regular expressions of any kind other * than TOKEN. In addition, this loop also removes top level * "RJustName"s from "rexprlist". * This code is not executed if Options.getUserTokenManager() is set to * true. Instead the following block of code is executed. */ if (!Options.getUserTokenManager()) { FixRJustNames frjn = new FixRJustNames(); foreach (var tp in CSharpCCGlobals.rexprlist) { IList <RegExprSpec> respecs = tp.RegexSpecs; foreach (var res in respecs) { frjn.root = res.RegularExpression; ExpansionTreeWalker.PreOrderWalk(res.RegularExpression, frjn); if (res.RegularExpression is RJustName) { prepareToRemove(respecs, res); } } } } removePreparedItems(); /* * The following code is executed only if Options.getUserTokenManager() is * set to true. This code visits all top-level "RJustName"s (ignores * "RJustName"s nested within regular expressions). Since regular expressions * are optional in this case, "RJustName"s without corresponding regular * expressions are given ordinal values here. If "RJustName"s refer to * a named regular expression, their ordinal values are set to reflect this. * All but one "RJustName" node is removed from the lists by the end of * execution of this code. */ if (Options.getUserTokenManager()) { foreach (var tp in CSharpCCGlobals.rexprlist) { IList <RegExprSpec> respecs = tp.RegexSpecs; foreach (var res in respecs) { if (res.RegularExpression is RJustName) { RJustName jn = (RJustName)res.RegularExpression; RegularExpression rexp; if (!CSharpCCGlobals.named_tokens_table.TryGetValue(jn.Label, out rexp)) { jn.Ordinal = CSharpCCGlobals.tokenCount++; CSharpCCGlobals.named_tokens_table[jn.Label] = jn; CSharpCCGlobals.ordered_named_tokens.Add(jn); CSharpCCGlobals.names_of_tokens[jn.Ordinal] = jn.Label; } else { jn.Ordinal = rexp.Ordinal; prepareToRemove(respecs, res); } } } } } removePreparedItems(); /* * The following code is executed only if Options.getUserTokenManager() is * set to true. This loop labels any unlabeled regular expression and * prints a warning that it is doing so. These labels are added to * "ordered_named_tokens" so that they may be generated into the ...Constants * file. */ if (Options.getUserTokenManager()) { foreach (var tp in CSharpCCGlobals.rexprlist) { IList <RegExprSpec> respecs = tp.RegexSpecs; foreach (var res in respecs) { int ii = res.RegularExpression.Ordinal; if (!CSharpCCGlobals.names_of_tokens.ContainsKey(ii)) { CSharpCCErrors.Warning(res.RegularExpression, "Unlabeled regular expression cannot be referred to by " + "user generated token manager."); } } } } if (CSharpCCErrors.ErrorCount != 0) { throw new MetaParseException(); } // The following code sets the value of the "emptyPossible" field of NormalProduction // nodes. This field is initialized to false, and then the entire list of // productions is processed. This is repeated as long as at least one item // got updated from false to true in the pass. bool emptyUpdate = true; while (emptyUpdate) { emptyUpdate = false; foreach (var prod in CSharpCCGlobals.bnfproductions) { if (EmptyExpansionExists(prod.Expansion)) { if (!prod.IsEmptyPossible) { emptyUpdate = prod.IsEmptyPossible = true; } } } } if (Options.getSanityCheck() && CSharpCCErrors.ErrorCount == 0) { // The following code checks that all ZeroOrMore, ZeroOrOne, and OneOrMore nodes // do not contain expansions that can expand to the empty token list. foreach (var prod in CSharpCCGlobals.bnfproductions) { ExpansionTreeWalker.PreOrderWalk(prod.Expansion, new EmptyChecker()); } // The following code goes through the productions and adds pointers to other // productions that it can expand to without consuming any tokens. Once this is // done, a left-recursion check can be performed. foreach (var prod in CSharpCCGlobals.bnfproductions) { addLeftMost(prod, prod.Expansion); } // Now the following loop calls a recursive walk routine that searches for // actual left recursions. The way the algorithm is coded, once a node has // been determined to participate in a left recursive loop, it is not tried // in any other loop. foreach (var prod in CSharpCCGlobals.bnfproductions) { if (prod.WalkStatus == 0) { prodWalk(prod); } } // Now we do a similar, but much simpler walk for the regular expression part of // the grammar. Here we are looking for any kind of loop, not just left recursions, // so we only need to do the equivalent of the above walk. // This is not done if option USER_TOKEN_MANAGER is set to true. if (!Options.getUserTokenManager()) { foreach (var tp in CSharpCCGlobals.rexprlist) { IList <RegExprSpec> respecs = tp.RegexSpecs; foreach (var res in respecs) { RegularExpression rexp = res.RegularExpression; if (rexp.WalkStatus == 0) { rexp.WalkStatus = -1; if (rexpWalk(rexp)) { loopString = "..." + rexp.Label + "... --> " + loopString; CSharpCCErrors.SemanticError(rexp, "Loop in regular expression detected: \"" + loopString + "\""); } rexp.WalkStatus = 1; } } } } /* * The following code performs the lookahead ambiguity checking. */ if (CSharpCCErrors.ErrorCount == 0) { foreach (var prod in CSharpCCGlobals.bnfproductions) { ExpansionTreeWalker.PreOrderWalk(prod.Expansion, new LookaheadChecker()); } } } // matches "if (Options.getSanityCheck()) {" if (CSharpCCErrors.ErrorCount != 0) { throw new MetaParseException(); } }