private static void Main(string[] args) { try { string filename; string text; string log; if (GPCG.ProcessOptions(args, out filename, out text, out log)) { using (TextWriter textWriter = (text != null) ? File.CreateText(text) : Console.Out) { Parser parser = new Parser(); Grammar grammar = parser.Parse(filename); LALRGenerator lALRGenerator = new LALRGenerator(grammar); List<State> states = lALRGenerator.BuildStates(); lALRGenerator.ComputeLookAhead(); lALRGenerator.BuildParseTable(); if (GPCG.REPORT) { lALRGenerator.Report(log); } CodeGenerator codeGenerator = new CodeGenerator(textWriter); codeGenerator.Generate(states, grammar); } } } catch (Scanner.ParseException ex) { Console.Error.WriteLine("Parse error (line {0}, column {1}): {2}", ex.line, ex.column, ex.Message); } catch (Exception ex2) { Console.Error.WriteLine("Unexpected Error {0}", ex2.Message); Console.Error.WriteLine("Please report to [email protected]"); } }
private static void Main(string[] args) { try { string filename = ProcessOptions(args); if (filename == null) return; Parser parser = new Parser(); Grammar grammar = parser.Parse(filename); LALRGenerator generator = new LALRGenerator(grammar); List<State> states = generator.BuildStates(); generator.ComputeLookAhead(); generator.BuildParseTable(); if (!grammar.CheckGrammar()) throw new Exception("Non-terminating grammar"); if (REPORT) generator.Report(); else { CodeGenerator code = new CodeGenerator(); code.Generate(states, grammar); } } catch (Scanner.ParseException e) { Console.Error.WriteLine("Parse error (line {0}, column {1}): {2}", e.line, e.column, e.Message); } catch (System.Exception e) { Console.Error.WriteLine("Unexpected Error {0}", e.Message); } }
private static void Main(string[] args) { try { string filename = ProcessOptions(args); if (filename == null) return; Assembly assm = Assembly.GetExecutingAssembly(); object info = Attribute.GetCustomAttribute(assm, typeof(AssemblyInformationalVersionAttribute)); versionInfo = ((AssemblyInformationalVersionAttribute)info).InformationalVersion; Parser parser = new Parser(); Grammar grammar = parser.Parse(filename); LALRGenerator generator = new LALRGenerator(grammar); List<State> states = generator.BuildStates(); generator.ComputeLookAhead(); generator.BuildParseTable(); if (!grammar.CheckGrammar()) throw new Exception("Non-terminating grammar"); if (REPORT) generator.Report(); else { CodeGenerator code = new CodeGenerator(); code.Generate(states, grammar); } } catch (Scanner.ParseException e) { Console.Error.WriteLine("Parse error (line {0}, column {1}): {2}", e.line, e.column, e.Message); } catch (System.Exception e) { Console.Error.WriteLine("Unexpected Error {0}", e.Message); } }
public void GenerateCode(CodeGenerator codeGenerator) { int i = 0; string lineTag = ""; if (commands.StartsWith("#line")) { lineTag = commands.Substring(0, commands.IndexOf('"')).Trim(); } while (i < commands.Length) { switch (commands[i]) { case '/': Output(i++); if (commands[i] == '/') // C++ style comments { while (i < commands.Length && commands[i] != '\n') Output(i++); if (i < commands.Length) Output(i++); } else if (commands[i] == '*') // C style comments { Output(i++); do { while (i < commands.Length && commands[i] != '*') Output(i++); if (i < commands.Length) Output(i++); } while (i < commands.Length && commands[i] != '/'); if (i < commands.Length) Output(i++); } break; case '"': // start of string literal Output(i++); while (i < commands.Length && commands[i] != '"') { if (commands[i] == '\\') Output(i++); if (i < commands.Length) Output(i++); } if (i < commands.Length) Output(i++); break; case '@': // Possible start of verbatim string literal // but also possible location marker access if (i + 1 < commands.Length) { char la = commands[i + 1]; // lookahead character if (la == '$') { i += 2; // read past '@', '$' Console.Write("yyloc"); } else if (Char.IsDigit(la)) { int num = (int)la - (int)'0'; i += 2; // read past '@', digit if (i < commands.Length && char.IsDigit(commands[i])) ErrReport(lineTag, "Only indexes up \"$9\" allowed"); else if (num > this.production.rhs.Count) ErrReport(lineTag, String.Format("Index @{0} is out of bounds", num)); Console.Write("GetLocation({0})", pos - num + 1); } else { Output(i++); if (la == '"') { Output(i++); while (i < commands.Length && commands[i] != '"') Output(i++); if (i < commands.Length) Output(i++); break; } } } else ErrReport(lineTag, "Invalid use of '@'"); break; case '\'': // start of char literal Output(i++); while (i < commands.Length && commands[i] != '\'') { if (commands[i] == '\\') Output(i++); if (i < commands.Length) Output(i++); } if (i < commands.Length) Output(i++); break; case '$': // $$ or $n placeholder i++; if (i < commands.Length) { string kind = null; if (commands[i] == '<') // $<kind>n { i++; StringBuilder builder = new StringBuilder(); while (i < commands.Length && commands[i] != '>') { builder.Append(commands[i]); i++; } if (i < commands.Length) { i++; kind = builder.ToString(); } } if (commands[i] == '$') { i++; if (kind == null) kind = production.lhs.kind; Console.Write("yyval"); if (kind != null) Console.Write(".{0}", kind); } else if (char.IsDigit(commands[i])) { int num = commands[i] - '0'; i++; if (i < commands.Length && char.IsDigit(commands[i])) ErrReport(lineTag, "Only indexes up \"$9\" allowed"); else if (num > this.production.rhs.Count) ErrReport(lineTag, String.Format("Index ${0} is out of bounds", num)); if (kind == null) kind = production.rhs[num - 1].kind; Console.Write("GetValue({0})", pos - num + 1); if (kind != null) Console.Write(".{0}", kind); } } else ErrReport(lineTag, "Unexpected '$'"); break; default: Output(i++); break; } } Console.WriteLine(); }
private void Output(CodeGenerator codeGenerator, int i) { if (this.commands[i] == '\n') { codeGenerator.Output.WriteLine(); return; } codeGenerator.Output.Write(this.commands[i]); }
private void ParseItemReference(CodeGenerator codeGenerator, string item, string kind, int line, ref int i) { if (this.commands[i] == '$') { i++; if (kind == null) { kind = this.production.lhs.kind; } codeGenerator.Output.Write(item); if (!string.IsNullOrEmpty(kind)) { codeGenerator.Output.Write(".{0}", kind); return; } } else { if (char.IsDigit(this.commands[i])) { int num = (int)(this.commands[i] - '0'); i++; while (i < this.commands.Length && this.commands[i] >= '0' && this.commands[i] <= '9') { num = 10 * num + (int)this.commands[i] - 48; i++; } if (num <= 0 || num > this.production.rhs.Count) { throw new Scanner.ParseException(line, this.pos, string.Format("Invalid production token number {0}.", num)); } if (kind == null) { kind = this.production.rhs[num - 1].kind; } codeGenerator.Output.Write("value_stack.array[value_stack.top-{0}].{1}", this.pos - num + 1, item); if (!string.IsNullOrEmpty(kind)) { codeGenerator.Output.Write(".{0}", kind); return; } } else { Console.Error.WriteLine("Unexpected '$' at ({0}:{1})", line, i); } } }
public void GenerateCode(CodeGenerator codeGenerator) { int i = 0; int num = this.startLine; while (i < this.commands.Length) { char c = this.commands[i]; if (c <= '$') { if (c == '\n') { num++; this.Output(codeGenerator, i++); continue; } switch (c) { case '"': this.Output(codeGenerator, i++); while (i < this.commands.Length && this.commands[i] != '"') { if (this.commands[i] == '\\') { this.Output(codeGenerator, i++); } if (i < this.commands.Length) { this.Output(codeGenerator, i++); } } if (i < this.commands.Length) { this.Output(codeGenerator, i++); continue; } continue; case '$': { i++; string kind = this.ParseKind(codeGenerator, num, ref i); this.ParseItemReference(codeGenerator, "yyval", kind, num, ref i); continue; } } } else { if (c != '\'') { if (c != '/') { if (c == '@') { if (i + 1 >= this.commands.Length || this.commands[i + 1] != '"') { i++; this.ParseItemReference(codeGenerator, "yypos", "", num, ref i); continue; } this.Output(codeGenerator, i++); this.Output(codeGenerator, i++); while (i < this.commands.Length && this.commands[i] != '"') { this.Output(codeGenerator, i++); } if (i < this.commands.Length) { this.Output(codeGenerator, i++); continue; } continue; } } else { this.Output(codeGenerator, i++); if (this.commands[i] == '/') { while (i < this.commands.Length && this.commands[i] != '\n') { this.Output(codeGenerator, i++); } if (i < this.commands.Length) { this.Output(codeGenerator, i++); continue; } continue; } else { if (this.commands[i] != '*') { continue; } this.Output(codeGenerator, i++); while (true) { if (i >= this.commands.Length || this.commands[i] == '*') { if (i < this.commands.Length) { this.Output(codeGenerator, i++); } if (i >= this.commands.Length || this.commands[i] == '/') { break; } } else { this.Output(codeGenerator, i++); } } if (i < this.commands.Length) { this.Output(codeGenerator, i++); continue; } continue; } } } else { this.Output(codeGenerator, i++); while (i < this.commands.Length && this.commands[i] != '\'') { if (this.commands[i] == '\\') { this.Output(codeGenerator, i++); } if (i < this.commands.Length) { this.Output(codeGenerator, i++); } } if (i < this.commands.Length) { this.Output(codeGenerator, i++); continue; } continue; } } this.Output(codeGenerator, i++); } codeGenerator.Output.WriteLine(); }
private string ParseKind(CodeGenerator codeGenerator, int line, ref int i) { if (this.commands[i] == '<') { i++; StringBuilder stringBuilder = new StringBuilder(); while (i < this.commands.Length && this.commands[i] != '>') { stringBuilder.Append(this.commands[i]); i++; } if (i < this.commands.Length) { i++; return stringBuilder.ToString(); } Console.Error.WriteLine("Expected '>' at ({0}:{1})", line, i); } return null; }
public void GenerateCode(CodeGenerator codeGenerator) { int i = 0; string lineTag = ""; if (commands.StartsWith("#line")) lineTag = commands.Substring(0, commands.IndexOf('"')).Trim(); int length = commands.Length; while (i < length) { switch (commands[i]) { case 'Y': { int j = i; do { j++; } while (j < length && char.IsLetter(commands, j)); string substr = commands.Substring(i, j - i); if (substr.Equals("YYACCEPT")) { i = j; Console.Write("YYAccept()"); } else if (substr.Equals("YYABORT")) { i = j; Console.Write("YYAbort()"); } else if (substr.Equals("YYERROR")) { i = j; Console.Write("YYError()"); } else Output(i++); break; } case '/': Output(i++); if (i < length && commands[i] == '/') // C++ style comments { while (i < length && commands[i] != '\n') Output(i++); if (i < length) Output(i++); } else if (i < length && commands[i] == '*') // C style comments { Output(i++); do { while (i < length && commands[i] != '*') Output(i++); if (i < length) Output(i++); } while (i < length && commands[i] != '/'); if (i < length) Output(i++); } break; case '"': // start of string literal Output(i++); while (i < length && commands[i] != '"') { if (commands[i] == '\\') Output(i++); if (i < length) Output(i++); } if (i < length) Output(i++); break; case '@': // Possible start of verbatim string literal // but also possible location marker access if (i + 1 < length) { char la = commands[i + 1]; // lookahead character if (la == '$') { i += 2; // read past '@', '$' Console.Write("yyloc"); } else if (Char.IsDigit(la)) { i++; int num = (int)commands[i++] - (int)'0'; while (i < length && char.IsDigit(commands[i])) num = num * 10 + (int)commands[i++] - (int)'0'; if (num > this.production.rhs.Count) ErrReport(lineTag, String.Format("Index @{0} is out of bounds", num)); Console.Write("location_stack.array[location_stack.top-{0}]", pos - num + 1); } else { Output(i++); if (la == '"') { Output(i++); while (i < length && commands[i] != '"') Output(i++); if (i < length) Output(i++); break; } } } else ErrReport(lineTag, "Invalid use of '@'"); break; case '\'': // start of char literal Output(i++); while (i < length && commands[i] != '\'') { if (commands[i] == '\\') Output(i++); if (i < length) Output(i++); } if (i < length) Output(i++); break; case '$': // $$ or $n placeholder i++; if (i < length) { string kind = null; if (commands[i] == '<') // $<kind>n { i++; StringBuilder builder = new StringBuilder(); while (i < length && commands[i] != '>') { builder.Append(commands[i]); i++; } if (i < length) { i++; kind = builder.ToString(); } } if (commands[i] == '$') { i++; if (kind == null) kind = production.lhs.kind; Console.Write("yyval"); if (kind != null) Console.Write(".{0}", kind); } else if (char.IsDigit(commands[i])) { int num = (int)commands[i++] - (int)'0'; while (i < length && char.IsDigit(commands[i])) num = num * 10 + (int)commands[i++] - (int)'0'; if (num > this.production.rhs.Count) ErrReport(lineTag, String.Format("Index ${0} is out of bounds", num)); if (kind == null) kind = production.rhs[num - 1].kind; Console.Write("value_stack.array[value_stack.top-{0}]", pos - num + 1); if (kind != null) Console.Write(".{0}", kind); } } else ErrReport(lineTag, "Unexpected '$'"); break; default: Output(i++); break; } } Console.WriteLine(); }