public LanguageMatcher Convert(string name, string ebnfText) { _ebnfText = ebnfText; _patternMatcherMap = new Dictionary <string, PatternMatcher>(StringComparer.Ordinal); _fragmentMatcherMap = new Dictionary <string, ValueTuple <FragmentMatcher, FragmentMatchData> >(StringComparer.Ordinal); _languageMatcher = new LanguageMatcher() { Name = name, Patterns = new List <PatternMatcher>(), Fragments = new List <FragmentMatcher>() }; MatcherResult matcherResult = _ebnfMatchEngine.Match(ebnfText); if (!matcherResult.Success) { throw new LanaguageSyntaxException($"Unsupported EBNF syntax", matcherResult.FailureIndex.Value); } foreach (FragmentMatcher defaultFragment in DefaultFragments) { AddFragmentMatcherAndParts(defaultFragment); } AddRules((FragmentMatchData)matcherResult.MatchData); _languageMatcher.IndexingMode = IndexingMode.Lazy; _languageMatcher.StartingFragment = _languageMatcher.Fragments.FirstOrDefault(); return(_languageMatcher); }
public static LanguageMatcherDefinition Convert(LanguageMatcher languageMatcher) { HashSet <string> convertedPatterns = new HashSet <string>(); List <PatternMatcherDefinition> patterns = new List <PatternMatcherDefinition>(languageMatcher.Patterns.Select(ConvertPattern)); List <FragmentMatcherDefinition> fragments = new List <FragmentMatcherDefinition>(languageMatcher.Fragments.Select(ConvertFragment)); LanguageMatcherDefinition matcherDefinition = new LanguageMatcherDefinition { Name = languageMatcher.Name, LogMatches = languageMatcher.LogMatches, IndexingMode = languageMatcher.IndexingMode, StartingFragment = languageMatcher.StartingFragment.Name, Patterns = patterns, Fragments = fragments }; return(matcherDefinition); PatternMatcherDefinition ConvertPattern(PatternMatcher patternMatcher) { convertedPatterns.Add(patternMatcher.Name); return(new PatternMatcherDefinition { IsNoise = patternMatcher.IsNoise, Mergable = patternMatcher.Mergable, Name = patternMatcher.Name, Pattern = patternMatcher is GroupPatternMatcher groupPatternMatcher?groupPatternMatcher.ToString(true) : patternMatcher.ToString() }); };
public void DefinitionConverter_Convert() { string definition = File.ReadAllText("Interop/Json/Files/TestDefinition.json"); LanguageMatcherDefinition languageMatcherDefinition = JsonConvert.DeserializeObject <LanguageMatcherDefinition>(definition); LanguageMatcher languageMatcher = DefinitionConverter.Convert(languageMatcherDefinition); LanguageMatcherDefinition newLanguageDefinition = DefinitionConverter.Convert(languageMatcher); Assert.Equal(languageMatcherDefinition, newLanguageDefinition, new LanguageMatcherDefinitionComparer()); }
private static void Main(string[] args) { Dictionary <string, List <string> > parsedArgs = GetCommandLineParameters(string.Join(" ", args)); if (parsedArgs.Count == 0) { PrintHelpText(); return; } string definitionFile = GetDefinitionFile(parsedArgs); string outputFolder = GetOutputFolder(parsedArgs); OutputType outputType = GetOutputType(parsedArgs); string definitionFileText; if (!string.IsNullOrEmpty(definitionFile)) { definitionFileText = File.ReadAllText(definitionFile); } else { definitionFileText = Console.In.ReadToEnd(); if (string.IsNullOrWhiteSpace(definitionFileText)) { throw new ArgumentException("A language defintion file is required."); } } try { LanguageMatcherDefinition languageMatcherModel = JsonConvert.DeserializeObject <LanguageMatcherDefinition>(definitionFileText); LanguageMatcher languageMatcher = DefinitionConverter.Convert(languageMatcherModel); MatcherClassGenerator generator = new MatcherClassGenerator(languageMatcher); if (outputType == OutputType.Assembly) { generator.OutputAssembly(outputFolder); } else if (outputFolder == "stdout") { Console.WriteLine(generator.GetClass()); } else { generator.OutputClass(outputFolder); } } catch (Exception) { throw new ArgumentException("A matcher could not be generated using the given definition file."); } }
private static Assembly GetAssembly(Language language, LanguageMatcher matcher) { lock (_assemblyMap) { if (!_assemblyMap.TryGetValue(language.ToString(), out Assembly assembly)) { MatcherClassGenerator generator = new MatcherClassGenerator(matcher); assembly = generator.GetAssembly(); _assemblyMap[language.ToString()] = assembly; } return(assembly); } }
public static LanguageMatcher GetJsonMatcher() { lock (_matcherMap) { if (!_matcherMap.TryGetValue(Language.Json.ToString(), out LanguageMatcher languageMatcher)) { PatternMatcher stringLiteralPattern = PatternReader.LazyParse(id: 1, name: "String", pattern: "\"((\"!.)|\\\\.)+\""); PatternMatcher nullPattern = PatternReader.LazyParse(id: 2, name: "Null", pattern: "`~null"); PatternMatcher booleanPattern = PatternReader.LazyParse(id: 3, name: "Boolean", pattern: "`~true|false"); PatternMatcher numberPattern = PatternReader.LazyParse(id: 4, name: "Number", pattern: "~-?(\\d*\\.\\d+(e(-|\\+)?\\d+)?|\\d+)"); PatternMatcher colonSeparatorPattern = PatternReader.LazyParse(id: 5, name: "ColonSeparator", pattern: "\\s*:\\s*"); PatternMatcher commaSeparatorPattern = PatternReader.LazyParse(id: 6, name: "CommaSeparator", pattern: "\\s*,\\s*"); PatternMatcher openBracePattern = PatternReader.LazyParse(id: 7, name: "OpenBrace", pattern: "\\{"); PatternMatcher closeBracePattern = PatternReader.LazyParse(id: 8, name: "CloseBrace", pattern: "\\}"); PatternMatcher openBracketPattern = PatternReader.LazyParse(id: 9, name: "OpenBracket", pattern: "\\["); PatternMatcher closeBracketPattern = PatternReader.LazyParse(id: 10, name: "CloseBracket", pattern: "\\]"); PatternMatcher whitespacePattern = PatternReader.LazyParse(id: 11, name: "Whitespace", pattern: "\\s+"); FragmentMatcher keyValueFragment = new FragmentMatcher(id: 5, name: "KeyValue", parts: new IMatcher[2] { stringLiteralPattern, null }, partsMatchMode: MatchMode.Ordered, partsDelimiter: colonSeparatorPattern); FragmentMatcher objectFragment = new FragmentMatcher(id: 4, name: "Object", parts: new IMatcher[] { keyValueFragment }, partsMatchMode: MatchMode.Multiple, partsDelimiter: commaSeparatorPattern, minMatchedParts: 3, partsPadding: whitespacePattern, start: openBracePattern, end: closeBracePattern); FragmentMatcher arrayFragment = new FragmentMatcher(id: 3, name: "Array", parts: new IMatcher[1], partsMatchMode: MatchMode.Multiple, partsDelimiter: commaSeparatorPattern, minMatchedParts: 0, partsPadding: whitespacePattern, start: openBracketPattern, end: closeBracketPattern); FragmentMatcher itemFragment = new FragmentMatcher(id: 2, name: "Item", parts: new IMatcher[] { objectFragment, arrayFragment, booleanPattern, nullPattern, stringLiteralPattern, numberPattern }, partsMatchMode: MatchMode.One, fallThrough: true); arrayFragment.Parts[0] = itemFragment; keyValueFragment.Parts[1] = itemFragment; FragmentMatcher jsonFragment = new FragmentMatcher(id: 1, name: "Json", parts: new IMatcher[] { objectFragment, arrayFragment }, partsMatchMode: MatchMode.One, partsPadding: whitespacePattern); languageMatcher = new LanguageMatcher { Name = Language.Json.ToString(), IndexingMode = IndexingMode.Lazy, StartingFragment = jsonFragment, Fragments = new List <FragmentMatcher> { keyValueFragment, objectFragment, arrayFragment, itemFragment, jsonFragment }, Patterns = new List <PatternMatcher> { stringLiteralPattern, nullPattern, booleanPattern, numberPattern, colonSeparatorPattern, commaSeparatorPattern, openBracePattern, closeBracePattern, openBracketPattern, closeBracketPattern, whitespacePattern } }; _matcherMap[Language.Json.ToString()] = languageMatcher; } return(languageMatcher); } }
public void ConversionTest(string grammarFileName, int numRules) { const string fileDirectory = "Interop/Ebnf/Files"; string ebnf = File.ReadAllText(Path.Combine(fileDirectory, "Grammars", grammarFileName)); EbnfConverter ebnfConverter = new EbnfConverter(); LanguageMatcher languageMatcher = ebnfConverter.Convert("ebnf", ebnf); Assert.Equal(numRules, languageMatcher.Fragments.Count(f => !f.FallThrough)); string parsable = File.ReadAllText(Path.Combine(fileDirectory, "Parsables", "abc.txt")); Stopwatch watch = new Stopwatch(); watch.Start(); LanguageMatchEngine languageMatchEngine = LanguageMatchEngine.Build(languageMatcher); MatcherResult result = languageMatchEngine.Match(parsable); watch.Stop(); Assert.True(result.Success); }
private string Generate() { return(LanguageMatcher.Generate(this).Replace("<<Generated Methods>>", _codeBuilder.ToString())); }
private MatcherEngineGenerator(LanguageMatcher languageMatcher) { LanguageMatcher = languageMatcher; IndexingMode = languageMatcher.IndexingMode; }
public static string GenerateEngine(LanguageMatcher languageMatcher) { MatcherEngineGenerator generator = new MatcherEngineGenerator(languageMatcher); return(generator.Generate()); }
public EagerIndexLanguageMatchEngine(LanguageMatcher languageMatcher) : base(languageMatcher) { _hasCheckFlags = false; }
public MatcherClassGenerator(LanguageMatcher languageMatcher) { _languageMatcher = languageMatcher; _className = $"{languageMatcher.Name}MatchEngine"; _assemblyName = $"Synfron.Staxe.Matcher.{languageMatcher.Name}"; }