/// <summary> /// Output the ANTLR translation of the specified character value node /// </summary> protected override void WriteCharValNode(ITree node) { var isCaseSensitive = IsCaseSensitive(node); var text = GetStringValue(node); var length = text.Length; if (isCaseSensitive && length > 0) { Write("'"); Write(text); Write("'"); } else { if (length > 1) { Write("("); } for (int index = 0; index < length; index++) { if (index > 0) { Write(" "); } var upperCharacter = char.ToUpperInvariant(text[index]); var lowerCharacter = char.ToLowerInvariant(text[index]); if (upperCharacter == lowerCharacter) { Write("'"); Write(AntlrHelper.CharEscape(lowerCharacter)); Write("'"); } else { Write("("); Write("'"); Write(AntlrHelper.CharEscape(upperCharacter)); Write("'"); Write(" | "); Write("'"); Write(AntlrHelper.CharEscape(lowerCharacter)); Write("'"); Write(")"); } } if (length > 1) { Write(")"); } } }
void OutputLiteralRules(IDictionary<char, NamedCharacter> literals, TextWriter writer, INamedCharacterLookup lookup) { var knownValues = literals.Values .Where(x => lookup.IsKnownCharacter(x.Character)) .OrderBy(x => x.Character) .Select(x => x); var unknownValues = literals.Values .Where(x => !(lookup.IsKnownCharacter(x.Character))) .OrderBy(x => x.Character) .Select(x => x); if (literals.Count > 0) { writer.WriteLine(""); writer.WriteLine(""); writer.WriteLine(@"////////////////////////////////////////////////////////////////////////////////////////////"); writer.WriteLine(@"// Lexer rules generated for each distinct character in original grammar"); writer.WriteLine(@"// " + lookup.Description); writer.WriteLine(@"////////////////////////////////////////////////////////////////////////////////////////////"); writer.WriteLine(""); } // output known (named) literals first foreach (var value in knownValues) { writer.Write(value.Name); writer.Write(" : "); writer.Write("'"); var character = value.Character; writer.Write(AntlrHelper.CharEscape(character)); writer.Write("'"); writer.WriteLine(";"); } // output unknown literals foreach (var value in unknownValues) { writer.Write(value.Name); writer.Write(" : "); int number = value.Character; writer.Write(@"'\u"); writer.Write(number.ToString("X4")); writer.Write("'"); writer.WriteLine(";"); } }
Dictionary<char, NamedCharacter> LiteralsCollection; // literals collection /// <summary> /// Translate ABNF grammar to ANTLR grammar /// </summary> /// <param name="input">TextReader which reads the ABNF grammar</param> /// <param name="output">TextWriter which writes the ANTLR grammar</param> public void Translate(TextReader input, TextWriter writer, bool performDirectTranslation) { // force single threaded operation lock (SyncLock) { this.LiteralsCollection = new Dictionary<char, NamedCharacter>(); // open input stream var stream = new Antlr.Runtime.ANTLRReaderStream(input); // create lexer var lexer = new AbnfAstLexer(stream); // get token stream from input stream var tokens = new CommonTokenStream(lexer); // create parser var parser = new AbnfAstParser(tokens); // parse token stream var results = parser.start(); if (parser.RecognitionExceptions.Count > 0 || lexer.RecognitionExceptions.Count > 0) { var message = AntlrHelper.GetErrorMessages(parser.RecognitionExceptions) + AntlrHelper.GetErrorMessages(lexer.RecognitionExceptions) ; throw new TranslationException(message, parser.RecognitionExceptions, lexer.RecognitionExceptions); } // get parse tree var tree = results.Tree; // Use simplified named characters for indirect translation var lookup = new NamedCharacterLookupSimple(); // enable this line to use Unicode named characters for indirect translation // var lookup = new NamedCharacterLookupUnicode(); var ruleStatistics = new RuleStatistics(); var statisticsVisitor = new TreeVisitor_GatherRuleStatistics(ruleStatistics); statisticsVisitor.Visit(tree); // output translated grammar if (performDirectTranslation) { OutputDirectTranslation(writer, tokens, tree, lookup, ruleStatistics); } else { OutputIndirectTranslation(writer, tokens, tree, lookup, ruleStatistics); } } }
public void GatherIncrementalAliases() { foreach (var ruleName in _ruleStatistics.LhsRawRuleNames) { var ruleDetail = _ruleStatistics.RuleDetails[ruleName]; var countOfIncrementalAlternatives = ruleDetail.CountOfIncrementalAlternatives; if (countOfIncrementalAlternatives > 0) { var incrementalAliases = new string[countOfIncrementalAlternatives]; var lastIndex = countOfIncrementalAlternatives - 1; for (int index = 0; index < countOfIncrementalAlternatives; index++) { // determine alias var parserRuleName = AntlrHelper.GetParserRuleName(ruleName); var alias = parserRuleName; int counter = 0; while (AntlrHelper.IsReservedKeyWord(alias) || _ruleStatistics.Aliases.Contains(alias) || _allIncrementalAliases.Contains(alias)) { counter++; alias = parserRuleName + "_" + counter; while (_ruleStatistics.AllParserRuleNames.Contains(alias)) { counter++; alias = parserRuleName + "_" + counter; } } _allIncrementalAliases.Add(alias); if (index == lastIndex) { if (ruleDetail.IsLexerRule) { alias = GetLexerRuleName(alias); } } incrementalAliases[index] = alias; } _mapRuleNameToIncrementalAliases.Add(ruleName, incrementalAliases); _lhsIncrementalRuleCounters[ruleName] = 0; } } }