Example #1
0
		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]");
			}
		}
Example #2
0
        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);
            }
        }
Example #3
0
        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);
            }
        }
Example #4
0
        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();
        }
Example #5
0
		private void Output(CodeGenerator codeGenerator, int i)
		{
			if (this.commands[i] == '\n')
			{
				codeGenerator.Output.WriteLine();
				return;
			}
			codeGenerator.Output.Write(this.commands[i]);
		}
Example #6
0
		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);
				}
			}
		}
Example #7
0
		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();
		}
Example #8
0
		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;
		}
Example #9
0
        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();
        }