14 using System.Collections.Generic;
15 using System.ComponentModel;
18 using System.Windows.Forms;
19 using System.Diagnostics;
21 using System.Configuration;
22 using System.Text.RegularExpressions;
25 using Irony.GrammarExplorer.Properties;
28 namespace Irony.GrammarExplorer {
31 InitializeComponent();
32 _grammarLoader.AssemblyUpdated += GrammarAssemblyUpdated;
43 #region Form load/unload events
44 private void fmExploreGrammar_Load(
object sender,
EventArgs e) {
47 txtSource.Text = Settings.Default.SourceSample;
48 txtSearch.Text = Settings.Default.SearchPattern;
49 GrammarItemList grammars = GrammarItemList.FromXml(Settings.Default.Grammars);
50 grammars.ShowIn(cboGrammars);
51 chkParserTrace.Checked = Settings.Default.EnableTrace;
52 chkDisableHili.Checked = Settings.Default.DisableHili;
53 chkAutoRefresh.Checked = Settings.Default.AutoRefresh;
54 cboGrammars.SelectedIndex = Settings.Default.LanguageIndex;
59 private void fmExploreGrammar_FormClosing(
object sender, FormClosingEventArgs e) {
60 Settings.Default.SourceSample = txtSource.Text;
61 Settings.Default.LanguageIndex = cboGrammars.SelectedIndex;
62 Settings.Default.SearchPattern = txtSearch.Text;
63 Settings.Default.EnableTrace = chkParserTrace.Checked;
64 Settings.Default.DisableHili = chkDisableHili.Checked;
65 Settings.Default.AutoRefresh = chkAutoRefresh.Checked;
66 var grammars = GrammarItemList.FromCombo(cboGrammars);
67 Settings.Default.Grammars = grammars.ToXml();
68 Settings.Default.Save();
72 #region Show... methods
74 private void ClearLanguageInfo() {
75 lblLanguage.Text = string.Empty;
76 lblLanguageVersion.Text = string.Empty;
77 lblLanguageDescr.Text = string.Empty;
78 txtGrammarComments.Text = string.Empty;
81 private void ClearParserOutput() {
82 lblSrcLineCount.Text = string.Empty;
83 lblSrcTokenCount.Text =
"";
84 lblParseTime.Text =
"";
85 lblParseErrorCount.Text =
"";
87 lstTokens.Items.Clear();
88 gridCompileErrors.Rows.Clear();
89 gridParserTrace.Rows.Clear();
90 lstTokens.Items.Clear();
91 tvParseTree.Nodes.Clear();
93 Application.DoEvents();
96 private void ShowLanguageInfo() {
97 if (_grammar == null)
return;
98 var langAttr = LanguageAttribute.GetValue(_grammar.GetType());
99 if (langAttr == null)
return;
100 lblLanguage.Text = langAttr.LanguageName;
101 lblLanguageVersion.Text = langAttr.Version;
102 lblLanguageDescr.Text = langAttr.Description;
103 txtGrammarComments.Text = _grammar.GrammarComments;
106 private void ShowCompilerErrors() {
107 gridCompileErrors.Rows.Clear();
108 if (_parseTree == null || _parseTree.ParserMessages.Count == 0)
return;
109 foreach (var err
in _parseTree.ParserMessages)
110 gridCompileErrors.Rows.Add(err.Location, err, err.ParserState);
111 var needPageSwitch = tabBottom.SelectedTab != pageParserOutput &&
112 !(tabBottom.SelectedTab == pageParserTrace && chkParserTrace.Checked);
114 tabBottom.SelectedTab = pageParserOutput;
117 private void ShowParseTrace() {
118 gridParserTrace.Rows.Clear();
119 foreach (var entry
in _parser.Context.ParserTrace) {
120 int index = gridParserTrace.Rows.Add(entry.State, entry.StackTop, entry.Input, entry.Message);
122 gridParserTrace.Rows[gridParserTrace.Rows.Count - 1].DefaultCellStyle.ForeColor = Color.Red;
125 foreach (
Token tkn
in _parseTree.Tokens) {
127 lstTokens.Items.Add(tkn);
131 private void ShowCompileStats() {
132 if (_parseTree == null)
return;
133 lblSrcLineCount.Text = string.Empty;
134 if (_parseTree.Tokens.Count > 0)
135 lblSrcLineCount.Text = (_parseTree.Tokens[_parseTree.Tokens.Count - 1].Location.Line + 1).ToString();
136 lblSrcTokenCount.Text = _parseTree.Tokens.Count.ToString();
137 lblParseTime.Text = _parseTree.ParseTime.ToString();
138 lblParseErrorCount.Text = _parseTree.ParserMessages.Count.ToString();
139 Application.DoEvents();
143 private void ShowParseTree() {
144 tvParseTree.Nodes.Clear();
145 if (_parseTree == null)
return;
146 AddParseNodeRec(null, _parseTree.Root);
148 private void AddParseNodeRec(TreeNode parent,
ParseTreeNode node) {
149 if (node == null)
return;
150 string txt = node.ToString();
151 TreeNode tvNode = (parent == null? tvParseTree.Nodes.Add(txt) : parent.Nodes.Add(txt) );
154 AddParseNodeRec(tvNode, child);
157 private void ShowAstTree() {
159 if (_parseTree == null || _parseTree.Root == null || _parseTree.Root.AstNode == null)
return;
160 AddAstNodeRec(null, _parseTree.Root.AstNode);
163 private void AddAstNodeRec(TreeNode parent,
object astNode) {
164 if (astNode == null)
return;
165 string txt = astNode.ToString();
166 TreeNode newNode = (parent == null ?
167 tvAst.Nodes.Add(txt) : parent.Nodes.Add(txt));
168 newNode.Tag = astNode;
170 if (iBrowsable == null)
return;
171 var childList = iBrowsable.GetChildNodes();
172 foreach (var child
in childList)
173 AddAstNodeRec(newNode, child);
176 private void ShowParserConstructionResults() {
177 lblParserStateCount.Text = _language.ParserData.States.Count.ToString();
178 lblParserConstrTime.Text = _language.ConstructionTime.ToString();
179 txtParserStates.Text = string.Empty;
180 gridGrammarErrors.Rows.Clear();
181 txtTerms.Text = string.Empty;
182 txtNonTerms.Text = string.Empty;
183 txtParserStates.Text = string.Empty;
184 tabBottom.SelectedTab = pageLanguage;
185 if (_parser == null)
return;
186 txtTerms.Text = ParserDataPrinter.PrintTerminals(_parser.Language);
187 txtNonTerms.Text = ParserDataPrinter.PrintNonTerminals(_parser.Language);
188 txtParserStates.Text = ParserDataPrinter.PrintStateList(_parser.Language);
192 private void ShowGrammarErrors() {
193 gridGrammarErrors.Rows.Clear();
194 var errors = _parser.Language.Errors;
195 if (errors.Count == 0)
return;
196 foreach (var err
in errors)
197 gridGrammarErrors.Rows.Add(err.Level.ToString(), err.Message, err.State);
198 if (tabBottom.SelectedTab != pageGrammarErrors)
199 tabBottom.SelectedTab = pageGrammarErrors;
202 private void ShowSourceLocation(
SourceLocation location,
int length) {
204 txtSource.SelectionStart = location.Position;
205 txtSource.SelectionLength = length;
207 txtSource.ScrollToCaret();
208 if (tabGrammar.SelectedTab != pageTest)
209 tabGrammar.SelectedTab = pageTest;
213 private void ShowSourceLocationAndTraceToken(
SourceLocation location,
int length) {
214 ShowSourceLocation(location, length);
216 for (
int i = 0; i < lstTokens.Items.Count; i++) {
217 var tkn = lstTokens.Items[i] as
Token;
218 if (tkn.Location.Position == location.
Position) {
219 lstTokens.SelectedIndex = i;
224 private void LocateParserState(
ParserState state) {
225 if (state == null)
return;
226 if (tabGrammar.SelectedTab != pageParserStates)
227 tabGrammar.SelectedTab = pageParserStates;
229 txtParserStates.SelectionStart = txtParserStates.Text.Length - 1;
230 txtParserStates.ScrollToCaret();
231 DoSearch(txtParserStates,
"State " + state.
Name, 0);
234 private void ClearRuntimeInfo() {
235 lnkShowErrLocation.Enabled =
false;
236 lnkShowErrStack.Enabled =
false;
237 txtOutput.Text = string.Empty;
242 #region Grammar combo menu commands
243 private void menuGrammars_Opening(
object sender, CancelEventArgs e) {
244 miRemove.Enabled = cboGrammars.Items.Count > 0;
247 private void miAdd_Click(
object sender,
EventArgs e) {
248 if (dlgSelectAssembly.ShowDialog() != DialogResult.OK)
return;
249 string location = dlgSelectAssembly.FileName;
250 if (
string.IsNullOrEmpty(location))
return;
251 var oldGrammars =
new GrammarItemList();
252 foreach(var item
in cboGrammars.Items)
253 oldGrammars.Add((GrammarItem) item);
254 var grammars = fmSelectGrammars.SelectGrammars(location, oldGrammars);
255 if (grammars == null)
return;
256 foreach (GrammarItem item
in grammars)
257 cboGrammars.Items.Add(item);
259 if (cboGrammars.SelectedIndex < 0 && grammars.Count > 0)
260 cboGrammars.SelectedIndex = 0;
263 private void miRemove_Click(
object sender,
EventArgs e) {
264 if (MessageBox.Show(
"Are you sure you want to remove grammmar " + cboGrammars.SelectedItem +
"?",
265 "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) {
266 cboGrammars.Items.RemoveAt(cboGrammars.SelectedIndex);
268 if (cboGrammars.Items.Count > 0)
269 cboGrammars.SelectedIndex = 0;
273 private void miRemoveAll_Click(
object sender,
EventArgs e) {
274 if (MessageBox.Show(
"Are you sure you want to remove all grammmars in the list?",
275 "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) {
276 cboGrammars.Items.Clear();
282 #region Parsing and running
283 private void CreateGrammar() {
284 _grammar = _grammarLoader.CreateGrammar();
287 private void CreateParser() {
289 btnRun.Enabled =
false;
290 txtOutput.Text = string.Empty;
293 btnRun.Enabled = _grammar.FlagIsSet(LanguageFlags.CanRunSample);
294 _language = _grammar.CreateLanguageData();
295 _parser =
new Parsing.Parser (_language);
296 ShowParserConstructionResults();
300 private void ParseSample() {
302 if (_parser == null || !_parser.Language.CanParse())
return;
305 _parser.Context.SetOption(ParseOptions.TraceParser, chkParserTrace.Checked);
307 _parser.Parse(txtSource.Text,
"<source>");
309 gridCompileErrors.Rows.Add(null, ex.Message, null);
310 tabBottom.SelectedTab = pageParserOutput;
313 _parseTree = _parser.Context.CurrentParseTree;
314 ShowCompilerErrors();
315 if (chkParserTrace.Checked) {
324 private void WriteOutput(
string text) {
325 if (
string.IsNullOrEmpty(text))
return;
326 txtOutput.Text += text + Environment.NewLine;
327 txtOutput.Select(txtOutput.Text.Length - 1, 0);
332 #region miscellaneous: LoadSourceFile, Search, Source highlighting
333 private void LoadSourceFile(
string path) {
338 txtSource.Text = null;
339 txtSource.Text = reader.ReadToEnd();
340 txtSource.Select(0, 0);
342 MessageBox.Show(e.Message);
350 RichTextBoxHighlighter _highlighter;
351 private void StartHighlighter() {
352 if (_highlighter != null)
354 if (chkDisableHili.Checked)
return;
355 if (!_parser.Language.CanParse())
return;
356 _highlighter =
new RichTextBoxHighlighter(txtSource, _language);
357 _highlighter.Adapter.Activate();
359 private void StopHighlighter() {
360 if (_highlighter == null)
return;
361 _highlighter.Dispose();
365 private void ClearHighlighting() {
366 var txt = txtSource.Text;
368 txtSource.Text = txt;
370 private void EnableHighlighter(
bool enable) {
371 if (_highlighter != null)
378 private void DoSearch() {
379 lblSearchError.Visible =
false;
380 TextBoxBase textBox = GetSearchContentBox();
381 if (textBox == null)
return;
382 int idxStart = textBox.SelectionStart + textBox.SelectionLength;
383 if (!DoSearch(textBox, txtSearch.Text, idxStart)) {
384 lblSearchError.Text =
"Not found.";
385 lblSearchError.Visible =
true;
389 private bool DoSearch(TextBoxBase textBox,
string fragment,
int start) {
390 textBox.SelectionLength = 0;
392 Regex r =
new Regex(fragment, RegexOptions.IgnoreCase);
394 Match m = r.Match(textBox.Text.Substring(start));
397 Group g = m.Groups[i];
398 CaptureCollection cc = g.Captures;
400 textBox.SelectionStart = c.Index + start;
401 textBox.SelectionLength = c.Length;
403 textBox.ScrollToCaret();
410 switch (tabGrammar.SelectedIndex) {
416 return txtParserStates;
426 #region Controls event handlers
428 private void btnParse_Click(
object sender,
EventArgs e) {
432 private void btnRun_Click(
object sender,
EventArgs e)
434 MessageBox.Show(
this,
"No longer implemented");
437 private void tvParseTree_AfterSelect(
object sender, TreeViewEventArgs e) {
438 var vtreeNode = tvParseTree.SelectedNode;
439 if (vtreeNode == null)
return;
441 if (parseNode == null)
return;
442 ShowSourceLocation(parseNode.Span.Location, 1);
445 private void tvAst_AfterSelect(
object sender, TreeViewEventArgs e) {
446 var treeNode = tvAst.SelectedNode;
447 if (treeNode == null)
return;
448 var iBrowsable = treeNode.Tag as IBrowsableAstNode;
449 if (iBrowsable == null)
return;
450 ShowSourceLocation(iBrowsable.Location, 1);
453 bool _changingGrammar;
454 private void LoadSelectedGrammar() {
460 _changingGrammar =
true;
465 _changingGrammar =
false;
469 private void cboGrammars_SelectedIndexChanged(
object sender,
EventArgs e) {
470 _grammarLoader.SelectedGrammar = cboGrammars.SelectedItem as GrammarItem;
471 LoadSelectedGrammar();
474 private void GrammarAssemblyUpdated(
object sender,
EventArgs args) {
475 if (InvokeRequired) {
476 Invoke(
new EventHandler(GrammarAssemblyUpdated), sender, args);
479 if (chkAutoRefresh.Checked) {
480 LoadSelectedGrammar();
481 txtGrammarComments.Text += String.Format(
"{0}Grammar assembly reloaded: {1:HH:mm:ss}", Environment.NewLine, DateTime.Now);
485 private void btnFileOpen_Click(
object sender,
EventArgs e) {
486 if (dlgOpenFile.ShowDialog() != DialogResult.OK)
return;
487 LoadSourceFile(dlgOpenFile.FileName);
490 private void txtSource_TextChanged(
object sender,
EventArgs e) {
494 private void btnManageGrammars_Click(
object sender,
EventArgs e) {
495 menuGrammars.Show(btnManageGrammars, 0, btnManageGrammars.Height);
498 private void btnToXml_Click(
object sender,
EventArgs e) {
499 txtOutput.Text = string.Empty;
500 if (_parseTree == null)
502 if (_parseTree == null)
return;
503 txtOutput.Text += _parseTree.ToXml();
504 txtOutput.Select(0, 0);
505 tabBottom.SelectedTab = pageOutput;
508 private void cboParseMethod_SelectedIndexChanged(
object sender,
EventArgs e) {
511 if (!_changingGrammar)
515 private void gridParserTrace_CellDoubleClick(
object sender, DataGridViewCellEventArgs e) {
516 if (_parser.Context == null || e.RowIndex < 0 || e.RowIndex >= _parser.Context.ParserTrace.Count)
return;
517 var entry = _parser.Context.ParserTrace[e.RowIndex];
518 switch (e.ColumnIndex) {
521 LocateParserState(entry.State);
524 if (entry.StackTop != null)
525 ShowSourceLocationAndTraceToken(entry.StackTop.Span.Location, entry.StackTop.Span.Length);
528 if (entry.Input != null)
529 ShowSourceLocationAndTraceToken(entry.Input.Span.Location, entry.Input.Span.Length);
534 private void lstTokens_Click(
object sender,
EventArgs e) {
535 if (lstTokens.SelectedIndex < 0)
541 private void gridCompileErrors_CellDoubleClick(
object sender, DataGridViewCellEventArgs e) {
542 if (e.RowIndex < 0 || e.RowIndex >= gridCompileErrors.Rows.Count)
return;
543 var err = gridCompileErrors.Rows[e.RowIndex].Cells[1].Value as
ParserMessage;
544 switch (e.ColumnIndex) {
547 ShowSourceLocation(err.Location, 1);
550 if (err.ParserState != null)
551 LocateParserState(err.ParserState);
556 private void gridGrammarErrors_CellDoubleClick(
object sender, DataGridViewCellEventArgs e) {
557 if (e.RowIndex < 0 || e.RowIndex >= gridGrammarErrors.Rows.Count)
return;
558 var state = gridGrammarErrors.Rows[e.RowIndex].Cells[2].Value as
ParserState;
560 LocateParserState(state);
563 private void btnSearch_Click(
object sender,
EventArgs e) {
567 private void txtSearch_KeyPress(
object sender, KeyPressEventArgs e) {
568 if (e.KeyChar ==
'\r')
572 private void lnkShowErrLocation_LinkClicked(
object sender, LinkLabelLinkClickedEventArgs e)
574 MessageBox.Show(
this,
"No longer implemented");
577 private void lnkShowErrStack_LinkClicked(
object sender, LinkLabelLinkClickedEventArgs e) {
578 MessageBox.Show(
this,
"No longer implemented");
583 private void chkDisableHili_CheckedChanged(
object sender,
EventArgs e) {
584 if (!_loaded)
return;
585 EnableHighlighter(!chkDisableHili.Checked);
TokenCategory
Token category.
TokenCategory Category
Gets the category.
Maintains grammar assemblies, reloads updated files automatically.
readonly SourceLocation Location
Location in the source code.
ParseTreeNodeList ChildNodes
TextBoxBase GetSearchContentBox()
Tokens are produced by scanner and fed to parser, optionally passing through Token filters in between...
int Length
Gets the length.