Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
LineContinuationTerminal.cs
Go to the documentation of this file.
1 using System;
2 using System.Linq;
3 using System.Collections.Generic;
4 using System.Text;
5 
6 namespace Irony.Parsing {
7 
9 
10  public LineContinuationTerminal(string name, params string[] startSymbols) : base(name, TokenCategory.Outline) {
11  var symbols = startSymbols.Where(s => !IsNullOrWhiteSpace(s)).ToArray();
12  StartSymbols = new StringList(symbols);
13  if (StartSymbols.Count == 0)
14  StartSymbols.AddRange(_defaultStartSymbols);
15  Priority = Terminal.HighestPriority;
16  }
17 
19  private string _startSymbolsFirsts = String.Concat(_defaultStartSymbols);
20  static string[] _defaultStartSymbols = new[] { "\\", "_" };
21  public string LineTerminators = "\n\r\v";
22 
23  #region overrides
24 
25  public override void Init(GrammarData grammarData) {
26  base.Init(grammarData);
27 
28  // initialize string of start characters for fast lookup
29  _startSymbolsFirsts = new String(StartSymbols.Select(s => s.First()).ToArray());
30 
31  if (this.EditorInfo == null) {
32  this.EditorInfo = new TokenEditorInfo(TokenType.Delimiter, TokenColor.Comment, TokenTriggers.None);
33  }
34  }
35 
36  public override Token TryMatch(ParsingContext context, ISourceStream source) {
37  // Quick check
38  var lookAhead = source.PreviewChar;
39  var startIndex = _startSymbolsFirsts.IndexOf(lookAhead);
40  if (startIndex < 0)
41  return null;
42 
43  // Match start symbols
44  if (!BeginMatch(source, startIndex, lookAhead))
45  return null;
46 
47  // Match NewLine
48  var result = CompleteMatch(source);
49  if (result != null)
50  return result;
51 
52  // Report an error
53  return source.CreateErrorToken(Resources.ErrNewLineExpected);
54  }
55 
56  private bool BeginMatch(ISourceStream source, int startFrom, char lookAhead) {
57  foreach (var startSymbol in StartSymbols.Skip(startFrom)) {
58  if (startSymbol[0] != lookAhead)
59  continue;
60  if (source.MatchSymbol(startSymbol, !Grammar.CaseSensitive)) {
61  source.PreviewPosition += startSymbol.Length;
62  return true;
63  }
64  }
65  return false;
66  }
67 
68  private Token CompleteMatch(ISourceStream source) {
69  if (source.EOF())
70  return null;
71 
72  do {
73  // Match NewLine
74  var lookAhead = source.PreviewChar;
75  if (LineTerminators.IndexOf(lookAhead) >= 0)
76  {
77  source.PreviewPosition++;
78  // Treat \r\n as single NewLine
79  if (!source.EOF() && lookAhead == '\r' && source.PreviewChar == '\n')
80  source.PreviewPosition++;
81  break;
82  }
83 
84  // Eat up whitespace
85  if (GrammarData.Grammar.WhitespaceChars.IndexOf(lookAhead) >= 0)
86  {
87  source.PreviewPosition++;
88  continue;
89  }
90 
91  // Fail on anything else
92  return null;
93  }
94  while (!source.EOF());
95 
96  // Create output token
97  return source.CreateToken(this.OutputTerminal);
98  }
99 
100  public override IList<string> GetFirsts() {
101  return StartSymbols;
102  }
103 
104  #endregion
105 
106  private static bool IsNullOrWhiteSpace(string s) {
107 #if VS2008
108  if (String.IsNullOrEmpty(s))
109  return true;
110  return s.Trim().Length == 0;
111 #else
112  return String.IsNullOrWhiteSpace(s);
113 #endif
114  }
115 
116  } // LineContinuationTerminal class
117 }
TokenCategory
Token category.
Definition: Token.cs:29
LineContinuationTerminal(string name, params string[] startSymbols)
override Token TryMatch(ParsingContext context, ISourceStream source)
Interface for Terminals to access the source stream and produce tokens.
readonly bool CaseSensitive
Gets case sensitivity of the grammar. Read-only, true by default. Can be set to false only through a ...
Definition: Grammar.cs:27
function s(a)
Tokens are produced by scanner and fed to parser, optionally passing through Token filters in between...
Definition: Token.cs:74
bool MatchSymbol(string symbol, bool ignoreCase)
Tries to match the symbol with the text at current preview position.
static string ErrNewLineExpected
Looks up a localized string similar to NewLine expected..
override void Init(GrammarData grammarData)
newLine, indent, dedent