1 using System;
2 using System.Collections;
3 using System.IO;
4
5
6
7 public void PrintHelp()
8 {
9 Console.Out() << "Soul CM Parser Generator version " << soulcm.scmpg.ParserGeneratorVersionStr() << endl();
10 Console.Out() << "Usage: scmpg [options] <file.spg>" << endl();
11 Console.Out() << "Options:" << endl();
12 Console.Out() << "--help | -h" << endl();
13 Console.Out() << " Print help and exit." << endl();
14 Console.Out() << "--verbose | -v" << endl();
15 Console.Out() << " Be verbose." << endl();
16 Console.Out() << "--no-parser-debug-support | -n" << endl();
17 Console.Out() << " Do not generate parser debug support code to the generated parsers." << endl();
18 Console.Out() << "--debug | -d" << endl();
19 Console.Out() << " Debug parsing of .parser file." << endl();
20 }
21
22 public int main(int argc, const char** argv)
23 {
24 try
25 {
26 Uuid moduleId = Uuid.Random();
27 bool verbose = false;
28 bool noParserDebugSupport = false;
29 bool debug = false;
30 string projectFilePath;
31 for (int i = 1; i < argc; ++i;)
32 {
33 string arg = argv[i];
34 if (arg.StartsWith("--"))
35 {
36 if (arg == "--help")
37 {
38 PrintHelp();
39 return 1;
40 }
41 else if (arg == "--verbose")
42 {
43 verbose = true;
44 }
45 else if (arg == "--no-parser-debug-support")
46 {
47 noParserDebugSupport = true;
48 }
49 else if (arg == "--debug")
50 {
51 debug = true;
52 }
53 else
54 {
55 throw Exception("unknown option \'" + arg + "\'");
56 }
57 }
58 else if (arg.StartsWith("-"))
59 {
60 string options = arg.Substring(1);
61 if (options.IsEmpty())
62 {
63 throw Exception("unknown option \'" + arg + "\'");
64 }
65 else
66 {
67 for (char o : options)
68 {
69 if (o == 'h')
70 {
71 PrintHelp();
72 return 1;
73 }
74 else if (o == 'v')
75 {
76 verbose = true;
77 }
78 else if (o == 'n')
79 {
80 noParserDebugSupport = true;
81 }
82 else if (o == 'd')
83 {
84 debug = true;
85 }
86 else
87 {
88 throw Exception("unknown option \'-" + string(o, 1) + "\'");
89 }
90 }
91 }
92 }
93 else
94 {
95 string filePath = GetFullPath(arg);
96 if (Path.GetExtension(filePath) != ".spg")
97 {
98 throw Exception("unknown project file extension \'" + Path.GetExtension(filePath) + "\'");
99 }
100 projectFilePath = filePath;
101 }
102 }
103 if (projectFilePath.IsEmpty())
104 {
105 PrintHelp();
106 return 1;
107 }
108 if (verbose)
109 {
110 Console.Out() << "> " << projectFilePath << endl();
111 }
112 string s = File.ReadAllText(projectFilePath);
113 ustring content = ToUtf32(s);
114 ProjectFileLexer lexer(content, projectFilePath, 0);
115 UniquePtr<soulcm.scmpg.ProjectFile> projectFile = ProjectFileParser.Parse(lexer);
116 int index = 1;
117 List<UniquePtr<soulcm.scmpg.ParserFile>> parserFiles;
118 for (const string& sourceFileName : projectFile->SourceFiles())
119 {
120 string sourceFilePath = Path.Combine(projectFile->BasePath(), sourceFileName);
121 string s = File.ReadAllText(sourceFilePath);
122 ustring content = ToUtf32(s);
123 System.Lex.XmlParsingLog log(Console.Out());
124 ParserFileLexer lexer(content, sourceFilePath, index);
125 if (debug)
126 {
127 lexer.SetLog(&log);
128 }
129 ParsingContext parsingContext;
130 parsingContext.SetModuleId(moduleId);
131 UniquePtr<soulcm.scmpg.ParserFile> parserFile = ParserFileParser.Parse(lexer, &parsingContext);
132 ++index;
133 parserFiles.Add(Rvalue(parserFile));
134 }
135 soulcm.scmpg.Domain domain;
136 if (projectFile->RuleFiles().Count() == 1)
137 {
138 string ruleFilePath = GetFullPath(Path.Combine(projectFile->BasePath(), projectFile->RuleFiles()[0]));
139 domain.SetRuleFilePath(ruleFilePath + ".cm");
140 }
141 else if (projectFile->RuleFiles().Count() > 1)
142 {
143 throw Exception("only one rule file per project allowed");
144 }
145 for (const UniquePtr<soulcm.scmpg.ParserFile>& parserFile : parserFiles)
146 {
147 domain.AddParserFile(parserFile.Get());
148 }
149 soulcm.scmpg.LinkerVisitor linkerVisitor;
150 domain.Accept(linkerVisitor);
151 soulcm.scmpg.CodeGeneratorVisitor codeGeneratorVisitor(verbose, debug, noParserDebugSupport, moduleId);
152 domain.Accept(codeGeneratorVisitor);
153 }
154 catch (const Exception& ex)
155 {
156 Console.Error() << ex.Message() << endl();
157 return 1;
158 }
159 return 0;
160 }