PageRenderTime 54ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/Dependencies/boo/src/Boo.Lang.Parser/antlr/antlr/CharScanner.cs

https://github.com/w4x/boolangstudio
C# | 717 lines | 543 code | 100 blank | 74 comment | 52 complexity | f2365456cd9531cfb6898924308c69da MD5 | raw file
Possible License(s): GPL-2.0
  1. using System;
  2. using Stream = System.IO.Stream;
  3. using TextReader = System.IO.TextReader;
  4. using StringBuilder = System.Text.StringBuilder;
  5. using Hashtable = System.Collections.Hashtable;
  6. using Assembly = System.Reflection.Assembly;
  7. using EventHandlerList = System.ComponentModel.EventHandlerList;
  8. using BitSet = antlr.collections.impl.BitSet;
  9. using antlr.debug;
  10. namespace antlr
  11. {
  12. /*ANTLR Translator Generator
  13. * Project led by Terence Parr at http://www.jGuru.com
  14. * Software rights: http://www.antlr.org/license.html
  15. *
  16. * $Id:$
  17. */
  18. //
  19. // ANTLR C# Code Generator by Micheal Jordan
  20. // Kunle Odutola : kunle UNDERSCORE odutola AT hotmail DOT com
  21. // Anthony Oguntimehin
  22. //
  23. // With many thanks to Eric V. Smith from the ANTLR list.
  24. //
  25. public abstract class CharScanner : TokenStream, ICharScannerDebugSubject
  26. {
  27. internal const char NO_CHAR = (char) (0);
  28. public static readonly char EOF_CHAR = Char.MaxValue;
  29. // Used to store event delegates
  30. private EventHandlerList events_ = new EventHandlerList();
  31. protected internal EventHandlerList Events
  32. {
  33. get { return events_; }
  34. }
  35. // The unique keys for each event that CharScanner [objects] can generate
  36. internal static readonly object EnterRuleEventKey = new object();
  37. internal static readonly object ExitRuleEventKey = new object();
  38. internal static readonly object DoneEventKey = new object();
  39. internal static readonly object ReportErrorEventKey = new object();
  40. internal static readonly object ReportWarningEventKey = new object();
  41. internal static readonly object NewLineEventKey = new object();
  42. internal static readonly object MatchEventKey = new object();
  43. internal static readonly object MatchNotEventKey = new object();
  44. internal static readonly object MisMatchEventKey = new object();
  45. internal static readonly object MisMatchNotEventKey = new object();
  46. internal static readonly object ConsumeEventKey = new object();
  47. internal static readonly object LAEventKey = new object();
  48. internal static readonly object SemPredEvaluatedEventKey = new object();
  49. internal static readonly object SynPredStartedEventKey = new object();
  50. internal static readonly object SynPredFailedEventKey = new object();
  51. internal static readonly object SynPredSucceededEventKey = new object();
  52. protected internal StringBuilder text; // text of current token
  53. protected bool saveConsumedInput = true; // does consume() save characters?
  54. /// <summary>Used for creating Token instances.</summary>
  55. protected TokenCreator tokenCreator;
  56. /// <summary>Used for caching lookahead characters.</summary>
  57. protected char cached_LA1;
  58. protected char cached_LA2;
  59. protected bool caseSensitive = true;
  60. protected bool caseSensitiveLiterals = true;
  61. protected Hashtable literals; // set by subclass
  62. /*Tab chars are handled by tab() according to this value; override
  63. * method to do anything weird with tabs.
  64. */
  65. protected internal int tabsize = 8;
  66. protected internal IToken returnToken_ = null; // used to return tokens w/o using return val.
  67. protected internal LexerSharedInputState inputState;
  68. /*Used during filter mode to indicate that path is desired.
  69. * A subsequent scan error will report an error as usual if
  70. * acceptPath=true;
  71. */
  72. protected internal bool commitToPath = false;
  73. /*Used to keep track of indentdepth for traceIn/Out */
  74. protected internal int traceDepth = 0;
  75. public CharScanner()
  76. {
  77. text = new StringBuilder();
  78. setTokenCreator(new CommonToken.CommonTokenCreator());
  79. }
  80. public CharScanner(InputBuffer cb) : this()
  81. {
  82. inputState = new LexerSharedInputState(cb);
  83. cached_LA2 = inputState.input.LA(2);
  84. cached_LA1 = inputState.input.LA(1);
  85. }
  86. public CharScanner(LexerSharedInputState sharedState) : this()
  87. {
  88. inputState = sharedState;
  89. if (inputState != null)
  90. {
  91. cached_LA2 = inputState.input.LA(2);
  92. cached_LA1 = inputState.input.LA(1);
  93. }
  94. }
  95. public event TraceEventHandler EnterRule
  96. {
  97. add { Events.AddHandler(EnterRuleEventKey, value); }
  98. remove { Events.RemoveHandler(EnterRuleEventKey, value); }
  99. }
  100. public event TraceEventHandler ExitRule
  101. {
  102. add { Events.AddHandler(ExitRuleEventKey, value); }
  103. remove { Events.RemoveHandler(ExitRuleEventKey, value); }
  104. }
  105. public event TraceEventHandler Done
  106. {
  107. add { Events.AddHandler(DoneEventKey, value); }
  108. remove { Events.RemoveHandler(DoneEventKey, value); }
  109. }
  110. public event MessageEventHandler ErrorReported
  111. {
  112. add { Events.AddHandler(ReportErrorEventKey, value); }
  113. remove { Events.RemoveHandler(ReportErrorEventKey, value); }
  114. }
  115. public event MessageEventHandler WarningReported
  116. {
  117. add { Events.AddHandler(ReportWarningEventKey, value); }
  118. remove { Events.RemoveHandler(ReportWarningEventKey, value); }
  119. }
  120. public event NewLineEventHandler HitNewLine
  121. {
  122. add { Events.AddHandler(NewLineEventKey, value); }
  123. remove { Events.RemoveHandler(NewLineEventKey, value); }
  124. }
  125. public event MatchEventHandler MatchedChar
  126. {
  127. add { Events.AddHandler(MatchEventKey, value); }
  128. remove { Events.RemoveHandler(MatchEventKey, value); }
  129. }
  130. public event MatchEventHandler MatchedNotChar
  131. {
  132. add { Events.AddHandler(MatchNotEventKey, value); }
  133. remove { Events.RemoveHandler(MatchNotEventKey, value); }
  134. }
  135. public event MatchEventHandler MisMatchedChar
  136. {
  137. add { Events.AddHandler(MisMatchEventKey, value); }
  138. remove { Events.RemoveHandler(MisMatchEventKey, value); }
  139. }
  140. public event MatchEventHandler MisMatchedNotChar
  141. {
  142. add { Events.AddHandler(MisMatchNotEventKey, value); }
  143. remove { Events.RemoveHandler(MisMatchNotEventKey, value); }
  144. }
  145. public event TokenEventHandler ConsumedChar
  146. {
  147. add { Events.AddHandler(ConsumeEventKey, value); }
  148. remove { Events.RemoveHandler(ConsumeEventKey, value); }
  149. }
  150. public event TokenEventHandler CharLA
  151. {
  152. add { Events.AddHandler(LAEventKey, value); }
  153. remove { Events.RemoveHandler(LAEventKey, value); }
  154. }
  155. public event SemanticPredicateEventHandler SemPredEvaluated
  156. {
  157. add { Events.AddHandler(SemPredEvaluatedEventKey, value); }
  158. remove { Events.RemoveHandler(SemPredEvaluatedEventKey, value); }
  159. }
  160. public event SyntacticPredicateEventHandler SynPredStarted
  161. {
  162. add { Events.AddHandler(SynPredStartedEventKey, value); }
  163. remove { Events.RemoveHandler(SynPredStartedEventKey, value); }
  164. }
  165. public event SyntacticPredicateEventHandler SynPredFailed
  166. {
  167. add { Events.AddHandler(SynPredFailedEventKey, value); }
  168. remove { Events.RemoveHandler(SynPredFailedEventKey, value); }
  169. }
  170. public event SyntacticPredicateEventHandler SynPredSucceeded
  171. {
  172. add { Events.AddHandler(SynPredSucceededEventKey, value); }
  173. remove { Events.RemoveHandler(SynPredSucceededEventKey, value); }
  174. }
  175. // From interface TokenStream
  176. public virtual IToken nextToken() { return null; }
  177. public virtual void append(char c)
  178. {
  179. if (saveConsumedInput)
  180. {
  181. text.Append(c);
  182. }
  183. }
  184. public virtual void append(string s)
  185. {
  186. if (saveConsumedInput)
  187. {
  188. text.Append(s);
  189. }
  190. }
  191. public virtual void commit()
  192. {
  193. inputState.input.commit();
  194. }
  195. public virtual void consume()
  196. {
  197. if (inputState.guessing == 0)
  198. {
  199. if (caseSensitive)
  200. {
  201. append(cached_LA1);
  202. }
  203. else
  204. {
  205. // use input.LA(), not LA(), to get original case
  206. // CharScanner.LA() would toLower it.
  207. append(inputState.input.LA(1));
  208. }
  209. if (cached_LA1 == '\t')
  210. {
  211. tab();
  212. }
  213. else
  214. {
  215. inputState.column++;
  216. }
  217. }
  218. if (caseSensitive)
  219. {
  220. cached_LA1 = inputState.input.consume();
  221. cached_LA2 = inputState.input.LA(2);
  222. }
  223. else
  224. {
  225. cached_LA1 = toLower(inputState.input.consume());
  226. cached_LA2 = toLower(inputState.input.LA(2));
  227. }
  228. }
  229. /*Consume chars until one matches the given char */
  230. public virtual void consumeUntil(int c)
  231. {
  232. while ((EOF_CHAR != cached_LA1) && (c != cached_LA1))
  233. {
  234. consume();
  235. }
  236. }
  237. /*Consume chars until one matches the given set */
  238. public virtual void consumeUntil(BitSet bset)
  239. {
  240. while (cached_LA1 != EOF_CHAR && !bset.member(cached_LA1))
  241. {
  242. consume();
  243. }
  244. }
  245. public virtual bool getCaseSensitive()
  246. {
  247. return caseSensitive;
  248. }
  249. public bool getCaseSensitiveLiterals()
  250. {
  251. return caseSensitiveLiterals;
  252. }
  253. public virtual int getColumn()
  254. {
  255. return inputState.column;
  256. }
  257. public virtual void setColumn(int c)
  258. {
  259. inputState.column = c;
  260. }
  261. public virtual bool getCommitToPath()
  262. {
  263. return commitToPath;
  264. }
  265. public virtual string getFilename()
  266. {
  267. return inputState.filename;
  268. }
  269. public virtual InputBuffer getInputBuffer()
  270. {
  271. return inputState.input;
  272. }
  273. public virtual LexerSharedInputState getInputState()
  274. {
  275. return inputState;
  276. }
  277. public virtual void setInputState(LexerSharedInputState state)
  278. {
  279. inputState = state;
  280. }
  281. public virtual int getLine()
  282. {
  283. return inputState.line;
  284. }
  285. /*return a copy of the current text buffer */
  286. public virtual string getText()
  287. {
  288. return text.ToString();
  289. }
  290. public virtual IToken getTokenObject()
  291. {
  292. return returnToken_;
  293. }
  294. public virtual char LA(int i)
  295. {
  296. if (i == 1)
  297. {
  298. return cached_LA1;
  299. }
  300. if (i == 2)
  301. {
  302. return cached_LA2;
  303. }
  304. if (caseSensitive)
  305. {
  306. return inputState.input.LA(i);
  307. }
  308. else
  309. {
  310. return toLower(inputState.input.LA(i));
  311. }
  312. }
  313. protected internal virtual IToken makeToken(int t)
  314. {
  315. IToken newToken = null;
  316. bool typeCreated;
  317. try
  318. {
  319. newToken = tokenCreator.Create();
  320. if (newToken != null)
  321. {
  322. newToken.Type = t;
  323. newToken.setColumn(inputState.tokenStartColumn);
  324. newToken.setLine(inputState.tokenStartLine);
  325. // tracking real start line now: newToken.setLine(inputState.line);
  326. newToken.setFilename(inputState.filename);
  327. }
  328. typeCreated = true;
  329. }
  330. catch
  331. {
  332. typeCreated = false;
  333. }
  334. if (!typeCreated)
  335. {
  336. panic("Can't create Token object '" + tokenCreator.TokenTypeName + "'");
  337. newToken = Token.badToken;
  338. }
  339. return newToken;
  340. }
  341. public virtual int mark()
  342. {
  343. return inputState.input.mark();
  344. }
  345. public virtual void match(char c)
  346. {
  347. match((int) c);
  348. }
  349. public virtual void match(int c)
  350. {
  351. if (cached_LA1 != c)
  352. {
  353. throw new MismatchedCharException(cached_LA1, Convert.ToChar(c), false, this);
  354. }
  355. consume();
  356. }
  357. public virtual void match(BitSet b)
  358. {
  359. if (!b.member(cached_LA1))
  360. {
  361. throw new MismatchedCharException(cached_LA1, b, false, this);
  362. }
  363. consume();
  364. }
  365. public virtual void match(string s)
  366. {
  367. int len = s.Length;
  368. for (int i = 0; i < len; i++)
  369. {
  370. if (cached_LA1 != s[i])
  371. {
  372. throw new MismatchedCharException(cached_LA1, s[i], false, this);
  373. }
  374. consume();
  375. }
  376. }
  377. public virtual void matchNot(char c)
  378. {
  379. matchNot((int) c);
  380. }
  381. public virtual void matchNot(int c)
  382. {
  383. if (cached_LA1 == c)
  384. {
  385. throw new MismatchedCharException(cached_LA1, Convert.ToChar(c), true, this);
  386. }
  387. consume();
  388. }
  389. public virtual void matchRange(int c1, int c2)
  390. {
  391. if (cached_LA1 < c1 || cached_LA1 > c2)
  392. {
  393. throw new MismatchedCharException(cached_LA1, Convert.ToChar(c1), Convert.ToChar(c2), false, this);
  394. }
  395. consume();
  396. }
  397. public virtual void matchRange(char c1, char c2)
  398. {
  399. matchRange((int) c1, (int) c2);
  400. }
  401. public virtual void newline()
  402. {
  403. inputState.line++;
  404. inputState.column = 1;
  405. }
  406. /*advance the current column number by an appropriate amount
  407. * according to tab size. This method is called from consume().
  408. */
  409. public virtual void tab()
  410. {
  411. int c = getColumn();
  412. int nc = (((c - 1) / tabsize) + 1) * tabsize + 1; // calculate tab stop
  413. setColumn(nc);
  414. }
  415. public virtual void setTabSize(int size)
  416. {
  417. tabsize = size;
  418. }
  419. public virtual int getTabSize()
  420. {
  421. return tabsize;
  422. }
  423. public virtual void panic()
  424. {
  425. //Console.Error.WriteLine("CharScanner: panic");
  426. //Environment.Exit(1);
  427. panic("");
  428. }
  429. /// <summary>
  430. /// This method is executed by ANTLR internally when it detected an illegal
  431. /// state that cannot be recovered from.
  432. /// The previous implementation of this method called <see cref="Environment.Exit"/>
  433. /// and writes directly to <see cref="Console.Error"/>, which is usually not
  434. /// appropriate when a translator is embedded into a larger application.
  435. /// </summary>
  436. /// <param name="s">Error message.</param>
  437. public virtual void panic(string s)
  438. {
  439. //Console.Error.WriteLine("CharScanner; panic: " + s);
  440. //Environment.Exit(1);
  441. throw new ANTLRPanicException("CharScanner::panic: " + s);
  442. }
  443. /*Parser error-reporting function can be overridden in subclass */
  444. public virtual void reportError(RecognitionException ex)
  445. {
  446. Console.Error.WriteLine(ex);
  447. }
  448. /*Parser error-reporting function can be overridden in subclass */
  449. public virtual void reportError(string s)
  450. {
  451. if (getFilename() == null)
  452. {
  453. Console.Error.WriteLine("error: " + s);
  454. }
  455. else
  456. {
  457. Console.Error.WriteLine(getFilename() + ": error: " + s);
  458. }
  459. }
  460. /*Parser warning-reporting function can be overridden in subclass */
  461. public virtual void reportWarning(string s)
  462. {
  463. if (getFilename() == null)
  464. {
  465. Console.Error.WriteLine("warning: " + s);
  466. }
  467. else
  468. {
  469. Console.Error.WriteLine(getFilename() + ": warning: " + s);
  470. }
  471. }
  472. public virtual void refresh()
  473. {
  474. if (caseSensitive)
  475. {
  476. cached_LA2 = inputState.input.LA(2);
  477. cached_LA1 = inputState.input.LA(1);
  478. }
  479. else
  480. {
  481. cached_LA2 = toLower(inputState.input.LA(2));
  482. cached_LA1 = toLower(inputState.input.LA(1));
  483. }
  484. }
  485. public virtual void resetState(InputBuffer ib)
  486. {
  487. text.Length = 0;
  488. traceDepth = 0;
  489. inputState.resetInput(ib);
  490. refresh();
  491. }
  492. public void resetState(Stream s)
  493. {
  494. resetState(new ByteBuffer(s));
  495. }
  496. public void resetState(TextReader tr)
  497. {
  498. resetState(new CharBuffer(tr));
  499. }
  500. public virtual void resetText()
  501. {
  502. text.Length = 0;
  503. inputState.tokenStartColumn = inputState.column;
  504. inputState.tokenStartLine = inputState.line;
  505. }
  506. public virtual void rewind(int pos)
  507. {
  508. inputState.input.rewind(pos);
  509. //setColumn(inputState.tokenStartColumn);
  510. cached_LA2 = inputState.input.LA(2);
  511. cached_LA1 = inputState.input.LA(1);
  512. }
  513. public virtual void setCaseSensitive(bool t)
  514. {
  515. caseSensitive = t;
  516. if (caseSensitive)
  517. {
  518. cached_LA2 = inputState.input.LA(2);
  519. cached_LA1 = inputState.input.LA(1);
  520. }
  521. else
  522. {
  523. cached_LA2 = toLower(inputState.input.LA(2));
  524. cached_LA1 = toLower(inputState.input.LA(1));
  525. }
  526. }
  527. public virtual void setCommitToPath(bool commit)
  528. {
  529. commitToPath = commit;
  530. }
  531. public virtual void setFilename(string f)
  532. {
  533. inputState.filename = f;
  534. }
  535. public virtual void setLine(int line)
  536. {
  537. inputState.line = line;
  538. }
  539. public virtual void setText(string s)
  540. {
  541. resetText();
  542. text.Append(s);
  543. }
  544. public virtual void setTokenCreator(TokenCreator tokenCreator)
  545. {
  546. this.tokenCreator = tokenCreator;
  547. }
  548. // Test the token text against the literals table
  549. // Override this method to perform a different literals test
  550. public virtual int testLiteralsTable(int ttype)
  551. {
  552. string tokenText = text.ToString();
  553. if ( (tokenText == null) || (tokenText == string.Empty) )
  554. return ttype;
  555. else
  556. {
  557. object typeAsObject = literals[tokenText];
  558. return (typeAsObject == null) ? ttype : ((int) typeAsObject);
  559. }
  560. }
  561. /*Test the text passed in against the literals table
  562. * Override this method to perform a different literals test
  563. * This is used primarily when you want to test a portion of
  564. * a token.
  565. */
  566. public virtual int testLiteralsTable(string someText, int ttype)
  567. {
  568. if ( (someText == null) || (someText == string.Empty) )
  569. return ttype;
  570. else
  571. {
  572. object typeAsObject = literals[someText];
  573. return (typeAsObject == null) ? ttype : ((int) typeAsObject);
  574. }
  575. }
  576. // Override this method to get more specific case handling
  577. public virtual char toLower(int c)
  578. {
  579. return Char.ToLower(Convert.ToChar(c), System.Globalization.CultureInfo.InvariantCulture);
  580. }
  581. public virtual void traceIndent()
  582. {
  583. for (int i = 0; i < traceDepth; i++)
  584. Console.Out.Write(" ");
  585. }
  586. public virtual void traceIn(string rname)
  587. {
  588. traceDepth += 1;
  589. traceIndent();
  590. Console.Out.WriteLine("> lexer " + rname + "; c==" + LA(1));
  591. }
  592. public virtual void traceOut(string rname)
  593. {
  594. traceIndent();
  595. Console.Out.WriteLine("< lexer " + rname + "; c==" + LA(1));
  596. traceDepth -= 1;
  597. }
  598. /*This method is called by YourLexer.nextToken() when the lexer has
  599. * hit EOF condition. EOF is NOT a character.
  600. * This method is not called if EOF is reached during
  601. * syntactic predicate evaluation or during evaluation
  602. * of normal lexical rules, which presumably would be
  603. * an IOException. This traps the "normal" EOF condition.
  604. *
  605. * uponEOF() is called after the complete evaluation of
  606. * the previous token and only if your parser asks
  607. * for another token beyond that last non-EOF token.
  608. *
  609. * You might want to throw token or char stream exceptions
  610. * like: "Heh, premature eof" or a retry stream exception
  611. * ("I found the end of this file, go back to referencing file").
  612. */
  613. public virtual void uponEOF()
  614. {
  615. }
  616. }
  617. }