Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
Sloth - Grammar.cs

Grammar.cs

Caricato da: Totem
Scarica il programma completo

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. namespace Sloth
  7. {
  8.     public class Grammar : List<GrammarRule> { }
  9.  
  10.     public abstract class GrammarRule
  11.     {
  12.         public Int32 ID { get; set; }
  13.  
  14.         public abstract ParseTreeNode Match(IEnumerable<Token> tokens);
  15.     }
  16.  
  17.     public class TokenSequence : GrammarRule
  18.     {
  19.         public List<TokenType> Constraints { get; private set; }
  20.  
  21.         protected TokenSequence()
  22.         {
  23.             this.Constraints = new List<TokenType>();
  24.         }
  25.  
  26.         public static TokenSequence Create(Int32 id, params TokenType[] tokenConstraints)
  27.         {
  28.             if (tokenConstraints.Length == 0)
  29.                 throw new ArgumentException("At least one token is required to create a rule.");
  30.             TokenSequence rule = new TokenSequence();
  31.             rule.ID = id;
  32.             rule.Constraints.AddRange(tokenConstraints);
  33.             return rule;
  34.         }
  35.  
  36.         public Boolean IsValid(IEnumerable<Token> tokens)
  37.         {
  38.             IEnumerator<Token> enumerator = tokens.GetEnumerator();
  39.             Int32 index = 0;
  40.  
  41.             while (enumerator.MoveNext() && (index < this.Constraints.Count))
  42.             {
  43.                 if (enumerator.Current.Type != this.Constraints[index])
  44.                     return false;
  45.                 index++;
  46.             }
  47.  
  48.             return (index == this.Constraints.Count);
  49.         }
  50.  
  51.         public override ParseTreeNode Match(IEnumerable<Token> tokens)
  52.         {
  53.             ParseTreeNode result = new ParseTreeNode();
  54.             result.RuleID = this.ID;
  55.  
  56.             if (!this.IsValid(tokens))
  57.                 return null;
  58.  
  59.             result.Tokens.AddRange(tokens.Take(this.Constraints.Count));
  60.             return result;
  61.         }
  62.     }
  63.  
  64.     public class RuleSelection : GrammarRule
  65.     {
  66.         public List<GrammarRule> Alternatives { get; private set; }
  67.  
  68.         protected RuleSelection()
  69.         {
  70.             this.Alternatives = new List<GrammarRule>();
  71.         }
  72.  
  73.         public static RuleSelection Create(Int32 id, params GrammarRule[] possibleRules)
  74.         {
  75.             if (possibleRules.Length <= 1)
  76.                 throw new ArgumentException("At least two rules are needed to create an alternative.");
  77.             RuleSelection rule = new RuleSelection();
  78.             rule.ID = id;
  79.             rule.Alternatives.AddRange(possibleRules);
  80.             return rule;
  81.         }
  82.  
  83.         public override ParseTreeNode Match(IEnumerable<Token> tokens)
  84.         {
  85.             ParseTreeNode result = new ParseTreeNode();
  86.             result.RuleID = this.ID;
  87.  
  88.             foreach (GrammarRule rule in this.Alternatives)
  89.             {
  90.                 ParseTreeNode match = rule.Match(tokens);
  91.                 if (match != null)
  92.                 {
  93.                     result.Children.Add(match);
  94.                     return result;
  95.                 }
  96.             }
  97.  
  98.             return null;
  99.         }
  100.     }
  101.  
  102.     public class RuleSequence : GrammarRule
  103.     {
  104.         public List<GrammarRule> Constraints { get; private set; }
  105.  
  106.         protected RuleSequence()
  107.         {
  108.             this.Constraints = new List<GrammarRule>();
  109.         }
  110.  
  111.         public static RuleSequence Create(Int32 id, params GrammarRule[] ruleConstraints)
  112.         {
  113.             if (ruleConstraints.Length == 0)
  114.                 throw new ArgumentException("At least one rule is needed to create a rule.");
  115.             RuleSequence rule = new RuleSequence();
  116.             rule.ID = id;
  117.             rule.Constraints.AddRange(ruleConstraints);
  118.             return rule;
  119.         }
  120.  
  121.         public override ParseTreeNode Match(IEnumerable<Token> tokens)
  122.         {
  123.             Int32 matchedTokens = 0;
  124.             ParseTreeNode result = new ParseTreeNode();
  125.  
  126.             result.RuleID = this.ID;
  127.             foreach (GrammarRule rule in this.Constraints)
  128.             {
  129.                 ParseTreeNode match = rule.Match(tokens.Skip(matchedTokens));
  130.                 if (match == null)
  131.                     return null;
  132.                 matchedTokens += match.GetTokensCount();
  133.                 result.Children.Add(match);
  134.             }
  135.  
  136.             return result;
  137.         }
  138.     }
  139. }