public bool SyntaxError(lr_parser parser, Symbol curToken) { TypeCobolProgramParser tcpParser = parser as TypeCobolProgramParser; if (tcpParser.IsTrial) { return(true); } List <string> expected = ExpectedSymbols(parser, curToken); string symName = CodeElementTokenizer.CupTokenToString(curToken.sym); Symbol validSymbol = GetParserValidStackSymbol(parser, curToken); string text = validSymbol != null ? (validSymbol.value as CodeElement).Text : ""; string msg = string.Format("extraneous input '{0}' expecting {{{1}}}", text, string.Join(", ", expected)); System.Diagnostics.Debug.WriteLine(msg); CupParserDiagnostic diagnostic = new CupParserDiagnostic(msg, validSymbol, null); AddDiagnostic(diagnostic); //Try to add the last encountered statement in the stack if it is not already entered. StackList <Symbol> stack = tcpParser.getParserStack(); foreach (var symbol in stack) { if (symbol.value is StatementElement) { lr_parser stmtParser = CloneParser(parser, TypeCobolProgramSymbols.StatementEntryPoint, symbol.value as CodeElement, true); stmtParser.parse(); break; } } return(true); }
public static void CupParseProgramOrClass(TextSourceInfo textSourceInfo, ISearchableReadOnlyList <CodeElementsLine> codeElementsLines, TypeCobolOptions compilerOptions, SymbolTable customSymbols, PerfStatsForParserInvocation perfStatsForParserInvocation, out SourceFile root, out List <Diagnostic> diagnostics, out Dictionary <CodeElement, Node> nodeCodeElementLinkers) { PrepareCupParser(); #if DEBUG_ANTRL_CUP_TIME var t1 = DateTime.UtcNow; #endif CodeElementTokenizer scanner = new CodeElementTokenizer(codeElementsLines); CupParser.TypeCobolProgramParser parser = new CupParser.TypeCobolProgramParser(scanner); CupParserTypeCobolProgramDiagnosticErrorReporter diagReporter = new CupParserTypeCobolProgramDiagnosticErrorReporter(); parser.ErrorReporter = diagReporter; ProgramClassBuilder builder = new ProgramClassBuilder(); parser.Builder = builder; ParserDiagnostic programClassBuilderError = null; builder.SyntaxTree = new SyntaxTree <CodeElement>(); //Initializie SyntaxTree for the current source file builder.CustomSymbols = customSymbols; builder.Dispatcher = new NodeDispatcher <CodeElement>(); builder.Dispatcher.CreateListeners(); // Try to parse a Cobol program or class, with cup w are also building the The Syntax Tree Node perfStatsForParserInvocation.OnStartParsing(); try { TUVienna.CS_CUP.Runtime.Symbol symbol = parser.parse(); } catch (Exception ex) { var code = Diagnostics.MessageCode.ImplementationError; programClassBuilderError = new ParserDiagnostic(ex.ToString(), null, null, code, ex); } perfStatsForParserInvocation.OnStopParsing(0, 0); #if DEBUG_ANTRL_CUP_TIME var t2 = DateTime.UtcNow; var t = t2 - t1; System.Diagnostics.Debug.WriteLine("Time[" + textSourceInfo.Name + "];" + t.Milliseconds); #endif root = builder.SyntaxTree.Root; //Set output root node perfStatsForParserInvocation.OnStartTreeBuilding(); //Create link between data definition an Types, will be stored in SymbolTable root.AcceptASTVisitor(new TypeCobolLinker()); //Stop measuring tree building performance perfStatsForParserInvocation.OnStopTreeBuilding(); // Register compiler results diagnostics = diagReporter.Diagnostics ?? new List <Diagnostic>(); nodeCodeElementLinkers = builder.NodeCodeElementLinkers; if (programClassBuilderError != null) { diagnostics.Add(programClassBuilderError); } }
/// <summary> /// Create a new parser using a clone. /// </summary> /// <param name="parser">The parser to be cloned</param> /// <param name="start">The start entry point to use</param> /// <param name="firstSymbol">The First Symbol</param> /// <param name="trial">If we are creating atrial parser, fals eo therwise</param> /// <returns>The new parser</returns> public lr_parser CloneParser(lr_parser parser, int start, CodeElement firstSymbol, bool trial) { TypeCobolProgramParser tcpParser = parser as TypeCobolProgramParser; ProgramClassBuilder builder = tcpParser.Builder as ProgramClassBuilder; var errorReporter = tcpParser.ErrorReporter; var tokenizer = parser.getScanner() as CodeElementTokenizer; CodeElementTokenizer newTokenizer = new CodeElementTokenizer(start, firstSymbol); TypeCobolProgramParser newParser = new TypeCobolProgramParser(newTokenizer); newParser.Builder = builder; newParser.ErrorReporter = errorReporter; newParser.IsTrial = trial; return(newParser); }
/// <summary> /// Get the array of expected symbols on the given symbol current parser state. /// </summary> /// <param name="parser">The parser</param> /// <param name="curToken">The Symbol</param> /// <returns>The array of expected symbols</returns> private static List <string> ExpectedSymbols(lr_parser parser, Symbol curToken) { var actionTab = parser.action_table(); int state = ((TypeCobolProgramParser)parser).getParserState(); short[] row = actionTab[state]; List <string> expected = new List <string>(); for (int probe = 0; probe < row.Length; probe++) { int tag = row[probe++]; if (tag != -1 && tag != parser.error_sym()) {//symbol tag different of the default symbol. string name = CodeElementTokenizer.CupTokenToString(tag); if (name != null) { expected.Add(name); } } } return(expected); }