From 8e69b1496c19a2036db01c8c31687c856575af4a Mon Sep 17 00:00:00 2001 From: mmazas Date: Tue, 11 Feb 2025 17:39:02 +0100 Subject: [PATCH] Fixes, structure, readme. Signed-off-by: mmazas --- .github/workflows/main.yml | 4 +- LICENSE | 4 +- README.md | 5 + bugs/bug001/files/clc1.exp_err | 877 +++--- bugs/bug001/files/clc2.exp_err | 221 +- bugs/bug001/pom.xml | 4 +- .../src/main/javacc/ComplexLineComment.jj | 2 + bugs/bug002/files/bug.exp_err | 76 +- bugs/bug002/files/bug.exp_out | Bin 443 -> 462 bytes bugs/bug002/pom.xml | 4 +- bugs/bug002/src/main/cpp/Main.cpp | 1 + bugs/bug002/src/main/javacc/Bug002.jj | 21 +- bugs/pom.xml | 4 +- bugs/settings.xml | 4 +- build.xml | 4 +- examples/CORBA-IDL/pom.xml | 4 +- examples/Interpreter/AST/pom.xml | 28 +- examples/Interpreter/AST/src/.gitignore | 1 + .../src/main/{cpp => cpp.old}/ASTAddNode.cc | 0 .../src/main/{cpp => cpp.old}/ASTAddNode.h | 0 .../src/main/{cpp => cpp.old}/ASTAndNode.cc | 0 .../src/main/{cpp => cpp.old}/ASTAndNode.h | 0 .../main/{cpp => cpp.old}/ASTAssignment.cc | 0 .../src/main/{cpp => cpp.old}/ASTAssignment.h | 0 .../{cpp => cpp.old}/ASTBitwiseAndNode.cc | 0 .../main/{cpp => cpp.old}/ASTBitwiseAndNode.h | 0 .../{cpp => cpp.old}/ASTBitwiseComplNode.cc | 0 .../{cpp => cpp.old}/ASTBitwiseComplNode.h | 0 .../main/{cpp => cpp.old}/ASTBitwiseOrNode.cc | 0 .../main/{cpp => cpp.old}/ASTBitwiseOrNode.h | 0 .../{cpp => cpp.old}/ASTBitwiseXorNode.cc | 0 .../main/{cpp => cpp.old}/ASTBitwiseXorNode.h | 0 .../AST/src/main/{cpp => cpp.old}/ASTBlock.cc | 0 .../AST/src/main/{cpp => cpp.old}/ASTBlock.h | 0 .../{cpp => cpp.old}/ASTCompilationUnit.cc | 0 .../{cpp => cpp.old}/ASTCompilationUnit.h | 0 .../src/main/{cpp => cpp.old}/ASTDivNode.cc | 0 .../src/main/{cpp => cpp.old}/ASTDivNode.h | 0 .../src/main/{cpp => cpp.old}/ASTEQNode.cc | 0 .../AST/src/main/{cpp => cpp.old}/ASTEQNode.h | 0 .../src/main/{cpp => cpp.old}/ASTFalseNode.cc | 0 .../src/main/{cpp => cpp.old}/ASTFalseNode.h | 0 .../src/main/{cpp => cpp.old}/ASTGENode.cc | 0 .../AST/src/main/{cpp => cpp.old}/ASTGENode.h | 0 .../src/main/{cpp => cpp.old}/ASTGTNode.cc | 0 .../AST/src/main/{cpp => cpp.old}/ASTGTNode.h | 0 .../Interpreter/AST/src/main/cpp.old/ASTId.cc | 18 + .../Interpreter/AST/src/main/cpp.old/ASTId.h | 22 + .../main/{cpp => cpp.old}/ASTIfStatement.cc | 0 .../main/{cpp => cpp.old}/ASTIfStatement.h | 0 .../AST/src/main/cpp.old/ASTIntConstNode.cc | 16 + .../AST/src/main/cpp.old/ASTIntConstNode.h | 19 + .../src/main/{cpp => cpp.old}/ASTLENode.cc | 0 .../AST/src/main/{cpp => cpp.old}/ASTLENode.h | 0 .../src/main/{cpp => cpp.old}/ASTLTNode.cc | 0 .../AST/src/main/{cpp => cpp.old}/ASTLTNode.h | 0 .../src/main/{cpp => cpp.old}/ASTModNode.cc | 0 .../src/main/{cpp => cpp.old}/ASTModNode.h | 0 .../src/main/{cpp => cpp.old}/ASTMulNode.cc | 0 .../src/main/{cpp => cpp.old}/ASTMulNode.h | 0 .../src/main/{cpp => cpp.old}/ASTNENode.cc | 0 .../AST/src/main/{cpp => cpp.old}/ASTNENode.h | 0 .../src/main/{cpp => cpp.old}/ASTNotNode.cc | 0 .../src/main/{cpp => cpp.old}/ASTNotNode.h | 0 .../src/main/{cpp => cpp.old}/ASTOrNode.cc | 0 .../AST/src/main/{cpp => cpp.old}/ASTOrNode.h | 0 .../AST/src/main/cpp.old/ASTReadStatement.cc | 39 + .../AST/src/main/cpp.old/ASTReadStatement.h | 21 + .../ASTStatementExpression.cc | 0 .../{cpp => cpp.old}/ASTStatementExpression.h | 0 .../main/{cpp => cpp.old}/ASTSubtractNode.cc | 0 .../main/{cpp => cpp.old}/ASTSubtractNode.h | 0 .../src/main/{cpp => cpp.old}/ASTTrueNode.cc | 0 .../src/main/{cpp => cpp.old}/ASTTrueNode.h | 0 .../AST/src/main/cpp.old/ASTVarDeclaration.cc | 20 + .../AST/src/main/cpp.old/ASTVarDeclaration.h | 21 + .../{cpp => cpp.old}/ASTWhileStatement.cc | 0 .../main/{cpp => cpp.old}/ASTWhileStatement.h | 0 .../AST/src/main/cpp.old/ASTWriteStatement.cc | 26 + .../AST/src/main/cpp.old/ASTWriteStatement.h | 20 + .../AST/src/main/cpp.old/Boolean.cpp | 22 + .../AST/src/main/cpp.old/Boolean.h | 25 + .../AST/src/main/cpp.old/Integer.cpp | 46 + .../AST/src/main/cpp.old/Integer.h | 35 + .../AST/src/main/cpp.old/MyNode.cc | 12 + .../Interpreter/AST/src/main/cpp.old/MyNode.h | 68 + .../AST/src/main/cpp.old/Object.cpp | 15 + .../Interpreter/AST/src/main/cpp.old/Object.h | 16 + .../Interpreter/AST/src/main/cpp.old/SPLC.cpp | 56 + .../AST/src/main/cpp.old/Variable.cpp | 15 + .../AST/src/main/cpp.old/Variable.h | 24 + examples/Interpreter/VST/pom.xml | 4 +- examples/Interpreter/pom.xml | 4 +- examples/{JJTreeExamples => JJTree}/README | 0 .../{JJTreeExamples => JJTree}/eg1/eg1.ref | 0 .../{JJTreeExamples => JJTree}/eg1/pom.xml | 8 +- .../eg1/src/main/cpp/FileStreamReader.cpp | 0 .../eg1/src/main/cpp/eg1.cpp | 0 .../eg1/src/main/jjtree/eg1.jjt | 0 .../{JJTreeExamples => JJTree}/eg2/pom.xml | 8 +- .../eg2/src/main/cpp/eg2/ASTMyID.cc | 0 .../eg2/src/main/cpp/eg2/ASTMyID.h | 0 .../eg2/src/main/cpp/eg2/eg2.cpp | 0 .../eg2/src/main/jjtree/eg2.jjt | 0 .../{JJTreeExamples => JJTree}/eg3/pom.xml | 8 +- .../eg3/src/main/cpp/ASTMyID.cc | 0 .../eg3/src/main/cpp/ASTMyID.h | 0 .../eg3/src/main/cpp/eg3.cpp | 0 .../eg3/src/main/jjtree/eg3.jjt | 0 .../{JJTreeExamples => JJTree}/eg4/pom.xml | 8 +- .../eg4/src/main/cpp/ASTMyID.cc | 0 .../eg4/src/main/cpp/ASTMyID.h | 0 .../eg4/src/main/cpp/ASTMyOtherID.cc | 0 .../eg4/src/main/cpp/ASTMyOtherID.h | 0 .../eg4/src/main/cpp/EG4DumpVisitor.cc | 0 .../eg4/src/main/cpp/EG4DumpVisitor.h | 0 .../eg4/src/main/cpp/MyErrorHandler.cc | 0 .../eg4/src/main/cpp/MyErrorHandler.h | 0 .../eg4/src/main/cpp/eg4.cpp | 0 .../eg4/src/main/jjtree/eg4.jjt | 0 examples/JJTree/files/eg1.in | 1 + examples/JJTree/files/eg1.ref | 23 + examples/JJTree/files/eg2.in | 1 + examples/JJTree/files/eg2.ref | 9 + examples/JJTree/files/eg3.in | 1 + examples/JJTree/files/eg3.ref | 9 + examples/JJTree/files/eg4.in | 1 + examples/JJTree/files/eg4.ref | 9 + examples/{JJTreeExamples => JJTree}/pom.xml | 8 +- examples/LexicalState/pom.xml | 4 +- examples/MailProcessing/1.html | 39 + examples/MailProcessing/2.html | 20 + examples/MailProcessing/3.html | 22 + examples/MailProcessing/files/1.exp_out.html | 39 + examples/MailProcessing/files/2.exp_out.html | 20 + examples/MailProcessing/files/3.exp_out.html | 22 + .../MailProcessing/files/digestFile.exp_out | 102 + .../MailProcessing/files/index.exp_out.html | 5 + examples/MailProcessing/files/index.html | 5 + examples/MailProcessing/files/index.out.html | 5 + .../MailProcessing/files/sampleMailFile.in | 237 ++ examples/MailProcessing/pom.xml | 186 +- .../src/main/cpp/DigestMain.cpp | 177 ++ .../MailProcessing/src/main/cpp/DigestMain.h | 43 + .../MailProcessing/src/main/cpp/FaqMain.cpp | 182 ++ .../MailProcessing/src/main/cpp/FaqMain.h | 98 + examples/MailProcessing/src/main/cpp/Mail.cpp | 32 - .../src/main/cpp/StreamReader.cpp | 59 + .../src/main/cpp/StreamReader.h | 48 + examples/MailProcessing/src/main/cpp/main.cpp | 64 + .../MailProcessing/src/main/javacc/Digest.jj | 156 +- .../MailProcessing/src/main/javacc/Faq.jj | 215 +- examples/UserTokenManager/pom.xml | 4 +- examples/pom.xml | 6 +- examples/settings.xml | 4 +- grammars/asn1/pom.xml | 4 +- grammars/c/pom.xml | 4 +- grammars/chemical/pom.xml | 4 +- grammars/cobol/pom.xml | 4 +- grammars/dtd/pom.xml | 4 +- grammars/ecma/pom.xml | 4 +- grammars/java_1.1/pom.xml | 4 +- grammars/java_1.1_widechar/pom.xml | 4 +- grammars/java_1.5/pom.xml | 4 +- grammars/pom.xml | 7 +- grammars/settings.xml | 4 +- it/pom.xml | 4 +- pom.xml | 62 +- .../java/org/javacc/cpp/CppCodeBuilder.java | 121 +- .../java/org/javacc/cpp/CppCodeGenerator.java | 278 +- .../org/javacc/cpp/JJTreeCodeGenerator.java | 2 +- src/main/java/org/javacc/cpp/NodeFiles.java | 436 +-- .../java/org/javacc/cpp/OtherFilesGenCPP.java | 269 +- .../org/javacc/cpp/ParserCodeGenerator.java | 2439 +++++++++-------- .../org/javacc/cpp/TokenCodeGenerator.java | 91 +- .../javacc/cpp/TokenManagerCodeGenerator.java | 411 +-- .../templates/cpp/CharStream.h.template | 158 +- .../cpp/DefaultCharStream.cc.template | 343 ++- .../cpp/DefaultCharStream.h.template | 261 +- .../cpp/DefaultParserErrorHandler.cc.template | 91 +- .../cpp/DefaultParserErrorHandler.h.template | 70 +- ...efaultTokenManagerErrorHandler.cc.template | 55 +- ...DefaultTokenManagerErrorHandler.h.template | 47 +- .../templates/cpp/ImportExport.h.template | 118 +- .../resources/templates/cpp/JavaCC.h.template | 99 +- .../templates/cpp/ParseException.cc.template | 240 +- .../templates/cpp/ParseException.h.template | 123 +- .../cpp/ParserErrorHandler.h.template | 85 +- .../cpp/TableDrivenTokenManager.h.template | 96 - .../resources/templates/cpp/Token.cc.template | 60 +- .../resources/templates/cpp/Token.h.template | 226 +- .../templates/cpp/TokenManager.h.template | 99 +- ...emplate => TokenManagerDriver.cc.template} | 299 +- .../cpp/TokenManagerDriver.h.template | 125 + .../cpp/TokenManagerError.cc.template | 92 +- .../cpp/TokenManagerError.h.template | 78 +- .../cpp/TokenManagerErrorHandler.h.template | 66 +- 197 files changed, 6833 insertions(+), 3874 deletions(-) create mode 100644 README.md create mode 100644 examples/Interpreter/AST/src/.gitignore rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTAddNode.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTAddNode.h (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTAndNode.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTAndNode.h (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTAssignment.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTAssignment.h (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTBitwiseAndNode.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTBitwiseAndNode.h (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTBitwiseComplNode.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTBitwiseComplNode.h (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTBitwiseOrNode.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTBitwiseOrNode.h (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTBitwiseXorNode.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTBitwiseXorNode.h (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTBlock.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTBlock.h (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTCompilationUnit.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTCompilationUnit.h (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTDivNode.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTDivNode.h (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTEQNode.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTEQNode.h (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTFalseNode.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTFalseNode.h (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTGENode.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTGENode.h (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTGTNode.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTGTNode.h (100%) create mode 100644 examples/Interpreter/AST/src/main/cpp.old/ASTId.cc create mode 100644 examples/Interpreter/AST/src/main/cpp.old/ASTId.h rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTIfStatement.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTIfStatement.h (100%) create mode 100644 examples/Interpreter/AST/src/main/cpp.old/ASTIntConstNode.cc create mode 100644 examples/Interpreter/AST/src/main/cpp.old/ASTIntConstNode.h rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTLENode.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTLENode.h (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTLTNode.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTLTNode.h (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTModNode.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTModNode.h (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTMulNode.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTMulNode.h (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTNENode.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTNENode.h (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTNotNode.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTNotNode.h (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTOrNode.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTOrNode.h (100%) create mode 100644 examples/Interpreter/AST/src/main/cpp.old/ASTReadStatement.cc create mode 100644 examples/Interpreter/AST/src/main/cpp.old/ASTReadStatement.h rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTStatementExpression.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTStatementExpression.h (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTSubtractNode.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTSubtractNode.h (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTTrueNode.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTTrueNode.h (100%) create mode 100644 examples/Interpreter/AST/src/main/cpp.old/ASTVarDeclaration.cc create mode 100644 examples/Interpreter/AST/src/main/cpp.old/ASTVarDeclaration.h rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTWhileStatement.cc (100%) rename examples/Interpreter/AST/src/main/{cpp => cpp.old}/ASTWhileStatement.h (100%) create mode 100644 examples/Interpreter/AST/src/main/cpp.old/ASTWriteStatement.cc create mode 100644 examples/Interpreter/AST/src/main/cpp.old/ASTWriteStatement.h create mode 100644 examples/Interpreter/AST/src/main/cpp.old/Boolean.cpp create mode 100644 examples/Interpreter/AST/src/main/cpp.old/Boolean.h create mode 100644 examples/Interpreter/AST/src/main/cpp.old/Integer.cpp create mode 100644 examples/Interpreter/AST/src/main/cpp.old/Integer.h create mode 100644 examples/Interpreter/AST/src/main/cpp.old/MyNode.cc create mode 100644 examples/Interpreter/AST/src/main/cpp.old/MyNode.h create mode 100644 examples/Interpreter/AST/src/main/cpp.old/Object.cpp create mode 100644 examples/Interpreter/AST/src/main/cpp.old/Object.h create mode 100644 examples/Interpreter/AST/src/main/cpp.old/SPLC.cpp create mode 100644 examples/Interpreter/AST/src/main/cpp.old/Variable.cpp create mode 100644 examples/Interpreter/AST/src/main/cpp.old/Variable.h rename examples/{JJTreeExamples => JJTree}/README (100%) rename examples/{JJTreeExamples => JJTree}/eg1/eg1.ref (100%) rename examples/{JJTreeExamples => JJTree}/eg1/pom.xml (93%) rename examples/{JJTreeExamples => JJTree}/eg1/src/main/cpp/FileStreamReader.cpp (100%) rename examples/{JJTreeExamples => JJTree}/eg1/src/main/cpp/eg1.cpp (100%) rename examples/{JJTreeExamples => JJTree}/eg1/src/main/jjtree/eg1.jjt (100%) rename examples/{JJTreeExamples => JJTree}/eg2/pom.xml (94%) rename examples/{JJTreeExamples => JJTree}/eg2/src/main/cpp/eg2/ASTMyID.cc (100%) rename examples/{JJTreeExamples => JJTree}/eg2/src/main/cpp/eg2/ASTMyID.h (100%) rename examples/{JJTreeExamples => JJTree}/eg2/src/main/cpp/eg2/eg2.cpp (100%) rename examples/{JJTreeExamples => JJTree}/eg2/src/main/jjtree/eg2.jjt (100%) rename examples/{JJTreeExamples => JJTree}/eg3/pom.xml (92%) rename examples/{JJTreeExamples => JJTree}/eg3/src/main/cpp/ASTMyID.cc (100%) rename examples/{JJTreeExamples => JJTree}/eg3/src/main/cpp/ASTMyID.h (100%) rename examples/{JJTreeExamples => JJTree}/eg3/src/main/cpp/eg3.cpp (100%) rename examples/{JJTreeExamples => JJTree}/eg3/src/main/jjtree/eg3.jjt (100%) rename examples/{JJTreeExamples => JJTree}/eg4/pom.xml (91%) rename examples/{JJTreeExamples => JJTree}/eg4/src/main/cpp/ASTMyID.cc (100%) rename examples/{JJTreeExamples => JJTree}/eg4/src/main/cpp/ASTMyID.h (100%) rename examples/{JJTreeExamples => JJTree}/eg4/src/main/cpp/ASTMyOtherID.cc (100%) rename examples/{JJTreeExamples => JJTree}/eg4/src/main/cpp/ASTMyOtherID.h (100%) rename examples/{JJTreeExamples => JJTree}/eg4/src/main/cpp/EG4DumpVisitor.cc (100%) rename examples/{JJTreeExamples => JJTree}/eg4/src/main/cpp/EG4DumpVisitor.h (100%) rename examples/{JJTreeExamples => JJTree}/eg4/src/main/cpp/MyErrorHandler.cc (100%) rename examples/{JJTreeExamples => JJTree}/eg4/src/main/cpp/MyErrorHandler.h (100%) rename examples/{JJTreeExamples => JJTree}/eg4/src/main/cpp/eg4.cpp (100%) rename examples/{JJTreeExamples => JJTree}/eg4/src/main/jjtree/eg4.jjt (100%) create mode 100644 examples/JJTree/files/eg1.in create mode 100644 examples/JJTree/files/eg1.ref create mode 100644 examples/JJTree/files/eg2.in create mode 100644 examples/JJTree/files/eg2.ref create mode 100644 examples/JJTree/files/eg3.in create mode 100644 examples/JJTree/files/eg3.ref create mode 100644 examples/JJTree/files/eg4.in create mode 100644 examples/JJTree/files/eg4.ref rename examples/{JJTreeExamples => JJTree}/pom.xml (90%) create mode 100644 examples/MailProcessing/1.html create mode 100644 examples/MailProcessing/2.html create mode 100644 examples/MailProcessing/3.html create mode 100644 examples/MailProcessing/files/1.exp_out.html create mode 100644 examples/MailProcessing/files/2.exp_out.html create mode 100644 examples/MailProcessing/files/3.exp_out.html create mode 100644 examples/MailProcessing/files/digestFile.exp_out create mode 100644 examples/MailProcessing/files/index.exp_out.html create mode 100644 examples/MailProcessing/files/index.html create mode 100644 examples/MailProcessing/files/index.out.html create mode 100644 examples/MailProcessing/files/sampleMailFile.in create mode 100644 examples/MailProcessing/src/main/cpp/DigestMain.cpp create mode 100644 examples/MailProcessing/src/main/cpp/DigestMain.h create mode 100644 examples/MailProcessing/src/main/cpp/FaqMain.cpp create mode 100644 examples/MailProcessing/src/main/cpp/FaqMain.h delete mode 100644 examples/MailProcessing/src/main/cpp/Mail.cpp create mode 100644 examples/MailProcessing/src/main/cpp/StreamReader.cpp create mode 100644 examples/MailProcessing/src/main/cpp/StreamReader.h create mode 100644 examples/MailProcessing/src/main/cpp/main.cpp delete mode 100644 src/main/resources/templates/cpp/TableDrivenTokenManager.h.template rename src/main/resources/templates/cpp/{TableDrivenTokenManager.cc.template => TokenManagerDriver.cc.template} (62%) create mode 100644 src/main/resources/templates/cpp/TokenManagerDriver.h.template diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index cbb053d..caf0a02 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,8 +1,8 @@ # This workflow will build a Java project with Maven # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven # -# Copyright (c) 2020-2024, Sreeni Viswanadha . -# Copyright (c) 2024, Marc Mazas . +# Copyright (c) 2020-2025, Sreeni Viswanadha . +# Copyright (c) 2024-2025, Marc Mazas . # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/LICENSE b/LICENSE index 54dcded..6a307f9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,8 +1,8 @@ BSD 3-Clause License Copyright (c) 2020-2021, javacc -Copyright (c) 2020-2024, Sreeni Viswanadha . -Copyright (c) 2024, Marc Mazas . +Copyright (c) 2020-2025, Sreeni Viswanadha . +Copyright (c) 2024-2025, Marc Mazas . All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/README.md b/README.md new file mode 100644 index 0000000..d85d7d2 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# JavaCC-8 C++ (CPP) + +This is the JavaCC **C++** generator Git repository / java & maven project of JavaCC version 8. + +See the README at [javacc-8](https://github.com/javacc/javacc-8) diff --git a/bugs/bug001/files/clc1.exp_err b/bugs/bug001/files/clc1.exp_err index d64c113..8899dd8 100644 --- a/bugs/bug001/files/clc1.exp_err +++ b/bugs/bug001/files/clc1.exp_err @@ -1,568 +1,399 @@ - - Current character: 'a' at 1:1 + Current input char: 'a' at 1:1 No string literal start with char: 'a' Starting NFA with start state: 0 - Current character: 'a' -Looking to move from state: 0 for: -state=0 vectorindex=1 bitpattern=8589934592 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 0 characters. - Current character: 'a' -Looking to move from state: 1 for: -state=1 vectorindex=1 bitpattern=8589934592 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 1 characters. - Current character: ' ' -Looking to move from state: 1 for: -state=1 vectorindex=0 bitpattern=512 jjChars[state][vectorIndex]=287984085547089920 +Cur char: 'a' +Looking to move from state: 0 +Found a match of kind: 9 [] using the first: 0 characters +Cur char: 'a' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 1 characters +Cur char: ' ' +Looking to move from state: 1 Done with NFA at pos: 2 -Returning token: 'aa' - - Current character: ' ' at 1:8 -Looking for string literal match of kind:2 token image: '\t' - Current character: ' ' - Currently matched the first: 1 chars as kind: 2,with image: \t +Returning token: 'aa' + Current input char: ' ' at 1:3 +Looking for string literal match of kind: 2 "\t" +Cur char: ' ' +Currently matched the first: 1 chars as kind: 2 "\t" No NFA state at pos: 2 -Found a SKIP match. - - Current character: '-' at 1:9 -Looking for string literal match of kind:7 token image: '--' - Current character: '-' - Current character: '-' - Currently matched the first: 2 chars as kind: 7,with image: -- +Found a SKIP match + Current input char: '-' at 1:4 +Looking for string literal match of kind: 7 "--" +Cur char: '-' +Cur char: '-' +Currently matched the first: 2 chars as kind: 7 "--" No NFA state at pos: 3 -Found a SKIP match. - - Current character: ' ' at 1:11 +Found a SKIP match + Current input char: ' ' at 1:6 No string literal start with char: ' ' Starting NFA with start state: 9 - Current character: ' ' -Looking to move from state: 6 for: -state=6 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=35184372088832 -Looking to move from state: 5 for: -state=5 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=9216 -Looking to move from state: 4 for: -state=4 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=8192 -Looking to move from state: 2 for: -state=2 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=18446708889337453567 -Found a match of kind:8; kind: using the first: 0 characters. -Looking to move from state: 9 for: -state=9 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=0 - Current character: 'I' -Looking to move from state: 6 for: -state=6 vectorindex=1 bitpattern=512 jjChars[state][vectorIndex]=0 -Looking to move from state: 5 for: -state=5 vectorindex=1 bitpattern=512 jjChars[state][vectorIndex]=0 -Looking to move from state: 4 for: -state=4 vectorindex=1 bitpattern=512 jjChars[state][vectorIndex]=0 -Looking to move from state: 2 for: -state=2 vectorindex=1 bitpattern=512 jjChars[state][vectorIndex]=18446744073709551615 -Found a match of kind:8; kind: using the first: 1 characters. - Current character: 'n' -Looking to move from state: 6 for: -state=6 vectorindex=1 bitpattern=70368744177664 jjChars[state][vectorIndex]=0 -Looking to move from state: 5 for: -state=5 vectorindex=1 bitpattern=70368744177664 jjChars[state][vectorIndex]=0 -Looking to move from state: 4 for: -state=4 vectorindex=1 bitpattern=70368744177664 jjChars[state][vectorIndex]=0 -Looking to move from state: 2 for: -state=2 vectorindex=1 bitpattern=70368744177664 jjChars[state][vectorIndex]=18446744073709551615 -Found a match of kind:8; kind: using the first: 2 characters. - Current character: 't' -Looking to move from state: 6 for: -state=6 vectorindex=1 bitpattern=4503599627370496 jjChars[state][vectorIndex]=0 -Looking to move from state: 5 for: -state=5 vectorindex=1 bitpattern=4503599627370496 jjChars[state][vectorIndex]=0 -Looking to move from state: 4 for: -state=4 vectorindex=1 bitpattern=4503599627370496 jjChars[state][vectorIndex]=0 -Looking to move from state: 2 for: -state=2 vectorindex=1 bitpattern=4503599627370496 jjChars[state][vectorIndex]=18446744073709551615 -Found a match of kind:8; kind: using the first: 3 characters. - Current character: '6' -Looking to move from state: 6 for: -state=6 vectorindex=0 bitpattern=18014398509481984 jjChars[state][vectorIndex]=35184372088832 -Looking to move from state: 5 for: -state=5 vectorindex=0 bitpattern=18014398509481984 jjChars[state][vectorIndex]=9216 -Looking to move from state: 4 for: -state=4 vectorindex=0 bitpattern=18014398509481984 jjChars[state][vectorIndex]=8192 -Looking to move from state: 2 for: -state=2 vectorindex=0 bitpattern=18014398509481984 jjChars[state][vectorIndex]=18446708889337453567 -Found a match of kind:8; kind: using the first: 4 characters. - Current character: ' ' -Looking to move from state: 6 for: -state=6 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=35184372088832 -Looking to move from state: 5 for: -state=5 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=9216 -Looking to move from state: 4 for: -state=4 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=8192 -Looking to move from state: 2 for: -state=2 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=18446708889337453567 -Found a match of kind:8; kind: using the first: 5 characters. - Current character: '-' -Looking to move from state: 6 for: -state=6 vectorindex=0 bitpattern=35184372088832 jjChars[state][vectorIndex]=35184372088832 -Looking to move from state: 5 for: -state=5 vectorindex=0 bitpattern=35184372088832 jjChars[state][vectorIndex]=9216 -Looking to move from state: 4 for: -state=4 vectorindex=0 bitpattern=35184372088832 jjChars[state][vectorIndex]=8192 -Looking to move from state: 2 for: -state=2 vectorindex=0 bitpattern=35184372088832 jjChars[state][vectorIndex]=18446708889337453567 - Current character: '-' -Looking to move from state: 8 for: -state=8 vectorindex=0 bitpattern=35184372088832 jjChars[state][vectorIndex]=35184372088832 -Found a match of kind:8; kind: using the first: 7 characters. -Looking to move from state: 7 for: -state=7 vectorindex=0 bitpattern=35184372088832 jjChars[state][vectorIndex]=8192 -Looking to move from state: 5 for: -state=5 vectorindex=0 bitpattern=35184372088832 jjChars[state][vectorIndex]=9216 -Looking to move from state: 2 for: -state=2 vectorindex=0 bitpattern=35184372088832 jjChars[state][vectorIndex]=18446708889337453567 +Cur char: ' ' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 0 characters +Looking to move from state: 9 +Cur char: 'I' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 1 characters +Cur char: 'n' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 2 characters +Cur char: 't' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 3 characters +Cur char: '6' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 4 characters +Cur char: ' ' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 5 characters +Cur char: '-' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Cur char: '-' +Looking to move from state: 8 +Found a match of kind: 8 [] using the first: 7 characters +Looking to move from state: 7 +Looking to move from state: 5 +Looking to move from state: 2 Done with NFA at pos: 7 -Found a SKIP match. - - Current character: ' ' at 1:19 -Looking for string literal match of kind:1 token image: ' ' - Current character: ' ' - Currently matched the first: 1 chars as kind: 1,with image: +Found a SKIP match + Current input char: ' ' at 1:14 +Looking for string literal match of kind: 1 " " +Cur char: ' ' +Currently matched the first: 1 chars as kind: 1 " " No NFA state at pos: 2 -Found a SKIP match. - - Current character: '-' at 1:20 -Looking for string literal match of kind:7 token image: '--' - Current character: '-' - Current character: '-' - Currently matched the first: 2 chars as kind: 7,with image: -- +Found a SKIP match + Current input char: '-' at 1:15 +Looking for string literal match of kind: 7 "--" +Cur char: '-' +Cur char: '-' +Currently matched the first: 2 chars as kind: 7 "--" No NFA state at pos: 3 -Found a SKIP match. - - Current character: ' ' at 1:22 +Found a SKIP match + Current input char: ' ' at 1:17 No string literal start with char: ' ' Starting NFA with start state: 9 - Current character: ' ' -Looking to move from state: 6 for: -state=6 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=35184372088832 -Looking to move from state: 5 for: -state=5 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=9216 -Looking to move from state: 4 for: -state=4 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=8192 -Looking to move from state: 2 for: -state=2 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=18446708889337453567 -Found a match of kind:8; kind: using the first: 0 characters. -Looking to move from state: 9 for: -state=9 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=0 - Current character: 'N' -Looking to move from state: 6 for: -state=6 vectorindex=1 bitpattern=16384 jjChars[state][vectorIndex]=0 -Looking to move from state: 5 for: -state=5 vectorindex=1 bitpattern=16384 jjChars[state][vectorIndex]=0 -Looking to move from state: 4 for: -state=4 vectorindex=1 bitpattern=16384 jjChars[state][vectorIndex]=0 -Looking to move from state: 2 for: -state=2 vectorindex=1 bitpattern=16384 jjChars[state][vectorIndex]=18446744073709551615 -Found a match of kind:8; kind: using the first: 1 characters. - Current character: 'o' -Looking to move from state: 6 for: -state=6 vectorindex=1 bitpattern=140737488355328 jjChars[state][vectorIndex]=0 -Looking to move from state: 5 for: -state=5 vectorindex=1 bitpattern=140737488355328 jjChars[state][vectorIndex]=0 -Looking to move from state: 4 for: -state=4 vectorindex=1 bitpattern=140737488355328 jjChars[state][vectorIndex]=0 -Looking to move from state: 2 for: -state=2 vectorindex=1 bitpattern=140737488355328 jjChars[state][vectorIndex]=18446744073709551615 -Found a match of kind:8; kind: using the first: 2 characters. - Current character: 't' -Looking to move from state: 6 for: -state=6 vectorindex=1 bitpattern=4503599627370496 jjChars[state][vectorIndex]=0 -Looking to move from state: 5 for: -state=5 vectorindex=1 bitpattern=4503599627370496 jjChars[state][vectorIndex]=0 -Looking to move from state: 4 for: -state=4 vectorindex=1 bitpattern=4503599627370496 jjChars[state][vectorIndex]=0 -Looking to move from state: 2 for: -state=2 vectorindex=1 bitpattern=4503599627370496 jjChars[state][vectorIndex]=18446744073709551615 -Found a match of kind:8; kind: using the first: 3 characters. - Current character: ' ' -Looking to move from state: 6 for: -state=6 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=35184372088832 -Looking to move from state: 5 for: -state=5 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=9216 -Looking to move from state: 4 for: -state=4 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=8192 -Looking to move from state: 2 for: -state=2 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=18446708889337453567 -Found a match of kind:8; kind: using the first: 4 characters. - Current character: 'y' -Looking to move from state: 6 for: -state=6 vectorindex=1 bitpattern=144115188075855872 jjChars[state][vectorIndex]=0 -Looking to move from state: 5 for: -state=5 vectorindex=1 bitpattern=144115188075855872 jjChars[state][vectorIndex]=0 -Looking to move from state: 4 for: -state=4 vectorindex=1 bitpattern=144115188075855872 jjChars[state][vectorIndex]=0 -Looking to move from state: 2 for: -state=2 vectorindex=1 bitpattern=144115188075855872 jjChars[state][vectorIndex]=18446744073709551615 -Found a match of kind:8; kind: using the first: 5 characters. - Current character: 'e' -Looking to move from state: 6 for: -state=6 vectorindex=1 bitpattern=137438953472 jjChars[state][vectorIndex]=0 -Looking to move from state: 5 for: -state=5 vectorindex=1 bitpattern=137438953472 jjChars[state][vectorIndex]=0 -Looking to move from state: 4 for: -state=4 vectorindex=1 bitpattern=137438953472 jjChars[state][vectorIndex]=0 -Looking to move from state: 2 for: -state=2 vectorindex=1 bitpattern=137438953472 jjChars[state][vectorIndex]=18446744073709551615 -Found a match of kind:8; kind: using the first: 6 characters. - Current character: 't' -Looking to move from state: 6 for: -state=6 vectorindex=1 bitpattern=4503599627370496 jjChars[state][vectorIndex]=0 -Looking to move from state: 5 for: -state=5 vectorindex=1 bitpattern=4503599627370496 jjChars[state][vectorIndex]=0 -Looking to move from state: 4 for: -state=4 vectorindex=1 bitpattern=4503599627370496 jjChars[state][vectorIndex]=0 -Looking to move from state: 2 for: -state=2 vectorindex=1 bitpattern=4503599627370496 jjChars[state][vectorIndex]=18446744073709551615 -Found a match of kind:8; kind: using the first: 7 characters. - Current character: ' ' -Looking to move from state: 6 for: -state=6 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=35184372088832 -Looking to move from state: 5 for: -state=5 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=9216 -Looking to move from state: 4 for: -state=4 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=8192 -Looking to move from state: 2 for: -state=2 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=18446708889337453567 -Found a match of kind:8; kind: using the first: 8 characters. - Current character: 's' -Looking to move from state: 6 for: -state=6 vectorindex=1 bitpattern=2251799813685248 jjChars[state][vectorIndex]=0 -Looking to move from state: 5 for: -state=5 vectorindex=1 bitpattern=2251799813685248 jjChars[state][vectorIndex]=0 -Looking to move from state: 4 for: -state=4 vectorindex=1 bitpattern=2251799813685248 jjChars[state][vectorIndex]=0 -Looking to move from state: 2 for: -state=2 vectorindex=1 bitpattern=2251799813685248 jjChars[state][vectorIndex]=18446744073709551615 -Found a match of kind:8; kind: using the first: 9 characters. - Current character: 'u' -Looking to move from state: 6 for: -state=6 vectorindex=1 bitpattern=9007199254740992 jjChars[state][vectorIndex]=0 -Looking to move from state: 5 for: -state=5 vectorindex=1 bitpattern=9007199254740992 jjChars[state][vectorIndex]=0 -Looking to move from state: 4 for: -state=4 vectorindex=1 bitpattern=9007199254740992 jjChars[state][vectorIndex]=0 -Looking to move from state: 2 for: -state=2 vectorindex=1 bitpattern=9007199254740992 jjChars[state][vectorIndex]=18446744073709551615 -Found a match of kind:8; kind: using the first: 10 characters. - Current character: 'p' -Looking to move from state: 6 for: -state=6 vectorindex=1 bitpattern=281474976710656 jjChars[state][vectorIndex]=0 -Looking to move from state: 5 for: -state=5 vectorindex=1 bitpattern=281474976710656 jjChars[state][vectorIndex]=0 -Looking to move from state: 4 for: -state=4 vectorindex=1 bitpattern=281474976710656 jjChars[state][vectorIndex]=0 -Looking to move from state: 2 for: -state=2 vectorindex=1 bitpattern=281474976710656 jjChars[state][vectorIndex]=18446744073709551615 -Found a match of kind:8; kind: using the first: 11 characters. - Current character: 'p' -Looking to move from state: 6 for: -state=6 vectorindex=1 bitpattern=281474976710656 jjChars[state][vectorIndex]=0 -Looking to move from state: 5 for: -state=5 vectorindex=1 bitpattern=281474976710656 jjChars[state][vectorIndex]=0 -Looking to move from state: 4 for: -state=4 vectorindex=1 bitpattern=281474976710656 jjChars[state][vectorIndex]=0 -Looking to move from state: 2 for: -state=2 vectorindex=1 bitpattern=281474976710656 jjChars[state][vectorIndex]=18446744073709551615 -Found a match of kind:8; kind: using the first: 12 characters. - Current character: 'o' -Looking to move from state: 6 for: -state=6 vectorindex=1 bitpattern=140737488355328 jjChars[state][vectorIndex]=0 -Looking to move from state: 5 for: -state=5 vectorindex=1 bitpattern=140737488355328 jjChars[state][vectorIndex]=0 -Looking to move from state: 4 for: -state=4 vectorindex=1 bitpattern=140737488355328 jjChars[state][vectorIndex]=0 -Looking to move from state: 2 for: -state=2 vectorindex=1 bitpattern=140737488355328 jjChars[state][vectorIndex]=18446744073709551615 -Found a match of kind:8; kind: using the first: 13 characters. - Current character: 'r' -Looking to move from state: 6 for: -state=6 vectorindex=1 bitpattern=1125899906842624 jjChars[state][vectorIndex]=0 -Looking to move from state: 5 for: -state=5 vectorindex=1 bitpattern=1125899906842624 jjChars[state][vectorIndex]=0 -Looking to move from state: 4 for: -state=4 vectorindex=1 bitpattern=1125899906842624 jjChars[state][vectorIndex]=0 -Looking to move from state: 2 for: -state=2 vectorindex=1 bitpattern=1125899906842624 jjChars[state][vectorIndex]=18446744073709551615 -Found a match of kind:8; kind: using the first: 14 characters. - Current character: 't' -Looking to move from state: 6 for: -state=6 vectorindex=1 bitpattern=4503599627370496 jjChars[state][vectorIndex]=0 -Looking to move from state: 5 for: -state=5 vectorindex=1 bitpattern=4503599627370496 jjChars[state][vectorIndex]=0 -Looking to move from state: 4 for: -state=4 vectorindex=1 bitpattern=4503599627370496 jjChars[state][vectorIndex]=0 -Looking to move from state: 2 for: -state=2 vectorindex=1 bitpattern=4503599627370496 jjChars[state][vectorIndex]=18446744073709551615 -Found a match of kind:8; kind: using the first: 15 characters. - Current character: 'e' -Looking to move from state: 6 for: -state=6 vectorindex=1 bitpattern=137438953472 jjChars[state][vectorIndex]=0 -Looking to move from state: 5 for: -state=5 vectorindex=1 bitpattern=137438953472 jjChars[state][vectorIndex]=0 -Looking to move from state: 4 for: -state=4 vectorindex=1 bitpattern=137438953472 jjChars[state][vectorIndex]=0 -Looking to move from state: 2 for: -state=2 vectorindex=1 bitpattern=137438953472 jjChars[state][vectorIndex]=18446744073709551615 -Found a match of kind:8; kind: using the first: 16 characters. - Current character: 'd' -Looking to move from state: 6 for: -state=6 vectorindex=1 bitpattern=68719476736 jjChars[state][vectorIndex]=0 -Looking to move from state: 5 for: -state=5 vectorindex=1 bitpattern=68719476736 jjChars[state][vectorIndex]=0 -Looking to move from state: 4 for: -state=4 vectorindex=1 bitpattern=68719476736 jjChars[state][vectorIndex]=0 -Looking to move from state: 2 for: -state=2 vectorindex=1 bitpattern=68719476736 jjChars[state][vectorIndex]=18446744073709551615 -Found a match of kind:8; kind: using the first: 17 characters. - Current character: ' ' -Looking to move from state: 6 for: -state=6 vectorindex=0 bitpattern=8192 jjChars[state][vectorIndex]=35184372088832 -Looking to move from state: 5 for: -state=5 vectorindex=0 bitpattern=8192 jjChars[state][vectorIndex]=9216 -Found a match of kind:8; kind: using the first: 18 characters. -Looking to move from state: 4 for: -state=4 vectorindex=0 bitpattern=8192 jjChars[state][vectorIndex]=8192 -Looking to move from state: 2 for: -state=2 vectorindex=0 bitpattern=8192 jjChars[state][vectorIndex]=18446708889337453567 - Current character: ' +Cur char: ' ' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 0 characters +Looking to move from state: 9 +Cur char: 'N' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 1 characters +Cur char: 'o' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 2 characters +Cur char: 't' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 3 characters +Cur char: ' ' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 4 characters +Cur char: 'y' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 5 characters +Cur char: 'e' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 6 characters +Cur char: 't' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 7 characters +Cur char: ' ' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 8 characters +Cur char: 's' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 9 characters +Cur char: 'u' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 10 characters +Cur char: 'p' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 11 characters +Cur char: 'p' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 12 characters +Cur char: 'o' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 13 characters +Cur char: 'r' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 14 characters +Cur char: 't' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 15 characters +Cur char: 'e' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 16 characters +Cur char: 'd' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 17 characters +Cur char: ' ' +Looking to move from state: 6 +Looking to move from state: 5 +Found a match of kind: 8 [] using the first: 18 characters +Looking to move from state: 4 +Looking to move from state: 2 +Cur char: ' ' -Looking to move from state: 3 for: -state=3 vectorindex=0 bitpattern=1024 jjChars[state][vectorIndex]=1024 -Found a match of kind:8; kind: using the first: 19 characters. +Looking to move from state: 3 +Found a match of kind: 8 [] using the first: 19 characters Done with NFA at pos: 19 -Found a SKIP match. - - Current character: 't' at 2:1 +Found a SKIP match + Current input char: 't' at 2:1 No string literal start with char: 't' Starting NFA with start state: 0 - Current character: 't' -Looking to move from state: 0 for: -state=0 vectorindex=1 bitpattern=4503599627370496 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 0 characters. - Current character: 'e' -Looking to move from state: 1 for: -state=1 vectorindex=1 bitpattern=137438953472 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 1 characters. - Current character: 'n' -Looking to move from state: 1 for: -state=1 vectorindex=1 bitpattern=70368744177664 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 2 characters. - Current character: ' ' -Looking to move from state: 1 for: -state=1 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=287984085547089920 +Cur char: 't' +Looking to move from state: 0 +Found a match of kind: 9 [] using the first: 0 characters +Cur char: 'e' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 1 characters +Cur char: 'n' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 2 characters +Cur char: ' ' +Looking to move from state: 1 Done with NFA at pos: 3 -Returning token: 'ten' - - Current character: ' ' at 2:4 -Looking for string literal match of kind:1 token image: ' ' - Current character: ' ' - Currently matched the first: 1 chars as kind: 1,with image: +Returning token: 'ten' + Current input char: ' ' at 2:4 +Looking for string literal match of kind: 1 " " +Cur char: ' ' +Currently matched the first: 1 chars as kind: 1 " " No NFA state at pos: 2 -Found a SKIP match. - - Current character: 'I' at 2:5 +Found a SKIP match + Current input char: 'I' at 2:5 No string literal start with char: 'I' Starting NFA with start state: 0 - Current character: 'I' -Looking to move from state: 0 for: -state=0 vectorindex=1 bitpattern=512 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 0 characters. - Current character: 'n' -Looking to move from state: 1 for: -state=1 vectorindex=1 bitpattern=70368744177664 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 1 characters. - Current character: 't' -Looking to move from state: 1 for: -state=1 vectorindex=1 bitpattern=4503599627370496 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 2 characters. - Current character: '1' -Looking to move from state: 1 for: -state=1 vectorindex=0 bitpattern=562949953421312 jjChars[state][vectorIndex]=287984085547089920 -Found a match of kind:9; kind: using the first: 3 characters. - Current character: ' ' -Looking to move from state: 1 for: -state=1 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=287984085547089920 +Cur char: 'I' +Looking to move from state: 0 +Found a match of kind: 9 [] using the first: 0 characters +Cur char: 'n' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 1 characters +Cur char: 't' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 2 characters +Cur char: '1' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 3 characters +Cur char: ' ' +Looking to move from state: 1 Done with NFA at pos: 4 -Returning token: 'Int1' - - Current character: ' ' at 2:9 -Looking for string literal match of kind:1 token image: ' ' - Current character: ' ' - Currently matched the first: 1 chars as kind: 1,with image: +Returning token: 'Int1' + Current input char: ' ' at 2:9 +Looking for string literal match of kind: 1 " " +Cur char: ' ' +Currently matched the first: 1 chars as kind: 1 " " No NFA state at pos: 2 -Found a SKIP match. - - Current character: 'o' at 2:10 +Found a SKIP match + Current input char: 'o' at 2:10 No string literal start with char: 'o' Starting NFA with start state: 0 - Current character: 'o' -Looking to move from state: 0 for: -state=0 vectorindex=1 bitpattern=140737488355328 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 0 characters. - Current character: 't' -Looking to move from state: 1 for: -state=1 vectorindex=1 bitpattern=4503599627370496 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 1 characters. - Current character: 'h' -Looking to move from state: 1 for: -state=1 vectorindex=1 bitpattern=1099511627776 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 2 characters. - Current character: 'e' -Looking to move from state: 1 for: -state=1 vectorindex=1 bitpattern=137438953472 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 3 characters. - Current character: 'r' -Looking to move from state: 1 for: -state=1 vectorindex=1 bitpattern=1125899906842624 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 4 characters. - Current character: '-' -Looking to move from state: 1 for: -state=1 vectorindex=0 bitpattern=35184372088832 jjChars[state][vectorIndex]=287984085547089920 -Found a match of kind:9; kind: using the first: 5 characters. - Current character: 't' -Looking to move from state: 1 for: -state=1 vectorindex=1 bitpattern=4503599627370496 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 6 characters. - Current character: 'e' -Looking to move from state: 1 for: -state=1 vectorindex=1 bitpattern=137438953472 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 7 characters. - Current character: 'n' -Looking to move from state: 1 for: -state=1 vectorindex=1 bitpattern=70368744177664 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 8 characters. - Current character: ' ' -Looking to move from state: 1 for: -state=1 vectorindex=0 bitpattern=8192 jjChars[state][vectorIndex]=287984085547089920 +Cur char: 'o' +Looking to move from state: 0 +Found a match of kind: 9 [] using the first: 0 characters +Cur char: 't' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 1 characters +Cur char: 'h' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 2 characters +Cur char: 'e' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 3 characters +Cur char: 'r' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 4 characters +Cur char: '-' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 5 characters +Cur char: 't' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 6 characters +Cur char: 'e' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 7 characters +Cur char: 'n' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 8 characters +Cur char: ' ' +Looking to move from state: 1 Done with NFA at pos: 9 -Returning token: 'other-ten' - - Current character: ' ' at 2:19 -Looking for string literal match of kind:4 token image: '\r' - Current character: ' ' - Currently matched the first: 1 chars as kind: 4,with image: \r +Returning token: 'other-ten' + Current input char: ' ' at 2:19 +Looking for string literal match of kind: 4 "\r" +Cur char: ' ' +Currently matched the first: 1 chars as kind: 4 "\r" No NFA state at pos: 2 -Found a SKIP match. - - Current character: ' +Found a SKIP match + Current input char: ' ' at 2:20 -Looking for string literal match of kind:3 token image: '\n' - Current character: ' +Looking for string literal match of kind: 3 "\n" +Cur char: ' ' - Currently matched the first: 1 chars as kind: 3,with image: \n +Currently matched the first: 1 chars as kind: 3 "\n" No NFA state at pos: 2 -Found a SKIP match. - - Current character: 'o' at 3:1 +Found a SKIP match + Current input char: 'o' at 3:1 No string literal start with char: 'o' Starting NFA with start state: 0 - Current character: 'o' -Looking to move from state: 0 for: -state=0 vectorindex=1 bitpattern=140737488355328 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 0 characters. - Current character: 't' -Looking to move from state: 1 for: -state=1 vectorindex=1 bitpattern=4503599627370496 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 1 characters. - Current character: 'h' -Looking to move from state: 1 for: -state=1 vectorindex=1 bitpattern=1099511627776 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 2 characters. - Current character: 'e' -Looking to move from state: 1 for: -state=1 vectorindex=1 bitpattern=137438953472 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 3 characters. - Current character: 'r' -Looking to move from state: 1 for: -state=1 vectorindex=1 bitpattern=1125899906842624 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 4 characters. - Current character: '-' -Looking to move from state: 1 for: -state=1 vectorindex=0 bitpattern=35184372088832 jjChars[state][vectorIndex]=287984085547089920 -Found a match of kind:9; kind: using the first: 5 characters. - Current character: 't' -Looking to move from state: 1 for: -state=1 vectorindex=1 bitpattern=4503599627370496 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 6 characters. - Current character: 'e' -Looking to move from state: 1 for: -state=1 vectorindex=1 bitpattern=137438953472 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 7 characters. - Current character: 'n' -Looking to move from state: 1 for: -state=1 vectorindex=1 bitpattern=70368744177664 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 8 characters. - Current character: ' ' -Looking to move from state: 1 for: -state=1 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=287984085547089920 +Cur char: 'o' +Looking to move from state: 0 +Found a match of kind: 9 [] using the first: 0 characters +Cur char: 't' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 1 characters +Cur char: 'h' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 2 characters +Cur char: 'e' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 3 characters +Cur char: 'r' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 4 characters +Cur char: '-' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 5 characters +Cur char: 't' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 6 characters +Cur char: 'e' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 7 characters +Cur char: 'n' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 8 characters +Cur char: ' ' +Looking to move from state: 1 Done with NFA at pos: 9 -Returning token: 'other-ten' - - Current character: ' ' at 3:10 -Looking for string literal match of kind:1 token image: ' ' - Current character: ' ' - Currently matched the first: 1 chars as kind: 1,with image: +Returning token: 'other-ten' + Current input char: ' ' at 3:10 +Looking for string literal match of kind: 1 " " +Cur char: ' ' +Currently matched the first: 1 chars as kind: 1 " " No NFA state at pos: 2 -Found a SKIP match. - - Current character: 'I' at 3:11 +Found a SKIP match + Current input char: 'I' at 3:11 No string literal start with char: 'I' Starting NFA with start state: 0 - Current character: 'I' -Looking to move from state: 0 for: -state=0 vectorindex=1 bitpattern=512 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 0 characters. - Current character: 'n' -Looking to move from state: 1 for: -state=1 vectorindex=1 bitpattern=70368744177664 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 1 characters. - Current character: 't' -Looking to move from state: 1 for: -state=1 vectorindex=1 bitpattern=4503599627370496 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 2 characters. - Current character: '2' -Looking to move from state: 1 for: -state=1 vectorindex=0 bitpattern=1125899906842624 jjChars[state][vectorIndex]=287984085547089920 -Found a match of kind:9; kind: using the first: 3 characters. - Current character: ' ' -Looking to move from state: 1 for: -state=1 vectorindex=0 bitpattern=8192 jjChars[state][vectorIndex]=287984085547089920 +Cur char: 'I' +Looking to move from state: 0 +Found a match of kind: 9 [] using the first: 0 characters +Cur char: 'n' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 1 characters +Cur char: 't' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 2 characters +Cur char: '2' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 3 characters +Cur char: ' ' +Looking to move from state: 1 Done with NFA at pos: 4 -Returning token: 'Int2' - - Current character: ' ' at 3:15 -Looking for string literal match of kind:4 token image: '\r' - Current character: ' ' - Currently matched the first: 1 chars as kind: 4,with image: \r +Returning token: 'Int2' + Current input char: ' ' at 3:15 +Looking for string literal match of kind: 4 "\r" +Cur char: ' ' +Currently matched the first: 1 chars as kind: 4 "\r" No NFA state at pos: 2 -Found a SKIP match. - - Current character: ' +Found a SKIP match + Current input char: ' ' at 3:16 -Looking for string literal match of kind:3 token image: '\n' - Current character: ' +Looking for string literal match of kind: 3 "\n" +Cur char: ' ' - Currently matched the first: 1 chars as kind: 3,with image: \n +Currently matched the first: 1 chars as kind: 3 "\n" No NFA state at pos: 2 -Found a SKIP match. - - Current character: ' ' at 4:1 -Looking for string literal match of kind:4 token image: '\r' - Current character: ' ' - Currently matched the first: 1 chars as kind: 4,with image: \r +Found a SKIP match + Current input char: ' ' at 4:1 +Looking for string literal match of kind: 4 "\r" +Cur char: ' ' +Currently matched the first: 1 chars as kind: 4 "\r" No NFA state at pos: 2 -Found a SKIP match. - - Current character: ' +Found a SKIP match + Current input char: ' ' at 4:2 -Looking for string literal match of kind:3 token image: '\n' - Current character: ' +Looking for string literal match of kind: 3 "\n" +Cur char: ' ' - Currently matched the first: 1 chars as kind: 3,with image: \n -Found a SKIP match. +Currently matched the first: 1 chars as kind: 3 "\n" +Found a SKIP match Reached EOF at 4:2 Input file parsed successfully diff --git a/bugs/bug001/files/clc2.exp_err b/bugs/bug001/files/clc2.exp_err index e1e95d2..d2bff96 100644 --- a/bugs/bug001/files/clc2.exp_err +++ b/bugs/bug001/files/clc2.exp_err @@ -1,149 +1,106 @@ - - Current character: 'a' at 1:1 + Current input char: 'a' at 1:1 No string literal start with char: 'a' Starting NFA with start state: 0 - Current character: 'a' -Looking to move from state: 0 for: -state=0 vectorindex=1 bitpattern=8589934592 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 0 characters. - Current character: 'a' -Looking to move from state: 1 for: -state=1 vectorindex=1 bitpattern=8589934592 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 1 characters. - Current character: ' ' -Looking to move from state: 1 for: -state=1 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=287984085547089920 +Cur char: 'a' +Looking to move from state: 0 +Found a match of kind: 9 [] using the first: 0 characters +Cur char: 'a' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 1 characters +Cur char: ' ' +Looking to move from state: 1 Done with NFA at pos: 2 -Returning token: 'aa' - - Current character: ' ' at 1:3 -Looking for string literal match of kind:1 token image: ' ' - Current character: ' ' - Currently matched the first: 1 chars as kind: 1,with image: +Returning token: 'aa' + Current input char: ' ' at 1:3 +Looking for string literal match of kind: 1 " " +Cur char: ' ' +Currently matched the first: 1 chars as kind: 1 " " No NFA state at pos: 2 -Found a SKIP match. - - Current character: '-' at 1:4 -Looking for string literal match of kind:7 token image: '--' - Current character: '-' - Current character: '-' - Currently matched the first: 2 chars as kind: 7,with image: -- +Found a SKIP match + Current input char: '-' at 1:4 +Looking for string literal match of kind: 7 "--" +Cur char: '-' +Cur char: '-' +Currently matched the first: 2 chars as kind: 7 "--" No NFA state at pos: 3 -Found a SKIP match. - - Current character: ' ' at 1:6 +Found a SKIP match + Current input char: ' ' at 1:6 No string literal start with char: ' ' Starting NFA with start state: 9 - Current character: ' ' -Looking to move from state: 6 for: -state=6 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=35184372088832 -Looking to move from state: 5 for: -state=5 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=9216 -Looking to move from state: 4 for: -state=4 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=8192 -Looking to move from state: 2 for: -state=2 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=18446708889337453567 -Found a match of kind:8; kind: using the first: 0 characters. -Looking to move from state: 9 for: -state=9 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=0 - Current character: 'o' -Looking to move from state: 6 for: -state=6 vectorindex=1 bitpattern=140737488355328 jjChars[state][vectorIndex]=0 -Looking to move from state: 5 for: -state=5 vectorindex=1 bitpattern=140737488355328 jjChars[state][vectorIndex]=0 -Looking to move from state: 4 for: -state=4 vectorindex=1 bitpattern=140737488355328 jjChars[state][vectorIndex]=0 -Looking to move from state: 2 for: -state=2 vectorindex=1 bitpattern=140737488355328 jjChars[state][vectorIndex]=18446744073709551615 -Found a match of kind:8; kind: using the first: 1 characters. - Current character: '-' -Looking to move from state: 6 for: -state=6 vectorindex=0 bitpattern=35184372088832 jjChars[state][vectorIndex]=35184372088832 -Looking to move from state: 5 for: -state=5 vectorindex=0 bitpattern=35184372088832 jjChars[state][vectorIndex]=9216 -Looking to move from state: 4 for: -state=4 vectorindex=0 bitpattern=35184372088832 jjChars[state][vectorIndex]=8192 -Looking to move from state: 2 for: -state=2 vectorindex=0 bitpattern=35184372088832 jjChars[state][vectorIndex]=18446708889337453567 - Current character: 'i' -Looking to move from state: 8 for: -state=8 vectorindex=1 bitpattern=2199023255552 jjChars[state][vectorIndex]=0 -Looking to move from state: 7 for: -state=7 vectorindex=1 bitpattern=2199023255552 jjChars[state][vectorIndex]=0 -Looking to move from state: 5 for: -state=5 vectorindex=1 bitpattern=2199023255552 jjChars[state][vectorIndex]=0 -Looking to move from state: 2 for: -state=2 vectorindex=1 bitpattern=2199023255552 jjChars[state][vectorIndex]=18446744073709551615 -Found a match of kind:8; kind: using the first: 3 characters. - Current character: ' ' -Looking to move from state: 6 for: -state=6 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=35184372088832 -Looking to move from state: 5 for: -state=5 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=9216 -Looking to move from state: 4 for: -state=4 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=8192 -Looking to move from state: 2 for: -state=2 vectorindex=0 bitpattern=4294967296 jjChars[state][vectorIndex]=18446708889337453567 -Found a match of kind:8; kind: using the first: 4 characters. - Current character: '-' -Looking to move from state: 6 for: -state=6 vectorindex=0 bitpattern=35184372088832 jjChars[state][vectorIndex]=35184372088832 -Looking to move from state: 5 for: -state=5 vectorindex=0 bitpattern=35184372088832 jjChars[state][vectorIndex]=9216 -Looking to move from state: 4 for: -state=4 vectorindex=0 bitpattern=35184372088832 jjChars[state][vectorIndex]=8192 -Looking to move from state: 2 for: -state=2 vectorindex=0 bitpattern=35184372088832 jjChars[state][vectorIndex]=18446708889337453567 - Current character: '-' -Looking to move from state: 8 for: -state=8 vectorindex=0 bitpattern=35184372088832 jjChars[state][vectorIndex]=35184372088832 -Found a match of kind:8; kind: using the first: 6 characters. -Looking to move from state: 7 for: -state=7 vectorindex=0 bitpattern=35184372088832 jjChars[state][vectorIndex]=8192 -Looking to move from state: 5 for: -state=5 vectorindex=0 bitpattern=35184372088832 jjChars[state][vectorIndex]=9216 -Looking to move from state: 2 for: -state=2 vectorindex=0 bitpattern=35184372088832 jjChars[state][vectorIndex]=18446708889337453567 +Cur char: ' ' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 0 characters +Looking to move from state: 9 +Cur char: 'o' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 1 characters +Cur char: '-' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Cur char: 'i' +Looking to move from state: 8 +Looking to move from state: 7 +Looking to move from state: 5 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 3 characters +Cur char: ' ' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Found a match of kind: 8 [] using the first: 4 characters +Cur char: '-' +Looking to move from state: 6 +Looking to move from state: 5 +Looking to move from state: 4 +Looking to move from state: 2 +Cur char: '-' +Looking to move from state: 8 +Found a match of kind: 8 [] using the first: 6 characters +Looking to move from state: 7 +Looking to move from state: 5 +Looking to move from state: 2 Done with NFA at pos: 6 -Found a SKIP match. - - Current character: ' ' at 1:13 -Looking for string literal match of kind:1 token image: ' ' - Current character: ' ' - Currently matched the first: 1 chars as kind: 1,with image: +Found a SKIP match + Current input char: ' ' at 1:13 +Looking for string literal match of kind: 1 " " +Cur char: ' ' +Currently matched the first: 1 chars as kind: 1 " " No NFA state at pos: 2 -Found a SKIP match. - - Current character: 'b' at 1:14 +Found a SKIP match + Current input char: 'b' at 1:14 No string literal start with char: 'b' Starting NFA with start state: 0 - Current character: 'b' -Looking to move from state: 0 for: -state=0 vectorindex=1 bitpattern=17179869184 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 0 characters. - Current character: 'b' -Looking to move from state: 1 for: -state=1 vectorindex=1 bitpattern=17179869184 jjChars[state][vectorIndex]=576460743847706622 -Found a match of kind:9; kind: using the first: 1 characters. - Current character: ' ' -Looking to move from state: 1 for: -state=1 vectorindex=0 bitpattern=8192 jjChars[state][vectorIndex]=287984085547089920 +Cur char: 'b' +Looking to move from state: 0 +Found a match of kind: 9 [] using the first: 0 characters +Cur char: 'b' +Looking to move from state: 1 +Found a match of kind: 9 [] using the first: 1 characters +Cur char: ' ' +Looking to move from state: 1 Done with NFA at pos: 2 -Returning token: 'bb' - - Current character: ' ' at 1:16 -Looking for string literal match of kind:4 token image: '\r' - Current character: ' ' - Currently matched the first: 1 chars as kind: 4,with image: \r +Returning token: 'bb' + Current input char: ' ' at 1:16 +Looking for string literal match of kind: 4 "\r" +Cur char: ' ' +Currently matched the first: 1 chars as kind: 4 "\r" No NFA state at pos: 2 -Found a SKIP match. - - Current character: ' +Found a SKIP match + Current input char: ' ' at 1:17 -Looking for string literal match of kind:3 token image: '\n' - Current character: ' +Looking for string literal match of kind: 3 "\n" +Cur char: ' ' - Currently matched the first: 1 chars as kind: 3,with image: \n -Found a SKIP match. +Currently matched the first: 1 chars as kind: 3 "\n" +Found a SKIP match Reached EOF at 1:17 Input file parsed successfully diff --git a/bugs/bug001/pom.xml b/bugs/bug001/pom.xml index a15d3d5..501b50d 100644 --- a/bugs/bug001/pom.xml +++ b/bugs/bug001/pom.xml @@ -1,7 +1,7 @@ + + org.apache.maven.plugins + maven-clean-plugin + + + clear-res + test + + clean + + + true + + + files + + *.out,*.out.html + + + + + + + + + + + org.codehaus.mojo + exec-maven-plugin + + + exec-Digest-1 + test + + exec + + + + ${project.basedir}/target/nar/${project.artifactId}-${project.version}-${nar.aol}-executable/bin/${nar.aol}/${project.artifactId}.exe + + ${project.basedir}/files/sampleMailFile.in + ${project.basedir}/files/digestFile.out + Digest + + + + + exec-Faq-2 + test + + exec + + + + ${project.basedir}/target/nar/${project.artifactId}-${project.version}-${nar.aol}-executable/bin/${nar.aol}/${project.artifactId}.exe + + 1 + ${project.basedir}/files/sampleMailFile.in + ${project.basedir}/files + Faq + + + + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + check-Digest-1 + test + + run + + + false + + + + + + + + + + + + + + + check-Faq-2 + test + + run + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/MailProcessing/src/main/cpp/DigestMain.cpp b/examples/MailProcessing/src/main/cpp/DigestMain.cpp new file mode 100644 index 0000000..4dde20d --- /dev/null +++ b/examples/MailProcessing/src/main/cpp/DigestMain.cpp @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include + +#include "JavaCC.h" +#include "ParseException.h" +#include "StreamReader.h" +#if !defined(JJ8) && !defined(JJ7) +#define JJ8 +#endif +#if defined(JJ8) +#include "DefaultCharStream.h" +#define CHARSTREAM DefaultCharStream +#elif defined(JJ7) +#include "CharStream.h" +#define CHARSTREAM CharStream +#endif + +#include "DigestMain.h" // not included in Digest.h +#include "Digest.h" +#include "DigestTokenManager.h" + +#define MYPARSER Digest +#define MYTM DigestTokenManager +#define MYENTRY MailFile + +using namespace std; + +void DigestMain::main(int argc, char *argv[]) { + if (argc != 3) { + cerr << "Error: bad number of arguments (" << argc - 1 << " instead of 2)" << endl; + cerr << "Usage: Digest infile outfile" << endl; + exit(4); + } + DigestMain dm; + dm.doMain(argc, argv); +} + +void DigestMain::doMain(int argc, char *argv[]) { + + ifstream ifs; + ofstream digpw; + + StreamReader *sr = nullptr; + CharStream *cs = nullptr; + + try { + // open files + switch (argc) { + case 3: + digpw.open(argv[2], ofstream::binary); + case 2: + ifs.open(argv[1], ifstream::binary); + } + if (ifs.is_open()) { + sr = new StreamReader(ifs); + cs = new CHARSTREAM(sr); + } else { + cerr << "Cannot open input file " << argv[1] << endl; + exit(8); + } + if (digpw.is_open()) { + } else { + cerr << "Cannot open output file " << argv[2] << endl; + exit(8); + } + + // parse + MYPARSER parser(new MYTM(cs)); + parser.setDigpw(&digpw); + digpw << "DIGEST OF RECENT MESSAGES FROM THE JAVACC MAILING LIST" << endl; + digpw << "----------------------------------------------------------------------" << endl; + digpw << endl; + digpw << "MESSAGE SUMMARY:" << endl; + digpw << endl; + digpw.flush(); + JJString buffer = parser.MYENTRY(); + if (buffer.empty()) { + digpw << "There have been no messages since the last digest posting." << endl; + digpw << endl; + digpw << "----------------------------------------------------------------------" << endl; + } else { + digpw << endl; + digpw << "----------------------------------------------------------------------" << endl; + digpw << endl; + digpw << buffer << endl; + } + digpw.flush(); + } catch (const ParseException &e) { + cerr << "Error parsing input file:" << endl; + clog << e.expectedTokenSequences << endl; + } catch (...) { + } + +// close files & others + if (ifs.is_open()) + ifs.close(); + if (digpw.is_open()) + digpw.close(); + if (cs) + delete cs; + if (sr) + delete sr; +} + +/* + package dig; + + import java.io.*; + + public class DigestMain { + + PrintWriter digpw; + + public static void main(String[] args) throws ParseException, IOException, FileNotFoundException { + if (args.length < 1) { + System.err.println("Error: bad number of arguments (" + args.length + " instead of 2)"); + System.err.println("Usage: DigestMain infile outfile"); + System.exit(4); + } + DigestMain dm = new DigestMain(); + dm.doMain(args); + } + + void doMain(String[] args) throws ParseException, IOException, FileNotFoundException { + digpw = new PrintWriter(new FileWriter(args[1])); + Digest parser = new Digest(new FileInputStream(args[0])); + parser.setDigpw(digpw); + digpw.println("DIGEST OF RECENT MESSAGES FROM THE JAVACC MAILING LIST"); + digpw.println("----------------------------------------------------------------------"); + digpw.println(""); + digpw.println("MESSAGE SUMMARY:"); + digpw.println(""); + String buffer = parser.MailFile(); + if (buffer.length() == 0) { + digpw.println("There have been no messages since the last digest posting."); + digpw.println(""); + digpw.println("----------------------------------------------------------------------"); + } else { + digpw.println(""); + digpw.println("----------------------------------------------------------------------"); + digpw.println(""); + digpw.println(buffer); + } + digpw.close(); + } + } + */ diff --git a/examples/MailProcessing/src/main/cpp/DigestMain.h b/examples/MailProcessing/src/main/cpp/DigestMain.h new file mode 100644 index 0000000..6ee33f8 --- /dev/null +++ b/examples/MailProcessing/src/main/cpp/DigestMain.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef DIGESTMAIN_H +#define DIGESTMAIN_H + +class DigestMain { + +public: + static void main(int argc, char *argv[]); + +private: + void doMain(int argc, char *argv[]); + +}; + +#endif diff --git a/examples/MailProcessing/src/main/cpp/FaqMain.cpp b/examples/MailProcessing/src/main/cpp/FaqMain.cpp new file mode 100644 index 0000000..0d92aaf --- /dev/null +++ b/examples/MailProcessing/src/main/cpp/FaqMain.cpp @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include + +#include "JavaCC.h" +#include "ParseException.h" +#include "StreamReader.h" +#if !defined(JJ8) && !defined(JJ7) +#define JJ8 +#endif +#if defined(JJ8) +#include "DefaultCharStream.h" +#define CHARSTREAM DefaultCharStream +#elif defined(JJ7) +#include "CharStream.h" +#define CHARSTREAM CharStream +#endif + +#include "Faq.h" // includes FaqMain.h +#include "FaqTokenManager.h" + +#define MYPARSER Faq +#define MYTM FaqTokenManager +#define MYENTRY MailFile + +using namespace std; + +JJString FaqMain::fix(JJString s) { + JJString retval = ""; + for (int i = 0; i < s.length(); i++) { + char c = s[i]; + if (c == '<') { + retval += "<"; + } else if (c == '>') { + retval += ">"; + } else { + retval += c; + } + } + return retval; +} + +void FaqMain::main(int argc, char *argv[]) { + if (argc != 4) { + cerr << "Error: bad number of arguments (" << argc - 1 << " instead of 3)" << endl; + cerr << "Usage: Faq index infile outdir" << endl; + exit(4); + } + + ifstream ifs; +#define ofs indexpw + ofstream ofs; + + StreamReader *sr = nullptr; + CharStream *cs = nullptr; + + try { + // open files + switch (argc) { + case 4: { + JJString dir(argv[3]); + indexpw.open(dir + "/index.out.html", ofstream::binary); + } + case 3: + ifs.open(argv[2], ifstream::binary); + case 2: + beginAt = stoi(argv[1]); + } + if (ifs.is_open()) { + sr = new StreamReader(ifs); + cs = new CHARSTREAM(sr); + } else { + cerr << "Cannot open input file " << argv[2] << endl; + exit(8); + } + if (indexpw.is_open()) { + } else { + cerr << "Cannot open output file " << argv[3] << "/index.out.html" << endl; + exit(8); + } + + // parse + indexpw << "Selected list of emails from the JavaCC mailing list" << endl; + indexpw << "

Selected list of emails from the JavaCC mailing list

" << endl; + MYPARSER parser(new MYTM(cs)); + parser.count = 0; + parser.beginAt = beginAt; + parser.outdir = outdir; + parser.indexpw = &indexpw; + parser.MYENTRY(); + } catch (const ParseException &e) { + cerr << "Error parsing input file:" << endl; + clog << e.expectedTokenSequences << endl; + } catch (...) { + } + + // close files & others + if (ifs.is_open()) + ifs.close(); + if (indexpw.is_open()) + indexpw.close(); + if (cs) + delete cs; + if (sr) + delete sr; +} + +/* + package faq; + + import java.io.*; + + public class FaqMain { + + static int count = 0; + + static int beginAt = 1; + + static String outdir; + + static PrintWriter indexpw; + + static String fix(String s) { + String retval = ""; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '<') { + retval += "<"; + } else if (c == '>') { + retval += ">"; + } else { + retval += c; + } + } + return retval; + } + + public static void main(String args[]) throws ParseException, IOException, FileNotFoundException { + if (args.length < 2) { + System.err.println("Error: bad number of arguments (" + args.length + " instead of 3)"); + System.err.println("Usage: FaqMain index infile outdir"); + System.exit(4); + } + beginAt = Integer.parseInt(args[0]); + outdir = args[2]; + indexpw = new PrintWriter(new FileWriter(outdir + "/index.out.html")); + indexpw.println("Selected list of emails from the JavaCC mailing list"); + indexpw.println("

Selected list of emails from the JavaCC mailing list

"); + Faq parser = new Faq(new FileInputStream(args[1])); + parser.MailFile(); + } + } + */ diff --git a/examples/MailProcessing/src/main/cpp/FaqMain.h b/examples/MailProcessing/src/main/cpp/FaqMain.h new file mode 100644 index 0000000..73d3771 --- /dev/null +++ b/examples/MailProcessing/src/main/cpp/FaqMain.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef FAQMAIN_H +#define FAQMAIN_H + +#include "JavaCC.h" + +#include + +using namespace std; + +class FaqMain { + +public: + + static JJString fix(JJString s); + void main(int argc, char *argv[]); + + int count; + int beginAt; + JJString outdir; + ofstream *indexpw; + +}; + +#endif + +/* + import java.io.*; + + public class FaqMain { + + static int count = 0; + + static int beginAt = 1; + + static String outdir; + + static PrintWriter indexpw; + + static String fix(String s) { + String retval = ""; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '<') { + retval += "<"; + } else if (c == '>') { + retval += ">"; + } else { + retval += c; + } + } + return retval; + } + + public static void main(String args[]) throws ParseException, IOException, FileNotFoundException { + if (args.length < 2) { + System.err.println("Error: bad number of arguments (" + args.length + " instead of 3)"); + System.err.println("Usage: FaqMain index infile outdir"); + System.exit(4); + } + beginAt = Integer.parseInt(args[0]); + outdir = args[2]; + indexpw = new PrintWriter(new FileWriter(outdir + "/index.out.html")); + indexpw.println("Selected list of emails from the JavaCC mailing list"); + indexpw.println("

Selected list of emails from the JavaCC mailing list

"); + Faq parser = new Faq(new FileInputStream(args[1])); + parser.MailFile(); + } + } + */ diff --git a/examples/MailProcessing/src/main/cpp/Mail.cpp b/examples/MailProcessing/src/main/cpp/Mail.cpp deleted file mode 100644 index dd7a357..0000000 --- a/examples/MailProcessing/src/main/cpp/Mail.cpp +++ /dev/null @@ -1,32 +0,0 @@ -int main(int argc, char **argv) { -} - -import java.io.*; - -public class Digest { - - static int count = 0; - - static String buffer = ""; - -public static void main(String args[]) throws ParseException, FileNotFoundException { - Digest parser = new Digest(new FileInputStream(args[0])); - System.out.println("DIGEST OF RECENT MESSAGES FROM THE JAVACC MAILING LIST"); - System.out.println("----------------------------------------------------------------------"); - System.out.println(""); - System.out.println("MESSAGE SUMMARY:"); - System.out.println(""); - parser.MailFile(); - if (count == 0) { - System.out.println("There have been no messages since the last digest posting."); - System.out.println(""); - System.out.println("----------------------------------------------------------------------"); - } else { - System.out.println(""); - System.out.println("----------------------------------------------------------------------"); - System.out.println(""); - System.out.println(buffer); - } - } - -} diff --git a/examples/MailProcessing/src/main/cpp/StreamReader.cpp b/examples/MailProcessing/src/main/cpp/StreamReader.cpp new file mode 100644 index 0000000..4a56bcb --- /dev/null +++ b/examples/MailProcessing/src/main/cpp/StreamReader.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include "JavaCC.h" + +class StreamReader: public ReaderStream { +public: + StreamReader(std::istream &is); + virtual ~StreamReader(); + + virtual size_t read(JJChar *buffer, int offset, size_t len); + virtual bool endOfInput(); + +private: + std::istream &is; +}; + +using namespace std; +StreamReader::StreamReader(std::istream &is) : + is(is) { + +} +StreamReader::~StreamReader() { + +} +size_t StreamReader::read(JJChar *buffer, int offset, size_t len) { + is.read(buffer + offset, len); + return is.gcount(); +} +bool StreamReader::endOfInput() { + return is.eof(); +} diff --git a/examples/MailProcessing/src/main/cpp/StreamReader.h b/examples/MailProcessing/src/main/cpp/StreamReader.h new file mode 100644 index 0000000..3b9e10e --- /dev/null +++ b/examples/MailProcessing/src/main/cpp/StreamReader.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef STREAM_READER_H_ +#define STREAM_READER_H_ + +#include +#include "JavaCC.h" + +class StreamReader: public ReaderStream { +public: + StreamReader(std::istream &is); + virtual ~StreamReader(); + + virtual size_t read(JJChar *buffer, int offset, size_t len); + virtual bool endOfInput(); + +private: + std::istream &is; +}; + +#endif diff --git a/examples/MailProcessing/src/main/cpp/main.cpp b/examples/MailProcessing/src/main/cpp/main.cpp new file mode 100644 index 0000000..550ce62 --- /dev/null +++ b/examples/MailProcessing/src/main/cpp/main.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * Not found any way to have the maven nar plugin produce more than one executable from a single + * sources structure, + * so a main() cannot be in both classes DigestMain and FaqMain, so we put it outside + * and made it direct to the right Main. + */ +#include "JavaCC.h" +#include "DigestMain.h" +#include "FaqMain.h" + +void usage() { + cerr << "Usage: main (infile outfile Digest | index infile outdir Faq)" << endl; + exit(4); +} + +int main(int argc, char *argv[]) { + +// cerr << "argc = " << argc << ", argv[argc-1] = " << argv[argc - 1] << endl; + + if (argc < 3) { + cerr << "Error: bad number of arguments (" << argc << ")" << endl; + usage(); + } + JJString pg(argv[argc - 1]); + if (pg == "Digest") { + DigestMain::main(argc - 1, argv); + } else if (pg == "Faq") { + FaqMain faqmain; + faqmain.main(argc - 1, argv); + } else { + cerr << "Error: bad program name (" << pg << ")" << endl; + usage(); + } + return 0; +} diff --git a/examples/MailProcessing/src/main/javacc/Digest.jj b/examples/MailProcessing/src/main/javacc/Digest.jj index 448b000..d904b7c 100644 --- a/examples/MailProcessing/src/main/javacc/Digest.jj +++ b/examples/MailProcessing/src/main/javacc/Digest.jj @@ -1,4 +1,6 @@ -/* Copyright (c) 2006, Sun Microsystems, Inc. +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,69 +27,107 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ - +options { + STATIC = false; // not JavaCC's default; will not change much in C++ + // for ofstream + PARSER_INCLUDE = ""; +} PARSER_BEGIN(Digest) -PARSER_END(Digest) +private: + int count = 0; + std::ofstream *digpw; + +public: + void setDigpw(std::ofstream *aDigpw) { + digpw = aDigpw; + } -// PARSER SPECIFICATIONS BEGIN HERE +// care: the line package, even if in comment, will be used! +/* +pac-kage dig; // different from Faq, to allow different helper files -void MailFile() : - { - } +import java.io.*; + +public class Digest { + private int count = 0; + PrintWriter digpw; + + void setDigpw(final PrintWriter aDigpw) { + digpw = aDigpw; + } +} +*/ + +PARSER_END(Digest) + +JJString MailFile() : +{ + JJString mail, mails = ""; +} { ( - { - count++; - } - MailMessage() + { count++; } + mail = MailMessage() + { + mails += mail; + std::cout << count << "."; + std::cout.flush(); + } )* + { + std::cout << std::endl; + return mails; + } } -void MailMessage() : - { - Token subj=null, from=null, date=null, body; - } +JJString MailMessage() : +{ + Token *subj, *from, *date,* body; + subj = nullptr; + from = nullptr; + date = nullptr; + JJString buffer = ""; +} { - ( subj= | from= | date= )+ - { - std::cout << (count + ". " + ((subj==null) ? "no subject" : subj.image)) << std::endl; - buffer += "\n"; - buffer += "Message " + count + ":\n"; - buffer += "\n"; - buffer += "Subject: " + ((subj==null) ? "no subject" : subj.image) + "\n"; - buffer += "From: " + ((from==null) ? "" : from.image) + "\n"; - buffer += "Date: " + ((date==null) ? "" : date.image) + "\n"; - buffer += "\n"; - } - ( body= - { - buffer += body.image; - } + ( subj = | from = | date = )+ + { + *digpw << count << ". " << (subj == nullptr ? "no subject" : subj->image()) << std::endl; + buffer += "\n"; + buffer += "Message " + std::to_string(count) + ":\n"; + buffer += "\n"; + buffer += "Subject: " + (subj == nullptr ? "no subject" : subj->image()) + "\n"; + buffer += "From: " + (from == nullptr ? "" : from->image()) + "\n"; + buffer += "Date: " + (date == nullptr ? "" : date->image()) + "\n"; + buffer += "\n"; + } + ( + body = + { + buffer += body->image(); + } )* - { - buffer += "\n"; - buffer += "----------------------------------------------------------------------\n"; - } + { + buffer += "\n"; + buffer += "----------------------------------------------------------------------\n"; + return buffer; + } } - -// LEXICAL SPECIFICATIONS BEGIN HERE - -TOKEN: +TOKEN : { - <#EOL: "\n" | "\r" | "\r\n"> + < #EOL : "\n" | "\r" | "\r\n" > | - <#TWOEOLS: (("\n"|"\r\n") ) | ("\r\r" [ "\n" ])> + < #TWOEOLS : ( ( "\n" | "\r\n" ) ) | ( "\r\r" [ "\n" ] )> | - <#NOT_EOL: ~["\n","\r"]> + < #NOT_EOL : ~[ "\n", "\r" ] > } -SKIP: +SKIP : { < "*** EOOH ***" > : MAILHEADER | @@ -95,9 +135,9 @@ SKIP: } -SKIP: +SKIP : { - <_TWOEOLS: > : MAILBODY + < _TWOEOLS : > : MAILBODY // We cannot have just a reference to a regular expression in a // lexical specification - i.e., we cannot simply have . | @@ -111,45 +151,45 @@ SKIP: } -TOKEN: +TOKEN : { - )+> + < SUBJECT : ( )+ > } -SKIP: +SKIP : { - <_EOL1: > : MAILHEADER + < _EOL1 : > : MAILHEADER } -TOKEN: +TOKEN : { - )+> + < FROM : ( )+ > } SKIP: { - <_EOL2: > : MAILHEADER + < _EOL2 : > : MAILHEADER } TOKEN: { - )+> + < DATE : ( )+ > } -SKIP: +SKIP : { - <_EOL3: > : MAILHEADER + < _EOL3 : > : MAILHEADER } -TOKEN: +TOKEN : { - > -| - : DEFAULT + < BODY : ( ~["\n", "\r", "\u001f" ] )* > +| + < END : "\u001f" > : DEFAULT } diff --git a/examples/MailProcessing/src/main/javacc/Faq.jj b/examples/MailProcessing/src/main/javacc/Faq.jj index 670eacd..134848b 100644 --- a/examples/MailProcessing/src/main/javacc/Faq.jj +++ b/examples/MailProcessing/src/main/javacc/Faq.jj @@ -1,4 +1,6 @@ -/* Copyright (c) 2006, Sun Microsystems, Inc. +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,139 +27,116 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ - +options { + STATIC = true; // JavaCC's default + // for decl of FaqMain.fix(); contains 'include JavaCC.h' & 'using namespace std' + PARSER_INCLUDE = "FaqMain.h"; +} PARSER_BEGIN(Faq) -/* -import java.io.*; - -public class Faq { - - static int count = 0; - - static int beginAt = 1; - static PrintWriter indstr; - - static { - try { - indstr = new PrintWriter(new FileWriter("index.html")); - indstr.println("Selected list of emails from the JavaCC mailing list"); - indstr.println("

Selected list of emails from the JavaCC mailing list

"); - } catch (IOException e) { - throw new Error(); - } - } +public: + int count = 0; + int beginAt; + JJString outdir; + ofstream *indexpw; - static String fix(String s) { - String retval = ""; - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - if (c == '<') { - retval += "<"; - } else if (c == '>') { - retval += ">"; - } else { - retval += c; - } - } - return retval; - } +// care: the line package, even if in comment, will be used! +/* +pac-kage faq; // different from Digest, to allow different helper files - public static void main(String args[]) throws ParseException, FileNotFoundException { - if (args.length >= 1) { - beginAt = Integer.parseInt(args[0]); - } - Faq parser = new Faq(new FileInputStream(args[1])); - parser.MailFile(); - } +import java.io.*; +public class Faq { + static int count = FaqMain.count; + static int beginAt = FaqMain.beginAt; + static String outdir = FaqMain.outdir; + static PrintWriter indexpw = FaqMain.indexpw; } */ -PARSER_END(Faq) - -// PARSER SPECIFICATIONS BEGIN HERE +PARSER_END(Faq) void MailFile() : - { - } +{} { ( - { - count++; - } + { count++; } MailMessage() - { - System.out.print(count + "."); - System.out.flush(); - } + { + cout << (count + "."); + cout.flush(); + } )* - { - System.out.println(""); - indstr.close(); - } + { + cout << endl; + indexpw->close(); + } } void MailMessage() : - { - PrintWriter msgstr = null; - Token subj=null, from=null, date=null, body; - if (count >= beginAt) { - try { - msgstr = new PrintWriter(new FileWriter(count + ".html")); - } catch (IOException e) { - throw new Error(); - } - } - } { - ( subj= | from= | date= )+ - { - indstr.print(""); - if (subj == null) { - indstr.println("no subject
"); - } else { - indstr.println(fix(subj.image) + "
"); - } - if (count >= beginAt) { - msgstr.println("" + ((subj==null) ? "no subject" : fix(subj.image)) + ""); - msgstr.println("Subject: " + ((subj==null) ? "no subject" : fix(subj.image)) + "
"); - msgstr.println("From: " + ((from==null) ? "" : fix(from.image)) + "
"); - msgstr.println("Date: " + ((date==null) ? "" : fix(date.image)) + "
"); - msgstr.println("
"); - } - } - ( body= - { - if (count >= beginAt) { - msgstr.print(fix(body.image) + "
"); - } - } + ofstream msgpw; + Token *subj, *from, *date, *body; + subj = nullptr; + from = nullptr; + date = nullptr; + if (count >= beginAt) { + msgpw.open(to_string(count) + ".html"); + if (!msgpw.is_open()) { + cerr << "Cannot open output file " << count << ".html" << endl; + exit(4); + } + } else { + cerr << "count (" << count << ") < beginAt (" << beginAt << ")" << endl; + return; + } +} +{ + ( subj = | from = | date = )+ + { + *indexpw << ""; + if (subj == nullptr) { + *indexpw << "no subject
" << endl; + } else { + *indexpw << FaqMain::fix(subj->image()) << "
" << endl; + } + if (count >= beginAt) { + msgpw << "" + (subj == nullptr ? "no subject" : FaqMain::fix(subj->image())) + "" << endl; + msgpw << "Subject: " + (subj == nullptr ? "no subject" : FaqMain::fix(subj->image())) + "
" << endl; + msgpw << "From: " + (from == nullptr ? "" : FaqMain::fix(from->image())) + "
" << endl; + msgpw << "Date: " + (date == nullptr ? "" : FaqMain::fix(date->image())) + "
" << endl; + msgpw << "
" << endl; + } + } + ( + body = + { + if (count >= beginAt) { + msgpw << (FaqMain::fix(body->image()) + "
"); + } + } )* - { - if (count >= beginAt) { - msgstr.close(); - } - } + { + if (msgpw) { + msgpw.close(); + } + } } - -// LEXICAL SPECIFICATIONS BEGIN HERE - TOKEN: { <#EOL: "\n" | "\r" | "\r\n"> | - <#TWOEOLS: (("\n"|"\r\n") ) | ("\r\r" [ "\n" ])> + <#TWOEOLS: ( ( "\n" | "\r\n" ) ) | ( "\r\r" [ "\n" ] )> | - <#NOT_EOL: ~["\n","\r"]> + <#NOT_EOL: ~[ "\n", "\r" ]> } -SKIP: +SKIP : { < "*** EOOH ***" > : MAILHEADER | @@ -165,9 +144,9 @@ SKIP: } -SKIP: +SKIP : { - <_TWOEOLS: > : MAILBODY + < _TWOEOLS : > : MAILBODY // We cannot have just a reference to a regular expression in a // lexical specification - i.e., we cannot simply have . | @@ -181,45 +160,45 @@ SKIP: } -TOKEN: +TOKEN : { - )+> + < SUBJECT : ( )+ > } -SKIP: +SKIP : { - <_EOL1: > : MAILHEADER + < _EOL1 : > : MAILHEADER } -TOKEN: +TOKEN : { - )+> + < FROM : ( )+ > } SKIP: { - <_EOL2: > : MAILHEADER + < _EOL2 : > : MAILHEADER } TOKEN: { - )+> + < DATE : ( )+ > } -SKIP: +SKIP : { - <_EOL3: > : MAILHEADER + < _EOL3 : > : MAILHEADER } -TOKEN: +TOKEN : { - > -| - : DEFAULT + < BODY : ( ~["\n", "\r", "\u001f" ] )* > +| + < END : "\u001f" > : DEFAULT } diff --git a/examples/UserTokenManager/pom.xml b/examples/UserTokenManager/pom.xml index 659c5ae..8088888 100644 --- a/examples/UserTokenManager/pom.xml +++ b/examples/UserTokenManager/pom.xml @@ -1,7 +1,7 @@ + fixing this would mean to rewrite the grammar... or the generator + So the module is commented out here; see also the project's base pom.xml' --> dtd ecma diff --git a/grammars/settings.xml b/grammars/settings.xml index e869ed0..5e2e31d 100644 --- a/grammars/settings.xml +++ b/grammars/settings.xml @@ -1,7 +1,7 @@ + + true + + + + + + + + + + com.github.maven-nar + nar-maven-plugin + true + + + + + + @@ -119,7 +150,7 @@ THE POSSIBILITY OF SUCH DAMAGE. bugs bugs/settings.xml - true + false @@ -132,20 +163,41 @@ THE POSSIBILITY OF SUCH DAMAGE. examples examples/settings.xml - true + false + - integration-test-cpp-grammars + integration-test-cpp-grammars-cobol-install install + + + + integration-test-cpp-grammars-cobol + run grammars grammars/settings.xml true + cobol + + + + integration-test-cpp-grammars-nocobol + + run + + + grammars + grammars/settings.xml + false + cobol/pom.xml diff --git a/src/main/java/org/javacc/cpp/CppCodeBuilder.java b/src/main/java/org/javacc/cpp/CppCodeBuilder.java index e753439..528621d 100644 --- a/src/main/java/org/javacc/cpp/CppCodeBuilder.java +++ b/src/main/java/org/javacc/cpp/CppCodeBuilder.java @@ -1,17 +1,41 @@ - +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ package org.javacc.cpp; +import java.io.File; import org.javacc.parser.CodeGeneratorSettings; import org.javacc.parser.Context; import org.javacc.parser.Options; import org.javacc.utils.CodeBuilder; -import java.io.File; - - -/** - * The {@link CppCodeBuilder} class. - */ +/** The {@link CppCodeBuilder} class. */ class CppCodeBuilder extends CodeBuilder { private enum Buffer { @@ -20,12 +44,11 @@ private enum Buffer { Static; } - private final boolean headeOnly; - private final StringBuffer mainBuffer = new StringBuffer(); + private final boolean headeOnly; + private final StringBuffer mainBuffer = new StringBuffer(); private final StringBuffer includeBuffer = new StringBuffer(); private final StringBuffer staticsBuffer = new StringBuffer(); - private Buffer kind; /** @@ -33,15 +56,14 @@ private enum Buffer { * * @param options */ - private CppCodeBuilder(Context context, CodeGeneratorSettings options, boolean headeOnly) { + private CppCodeBuilder( + final Context context, final CodeGeneratorSettings options, final boolean headeOnly) { super(context, options); this.headeOnly = headeOnly; kind = headeOnly ? Buffer.Include : Buffer.Main; } - /** - * Get the {@link StringBuffer} - */ + /** Get the {@link StringBuffer} */ @Override protected final StringBuffer getBuffer() { switch (kind) { @@ -55,13 +77,16 @@ protected final StringBuffer getBuffer() { } /** - * Generate a class with a given name, an array of superclass and another - * array of super interfaes + * Generate a class with a given name, an array of superclass and another array of super interfaes */ - void genClassStart(String mod, String name, String[] superClasses, String[] superInterfaces) { + void genClassStart( + final String mod, + final String name, + final String[] superClasses, + final String[] superInterfaces) { print("class "); if (!Options.getLibrary().isEmpty()) { - print(name.toUpperCase() + "_API "); + print(name.toUpperCase() + "_API "); } print(name); if ((superClasses.length > 0) || (superInterfaces.length > 0)) { @@ -70,14 +95,15 @@ void genClassStart(String mod, String name, String[] superClasses, String[] supe genCommaSeperatedString(superClasses); genCommaSeperatedString(superInterfaces); - println("{"); + println(" {"); + println(); println("public:"); } @Override protected final void build() { - String includeFileName = getFile().getName().replace(".cc", ".h"); - File includeFile = new File(getFile().getParentFile(), includeFileName); + final String includeFileName = getFile().getName().replace(".cc", ".h"); + final File includeFile = new File(getFile().getParentFile(), includeFileName); fixupLongLiterals(includeBuffer); store(includeFile, includeBuffer); @@ -94,17 +120,25 @@ protected final void build() { store(getFile(), mainBuffer); } - void generateMethodDefHeader(String modsAndRetType, String className, String nameAndParams) { + void generateMethodDefHeader( + final String modsAndRetType, final String className, final String nameAndParams) { generateMethodDefHeader(modsAndRetType, className, nameAndParams, null); } - void generateMethodDefHeader(String qualifiedModsAndRetType, String className, String nameAndParams, - String exceptions) { + void generateMethodDefHeader( + String qualifiedModsAndRetType, + final String className, + final String nameAndParams, + final String exceptions) { // for C++, we generate the signature in the header file and body in main file - includeBuffer.append(qualifiedModsAndRetType + " " + nameAndParams); + includeBuffer.append(" "); + if (qualifiedModsAndRetType != null && qualifiedModsAndRetType.length() > 0) { + includeBuffer.append(qualifiedModsAndRetType).append(' '); + } + includeBuffer.append(nameAndParams); // if (exceptions != null) // includeBuffer.append(" throw(" + exceptions + ")"); - includeBuffer.append(";\n"); + includeBuffer.append(";\n\n"); String modsAndRetType = null; int i = qualifiedModsAndRetType.lastIndexOf(':'); @@ -124,19 +158,19 @@ void generateMethodDefHeader(String qualifiedModsAndRetType, String className, S qualifiedModsAndRetType = qualifiedModsAndRetType.substring(i + "virtual".length()); } } - String qualifierClass = (className == null) ? "" : className + "::"; - mainBuffer.append("\n" + qualifiedModsAndRetType + " " + qualifierClass + nameAndParams); + final String qualifierClass = (className == null) ? "" : className + "::"; + mainBuffer.append((qualifiedModsAndRetType + " " + qualifierClass + nameAndParams).trim()); // if (exceptions != null) // mainBuffer.append(" throw( " + exceptions + ")"); switchToMainFile(); } // HACK - private void fixupLongLiterals(StringBuffer sb) { + private void fixupLongLiterals(final StringBuffer sb) { for (int i = 0; i < (sb.length() - 1); i++) { // int beg = i; - char c1 = sb.charAt(i); - char c2 = sb.charAt(i + 1); + final char c1 = sb.charAt(i); + final char c2 = sb.charAt(i + 1); if (Character.isDigit(c1) || ((c1 == '0') && (c2 == 'x'))) { i += c1 == '0' ? 2 : 1; while (CppCodeBuilder.isHexDigit(sb.charAt(i))) { @@ -158,53 +192,54 @@ private void fixupLongLiterals(StringBuffer sb) { * * @param c */ - private static boolean isHexDigit(char c) { + private static boolean isHexDigit(final char c) { return ((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'f')) || ((c >= 'A') && (c <= 'F')); } - private final void genCommaSeperatedString(String[] strings) { + private final void genCommaSeperatedString(final String[] strings) { for (int i = 0; i < strings.length; i++) { if (i > 0) { print(", "); } - print(strings[i]); } } - // Used by the CPP code generatror - final CppCodeBuilder printCharArray(String s) { + final CppCodeBuilder printCharArray(final String s) { print("{"); - for (char c : s.toCharArray()) { + for (final char c : s.toCharArray()) { print("0x" + Integer.toHexString(c) + ", "); } print("0}"); return this; } - public void printLiteralArray(String varName, String[] arr) { + public void printLiteralArray(final String varName, final String[] arr) { // First generate char array vars for (int i = 0; i < arr.length; i++) { println("static const JJChar " + varName + "_arr_" + i + "[] = "); + print(" "); printCharArray(arr[i]); + println(); println(";"); + println(); } println("static const JJString " + varName + "[] = {"); for (int i = 0; i < arr.length; i++) { - print(varName + "_arr_" + i); + print(" " + varName + "_arr_" + i); if ((i + 1) < arr.length) { print(", "); } println(); } println("};"); + println(); } - @Override - public final String escapeToUnicode(String text) { + public final String escapeToUnicode(final String text) { return text; } @@ -225,7 +260,7 @@ void switchToStaticsFile() { * * @param options */ - static CppCodeBuilder of(Context context, CodeGeneratorSettings options) { + static CppCodeBuilder of(final Context context, final CodeGeneratorSettings options) { return new CppCodeBuilder(context, options, false); } @@ -234,7 +269,7 @@ static CppCodeBuilder of(Context context, CodeGeneratorSettings options) { * * @param options */ - static CppCodeBuilder ofHeader(Context context, CodeGeneratorSettings options) { + static CppCodeBuilder ofHeader(final Context context, final CodeGeneratorSettings options) { return new CppCodeBuilder(context, options, true); } } diff --git a/src/main/java/org/javacc/cpp/CppCodeGenerator.java b/src/main/java/org/javacc/cpp/CppCodeGenerator.java index 94fba5d..e03f009 100644 --- a/src/main/java/org/javacc/cpp/CppCodeGenerator.java +++ b/src/main/java/org/javacc/cpp/CppCodeGenerator.java @@ -1,8 +1,35 @@ - +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ package org.javacc.cpp; import java.io.File; - import org.javacc.jjtree.DefaultJJTreeVisitor; import org.javacc.jjtree.JJTreeContext; import org.javacc.parser.CodeGenerator; @@ -16,177 +43,180 @@ public class CppCodeGenerator implements CodeGenerator { static final boolean IS_DEBUG = true; - /** - * The name of the C# code generator. - */ + /** The name of the C# code generator. */ @Override public final String getName() { return "C++"; } - /** - * Generate any other support files you need. - */ + /** Generate any other support files you need. */ @Override - public final boolean generateHelpers(Context context, CodeGeneratorSettings settings, TokenizerData tokenizerData) { + public final boolean generateHelpers( + final Context context, + final CodeGeneratorSettings settings, + final TokenizerData tokenizerData) { try { - try (CppCodeBuilder builder = CppCodeBuilder.ofHeader(context, settings)) { - builder.setFile(new File((String) settings.get("OUTPUT_DIRECTORY"), "CharStream.h")); - builder.addTools(JavaCCGlobals.toolName); - - builder.switchToIncludeFile(); - builder.printTemplate("/templates/cpp/CharStream.h.template"); - } - - try (CppCodeBuilder builder = CppCodeBuilder.of(context, settings)) { - builder.setFile(new File((String) settings.get("OUTPUT_DIRECTORY"), "DefaultCharStream.cc")); - builder.addTools(JavaCCGlobals.toolName); - builder.addOption(Options.USEROPTION__STATIC, Options.USEROPTION__SUPPORT_CLASS_VISIBILITY_PUBLIC); - - builder.printTemplate("/templates/cpp/DefaultCharStream.cc.template"); - builder.switchToIncludeFile(); - builder.printTemplate("/templates/cpp/DefaultCharStream.h.template"); - } - - try (CppCodeBuilder builder = CppCodeBuilder.of(context, settings)) { - builder.setFile(new File((String) settings.get("OUTPUT_DIRECTORY"), "TokenManagerError.cc")); - builder.addTools(JavaCCGlobals.toolName); - builder.addOption(Options.USEROPTION__STATIC, Options.USEROPTION__SUPPORT_CLASS_VISIBILITY_PUBLIC); - - builder.printTemplate("/templates/cpp/TokenManagerError.cc.template"); - builder.switchToIncludeFile(); - builder.printTemplate("/templates/cpp/TokenManagerError.h.template"); + try (CppCodeBuilder ccb = CppCodeBuilder.ofHeader(context, settings)) { + ccb.setFile(new File((String) settings.get("OUTPUT_DIRECTORY"), "CharStream.h")); + ccb.addTools(JavaCCGlobals.toolName); + + ccb.switchToIncludeFile(); + ccb.printTemplate("/templates/cpp/CharStream.h.template"); } - try (CppCodeBuilder builder = CppCodeBuilder.of(context, settings)) { - builder.setFile(new File((String) settings.get("OUTPUT_DIRECTORY"), "ParseException.cc")); - builder.addTools(JavaCCGlobals.toolName); - builder.addOption(Options.USEROPTION__STATIC, Options.USEROPTION__SUPPORT_CLASS_VISIBILITY_PUBLIC); + try (CppCodeBuilder ccb = CppCodeBuilder.of(context, settings)) { + ccb.setFile(new File((String) settings.get("OUTPUT_DIRECTORY"), "DefaultCharStream.cc")); + ccb.addTools(JavaCCGlobals.toolName); + ccb.addOption( + Options.UO__STATIC, Options.UO__SUPPORT_CLASS_VISIBILITY_PUBLIC); - builder.printTemplate("/templates/cpp/ParseException.cc.template"); - builder.switchToIncludeFile(); - builder.printTemplate("/templates/cpp/ParseException.h.template"); + ccb.printTemplate("/templates/cpp/DefaultCharStream.cc.template"); + ccb.switchToIncludeFile(); + ccb.printTemplate("/templates/cpp/DefaultCharStream.h.template"); } - try (CppCodeBuilder builder = CppCodeBuilder.ofHeader(context, settings)) { - builder.setFile(new File((String) settings.get("OUTPUT_DIRECTORY"), "TokenManager.h")); - builder.addTools(JavaCCGlobals.toolName); - builder.addOption(Options.USEROPTION__STATIC, Options.USEROPTION__SUPPORT_CLASS_VISIBILITY_PUBLIC); + try (CppCodeBuilder ccb = CppCodeBuilder.of(context, settings)) { + ccb.setFile(new File((String) settings.get("OUTPUT_DIRECTORY"), "TokenManagerError.cc")); + ccb.addTools(JavaCCGlobals.toolName); + ccb.addOption( + Options.UO__STATIC, Options.UO__SUPPORT_CLASS_VISIBILITY_PUBLIC); - builder.printTemplate("/templates/cpp/TokenManager.h.template"); + ccb.printTemplate("/templates/cpp/TokenManagerError.cc.template"); + ccb.switchToIncludeFile(); + ccb.printTemplate("/templates/cpp/TokenManagerError.h.template"); } - try (CppCodeBuilder builder = CppCodeBuilder.ofHeader(context, settings)) { - builder.setFile(new File((String) settings.get("OUTPUT_DIRECTORY"), "JavaCC.h")); - builder.addTools(JavaCCGlobals.toolName); - builder.addOption(Options.USEROPTION__STATIC, Options.USEROPTION__SUPPORT_CLASS_VISIBILITY_PUBLIC); + try (CppCodeBuilder ccb = CppCodeBuilder.of(context, settings)) { + ccb.setFile(new File((String) settings.get("OUTPUT_DIRECTORY"), "ParseException.cc")); + ccb.addTools(JavaCCGlobals.toolName); + ccb.addOption( + Options.UO__STATIC, Options.UO__SUPPORT_CLASS_VISIBILITY_PUBLIC); - builder.printTemplate("/templates/cpp/JavaCC.h.template"); - } + ccb.printTemplate("/templates/cpp/ParseException.cc.template"); + ccb.switchToIncludeFile(); + ccb.printTemplate("/templates/cpp/ParseException.h.template"); + } - if (!Options.getLibrary().isEmpty()) { - try (CppCodeBuilder builder = CppCodeBuilder.ofHeader(context, settings)) { - builder.setFile(new File((String) settings.get("OUTPUT_DIRECTORY"), "ImportExport.h")); - builder.addTools(JavaCCGlobals.toolName); - builder.addOption(Options.USEROPTION__CPP_LIBRARY); - builder.printTemplate("/templates/cpp/ImportExport.h.template"); - } + try (CppCodeBuilder ccb = CppCodeBuilder.ofHeader(context, settings)) { + ccb.setFile(new File((String) settings.get("OUTPUT_DIRECTORY"), "TokenManager.h")); + ccb.addTools(JavaCCGlobals.toolName); + ccb.addOption( + Options.UO__STATIC, Options.UO__SUPPORT_CLASS_VISIBILITY_PUBLIC); + + ccb.printTemplate("/templates/cpp/TokenManager.h.template"); } - - try (CppCodeBuilder builder = CppCodeBuilder.of(context, settings)) { - builder.setFile(new File((String) settings.get("OUTPUT_DIRECTORY"), "DefaultParserErrorHandler.cc")); - builder.addTools(JavaCCGlobals.toolName); - builder.addOption(Options.USEROPTION__STATIC, Options.USEROPTION__SUPPORT_CLASS_VISIBILITY_PUBLIC); - builder.addOption( - Options.USEROPTION__STATIC, - Options.USEROPTION__SUPPORT_CLASS_VISIBILITY_PUBLIC, - Options.USEROPTION__BUILD_PARSER, - Options.USEROPTION__BUILD_TOKEN_MANAGER); - - builder.printTemplate("/templates/cpp/DefaultParserErrorHandler.cc.template"); - builder.switchToIncludeFile(); - builder.printTemplate("/templates/cpp/DefaultParserErrorHandler.h.template"); - } - try (CppCodeBuilder builder = CppCodeBuilder.ofHeader(context, settings)) { - builder.setFile(new File((String) settings.get("OUTPUT_DIRECTORY"), "ParserErrorHandler.h")); - builder.addTools(JavaCCGlobals.toolName); - builder.addOption( - Options.USEROPTION__STATIC, - Options.USEROPTION__SUPPORT_CLASS_VISIBILITY_PUBLIC, - Options.USEROPTION__BUILD_PARSER, - Options.USEROPTION__BUILD_TOKEN_MANAGER); + try (CppCodeBuilder ccb = CppCodeBuilder.ofHeader(context, settings)) { + ccb.setFile(new File((String) settings.get("OUTPUT_DIRECTORY"), "JavaCC.h")); + ccb.addTools(JavaCCGlobals.toolName); + ccb.addOption( + Options.UO__STATIC, Options.UO__SUPPORT_CLASS_VISIBILITY_PUBLIC); - builder.printTemplate("/templates/cpp/ParserErrorHandler.h.template"); + ccb.printTemplate("/templates/cpp/JavaCC.h.template"); } - try (CppCodeBuilder builder = CppCodeBuilder.of(context, settings)) { - builder.setFile(new File((String) settings.get("OUTPUT_DIRECTORY"), "DefaultTokenManagerErrorHandler.cc")); - builder.addTools(JavaCCGlobals.toolName); - builder.addOption(Options.USEROPTION__STATIC, Options.USEROPTION__SUPPORT_CLASS_VISIBILITY_PUBLIC); - builder.addOption( - Options.USEROPTION__STATIC, - Options.USEROPTION__SUPPORT_CLASS_VISIBILITY_PUBLIC, - Options.USEROPTION__BUILD_PARSER, - Options.USEROPTION__BUILD_TOKEN_MANAGER); - - builder.printTemplate("/templates/cpp/DefaultTokenManagerErrorHandler.cc.template"); - builder.switchToIncludeFile(); - builder.printTemplate("/templates/cpp/DefaultTokenManagerErrorHandler.h.template"); + if (!Options.getLibrary().isEmpty()) { + try (CppCodeBuilder ccb = CppCodeBuilder.ofHeader(context, settings)) { + ccb.setFile(new File((String) settings.get("OUTPUT_DIRECTORY"), "ImportExport.h")); + ccb.addTools(JavaCCGlobals.toolName); + ccb.addOption(Options.UO__LIBRARY); + ccb.printTemplate("/templates/cpp/ImportExport.h.template"); } + } - try (CppCodeBuilder builder = CppCodeBuilder.ofHeader(context, settings)) { - builder.setFile(new File((String) settings.get("OUTPUT_DIRECTORY"), "TokenManagerErrorHandler.h")); - builder.addTools(JavaCCGlobals.toolName); - builder.addOption( - Options.USEROPTION__STATIC, - Options.USEROPTION__SUPPORT_CLASS_VISIBILITY_PUBLIC, - Options.USEROPTION__BUILD_PARSER, - Options.USEROPTION__BUILD_TOKEN_MANAGER); + try (CppCodeBuilder ccb = CppCodeBuilder.of(context, settings)) { + ccb.setFile( + new File((String) settings.get("OUTPUT_DIRECTORY"), "DefaultParserErrorHandler.cc")); + ccb.addTools(JavaCCGlobals.toolName); + ccb.addOption( + Options.UO__STATIC, Options.UO__SUPPORT_CLASS_VISIBILITY_PUBLIC); + ccb.addOption( + Options.UO__STATIC, + Options.UO__SUPPORT_CLASS_VISIBILITY_PUBLIC, + Options.UO__BUILD_PARSER, + Options.UO__BUILD_TOKEN_MANAGER); + + ccb.printTemplate("/templates/cpp/DefaultParserErrorHandler.cc.template"); + ccb.switchToIncludeFile(); + ccb.printTemplate("/templates/cpp/DefaultParserErrorHandler.h.template"); + } + + try (CppCodeBuilder ccb = CppCodeBuilder.ofHeader(context, settings)) { + ccb.setFile(new File((String) settings.get("OUTPUT_DIRECTORY"), "ParserErrorHandler.h")); + ccb.addTools(JavaCCGlobals.toolName); + ccb.addOption( + Options.UO__STATIC, + Options.UO__SUPPORT_CLASS_VISIBILITY_PUBLIC, + Options.UO__BUILD_PARSER, + Options.UO__BUILD_TOKEN_MANAGER); + + ccb.printTemplate("/templates/cpp/ParserErrorHandler.h.template"); + } - builder.printTemplate("/templates/cpp/TokenManagerErrorHandler.h.template"); + try (CppCodeBuilder ccb = CppCodeBuilder.of(context, settings)) { + ccb.setFile( + new File( + (String) settings.get("OUTPUT_DIRECTORY"), "DefaultTokenManagerErrorHandler.cc")); + ccb.addTools(JavaCCGlobals.toolName); + ccb.addOption( + Options.UO__STATIC, Options.UO__SUPPORT_CLASS_VISIBILITY_PUBLIC); + ccb.addOption( + Options.UO__STATIC, + Options.UO__SUPPORT_CLASS_VISIBILITY_PUBLIC, + Options.UO__BUILD_PARSER, + Options.UO__BUILD_TOKEN_MANAGER); + + ccb.printTemplate("/templates/cpp/DefaultTokenManagerErrorHandler.cc.template"); + ccb.switchToIncludeFile(); + ccb.printTemplate("/templates/cpp/DefaultTokenManagerErrorHandler.h.template"); + } + + try (CppCodeBuilder ccb = CppCodeBuilder.ofHeader(context, settings)) { + ccb.setFile( + new File((String) settings.get("OUTPUT_DIRECTORY"), "TokenManagerErrorHandler.h")); + ccb.addTools(JavaCCGlobals.toolName); + ccb.addOption( + Options.UO__STATIC, + Options.UO__SUPPORT_CLASS_VISIBILITY_PUBLIC, + Options.UO__BUILD_PARSER, + Options.UO__BUILD_TOKEN_MANAGER); + + ccb.printTemplate("/templates/cpp/TokenManagerErrorHandler.h.template"); } OtherFilesGenCPP.start(context, tokenizerData); - } catch (Exception e) { - e.printStackTrace(); + } catch (final Exception e) { + e.printStackTrace(); return false; } return true; } - /** - * The Token class generator. - */ + /** The Token class generator. */ @Override - public final TokenCodeGenerator getTokenCodeGenerator(Context context) { + public final TokenCodeGenerator getTokenCodeGenerator(final Context context) { return new TokenCodeGenerator(context); } - /** - * The TokenManager class generator. - */ + /** The TokenManager class generator. */ @Override - public final TokenManagerCodeGenerator getTokenManagerCodeGenerator(Context context) { + public final TokenManagerCodeGenerator getTokenManagerCodeGenerator(final Context context) { return new TokenManagerCodeGenerator(context); } - /** - * The Parser class generator. - */ + /** The Parser class generator. */ @Override - public final ParserCodeGenerator getParserCodeGenerator(Context context) { + public final ParserCodeGenerator getParserCodeGenerator(final Context context) { return new ParserCodeGenerator(context); } /** - * TODO(sreeni): Fix this when we do tree annotations in the parser code - * generator. The JJTree preprocesor. + * TODO(sreeni): Fix this when we do tree annotations in the parser code generator. The JJTree + * preprocesor. */ @Override - public final DefaultJJTreeVisitor getJJTreeCodeGenerator(JJTreeContext context) { + public final DefaultJJTreeVisitor getJJTreeCodeGenerator(final JJTreeContext context) { return new JJTreeCodeGenerator(context); } - } diff --git a/src/main/java/org/javacc/cpp/JJTreeCodeGenerator.java b/src/main/java/org/javacc/cpp/JJTreeCodeGenerator.java index de4d38c..45135b5 100644 --- a/src/main/java/org/javacc/cpp/JJTreeCodeGenerator.java +++ b/src/main/java/org/javacc/cpp/JJTreeCodeGenerator.java @@ -413,7 +413,7 @@ private void tryExpansionUnit(NodeScope ns, IO io, String indent, JJTreeNode exp @Override public void generateHelperFiles() throws java.io.IOException { CodeGeneratorSettings options = CodeGeneratorSettings.of(Options.getOptions()); - options.set(Options.NONUSER_OPTION__PARSER_NAME, JJTreeGlobals.parserName); + options.set(Options.NUO__PARSER_NAME, JJTreeGlobals.parserName); try (CppCodeBuilder builder = CppCodeBuilder.of(context, options)) { builder diff --git a/src/main/java/org/javacc/cpp/NodeFiles.java b/src/main/java/org/javacc/cpp/NodeFiles.java index 209e111..8d6f62d 100644 --- a/src/main/java/org/javacc/cpp/NodeFiles.java +++ b/src/main/java/org/javacc/cpp/NodeFiles.java @@ -1,65 +1,90 @@ - +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ package org.javacc.cpp; -import org.javacc.Version; -import org.javacc.jjtree.ASTNodeDescriptor; -import org.javacc.jjtree.JJTreeContext; -import org.javacc.jjtree.JJTreeGlobals; -import org.javacc.parser.CodeGeneratorSettings; -import org.javacc.parser.Options; - import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; +import org.javacc.Version; +import org.javacc.jjtree.ASTNodeDescriptor; +import org.javacc.jjtree.JJTreeContext; +import org.javacc.jjtree.JJTreeGlobals; +import org.javacc.parser.CodeGeneratorSettings; +import org.javacc.parser.Options; final class NodeFiles { private NodeFiles() {} private static List headersForJJTreeH = new ArrayList<>(); - /** - * ID of the latest version (of JJTree) in which one of the Node classes was - * modified. - */ - private static final String nodeVersion = Version.version; - private static Set nodesToBuild = new HashSet<>(); + /** ID of the latest version (of JJTree) in which one of the Node classes was modified. */ + private static final String nodeVersion = Version.version; - static void generateNodeType(String nodeType) { + private static Set nodesToBuild = new HashSet<>(); + + static void generateNodeType(final String nodeType) { if (!nodeType.equals("Tree") && !nodeType.equals("Node")) { NodeFiles.nodesToBuild.add(nodeType); } } - private static String nodeIncludeFile(File outputDirectory) { + private static String nodeIncludeFile(final File outputDirectory) { return new File(outputDirectory, "Tree.h").getAbsolutePath(); } - private static String simpleNodeCodeFile(File outputDirectory) { + private static String simpleNodeCodeFile(final File outputDirectory) { return new File(outputDirectory, "Node.cc").getAbsolutePath(); } - private static String jjtreeIncludeFile(File outputDirectory) { + private static String jjtreeIncludeFile(final File outputDirectory) { return new File(outputDirectory, JJTreeGlobals.parserName + "Tree.h").getAbsolutePath(); } - private static String jjtreeASTNodeImplFile(File outputDirectory, String s) { + private static String jjtreeASTNodeImplFile(final File outputDirectory, final String s) { return new File(outputDirectory, s + ".cc").getAbsolutePath(); } - private static String jjtreeImplFile(File outputDirectory, String s) { + private static String jjtreeImplFile(final File outputDirectory, final String s) { return new File(outputDirectory, s + ".cc").getAbsolutePath(); } - private static String visitorIncludeFile(File outputDirectory) { - String name = NodeFiles.visitorClass(); + private static String visitorIncludeFile(final File outputDirectory) { + final String name = NodeFiles.visitorClass(); return new File(outputDirectory, name + ".h").getAbsolutePath(); } - static void generateOutputFiles(JJTreeContext context) throws IOException { + static void generateOutputFiles(final JJTreeContext context) throws IOException { NodeFiles.generateNodeHeader(context); NodeFiles.generateSimpleNode(context); NodeFiles.generateOneTree(context, false); @@ -68,105 +93,151 @@ static void generateOutputFiles(JJTreeContext context) throws IOException { NodeFiles.generateVisitors(context); } - private static void generateNodeHeader(JJTreeContext context) { - CodeGeneratorSettings optionMap = CodeGeneratorSettings.of(Options.getOptions()); + private static void generateNodeHeader(final JJTreeContext context) { + final CodeGeneratorSettings optionMap = CodeGeneratorSettings.of(Options.getOptions()); optionMap.set("PARSER_NAME", JJTreeGlobals.parserName); optionMap.set("VISITOR_RETURN_TYPE", NodeFiles.getVisitorReturnType()); optionMap.set("VISITOR_DATA_TYPE", NodeFiles.getVisitorArgumentType()); - optionMap.set("VISITOR_RETURN_TYPE_VOID", Boolean.valueOf(NodeFiles.getVisitorReturnType().equals("void"))); - - try (CppCodeBuilder builder = CppCodeBuilder.ofHeader(context, optionMap)) { - builder.setFile(new File(NodeFiles.nodeIncludeFile(context.treeOptions().getJJTreeOutputDirectory()))); - builder.setVersion(NodeFiles.nodeVersion).addTools(JJTreeGlobals.toolName); - builder.addOption("MULTI", "NODE_USES_PARSER", "VISITOR", "TRACK_TOKENS", "NODE_PREFIX", "NODE_EXTENDS", - "NODE_FACTORY", "SUPPORT_CLASS_VISIBILITY_PUBLIC"); - - builder.printTemplate("/templates/cpp/Tree.h.template"); - } catch (IOException e) { + optionMap.set( + "VISITOR_RETURN_TYPE_VOID", + Boolean.valueOf(NodeFiles.getVisitorReturnType().equals("void"))); + + try (CppCodeBuilder ccb = CppCodeBuilder.ofHeader(context, optionMap)) { + ccb.setFile( + new File(NodeFiles.nodeIncludeFile(context.treeOptions().getJJTreeOutputDirectory()))); + ccb.setVersion(NodeFiles.nodeVersion).addTools(JJTreeGlobals.toolName); + ccb.addOption( + "MULTI", + "NODE_USES_PARSER", + "VISITOR", + "TRACK_TOKENS", + "NODE_PREFIX", + "NODE_EXTENDS", + "NODE_FACTORY", + "SUPPORT_CLASS_VISIBILITY_PUBLIC"); + + ccb.printTemplate("/templates/cpp/Tree.h.template"); + } catch (final IOException e) { throw new Error(e.toString()); } } - - private static void generateSimpleNode(JJTreeContext context) { - CodeGeneratorSettings optionMap = CodeGeneratorSettings.of(Options.getOptions()); - optionMap.set(Options.NONUSER_OPTION__PARSER_NAME, JJTreeGlobals.parserName); + private static void generateSimpleNode(final JJTreeContext context) { + final CodeGeneratorSettings optionMap = CodeGeneratorSettings.of(Options.getOptions()); + optionMap.set(Options.NUO__PARSER_NAME, JJTreeGlobals.parserName); optionMap.set("VISITOR_RETURN_TYPE", NodeFiles.getVisitorReturnType()); optionMap.set("VISITOR_DATA_TYPE", NodeFiles.getVisitorArgumentType()); - optionMap.set("VISITOR_RETURN_TYPE_VOID", Boolean.valueOf(NodeFiles.getVisitorReturnType().equals("void"))); - - try (CppCodeBuilder builder = CppCodeBuilder.of(context, optionMap)) { - builder.setFile(new File(NodeFiles.simpleNodeCodeFile(context.treeOptions().getJJTreeOutputDirectory()))); - builder.setVersion(NodeFiles.nodeVersion).addTools(JJTreeGlobals.toolName); - builder.addOption("MULTI", "NODE_USES_PARSER", "VISITOR", "TRACK_TOKENS", "NODE_PREFIX", "NODE_EXTENDS", - "NODE_FACTORY", Options.USEROPTION__SUPPORT_CLASS_VISIBILITY_PUBLIC); - - builder.printTemplate("/templates/cpp/Node.cc.template"); - builder.switchToIncludeFile(); - builder.printTemplate("/templates/cpp/Node.h.template"); - } catch (IOException e) { + optionMap.set( + "VISITOR_RETURN_TYPE_VOID", + Boolean.valueOf(NodeFiles.getVisitorReturnType().equals("void"))); + + try (CppCodeBuilder ccb = CppCodeBuilder.of(context, optionMap)) { + ccb.setFile( + new File(NodeFiles.simpleNodeCodeFile(context.treeOptions().getJJTreeOutputDirectory()))); + ccb.setVersion(NodeFiles.nodeVersion).addTools(JJTreeGlobals.toolName); + ccb.addOption( + "MULTI", + "NODE_USES_PARSER", + "VISITOR", + "TRACK_TOKENS", + "NODE_PREFIX", + "NODE_EXTENDS", + "NODE_FACTORY", + Options.UO__SUPPORT_CLASS_VISIBILITY_PUBLIC); + + ccb.printTemplate("/templates/cpp/Node.cc.template"); + ccb.switchToIncludeFile(); + ccb.printTemplate("/templates/cpp/Node.h.template"); + } catch (final IOException e) { throw new Error(e.toString()); } } - private static void generateOneTree(JJTreeContext context, boolean generateOneTreeImpl) { - CodeGeneratorSettings optionMap = CodeGeneratorSettings.of(Options.getOptions()); + private static void generateOneTree( + final JJTreeContext context, final boolean generateOneTreeImpl) { + final CodeGeneratorSettings optionMap = CodeGeneratorSettings.of(Options.getOptions()); optionMap.set("PARSER_NAME", JJTreeGlobals.parserName); optionMap.set("VISITOR_RETURN_TYPE", NodeFiles.getVisitorReturnType()); optionMap.set("VISITOR_DATA_TYPE", NodeFiles.getVisitorArgumentType()); - optionMap.set("VISITOR_RETURN_TYPE_VOID", Boolean.valueOf(NodeFiles.getVisitorReturnType().equals("void"))); - - try (CppCodeBuilder builder = - generateOneTreeImpl ? CppCodeBuilder.of(context, optionMap) : CppCodeBuilder.ofHeader(context, optionMap)) { - builder.setFile(new File(NodeFiles.jjtreeIncludeFile(context.treeOptions().getJJTreeOutputDirectory()))); - builder.setVersion(NodeFiles.nodeVersion).addTools(JJTreeGlobals.toolName); - builder.addOption("MULTI", "NODE_USES_PARSER", "VISITOR", "TRACK_TOKENS", "NODE_PREFIX", "NODE_EXTENDS", - "NODE_FACTORY", "SUPPORT_CLASS_VISIBILITY_PUBLIC"); - - builder.switchToIncludeFile(); - String guard = "JAVACC_" + "ONE_TREE_H"; - builder.println("#ifndef " + guard); - builder.println("#define " + guard); - builder.println(); - builder.println("#include \"Node.h\""); - for (String s : NodeFiles.nodesToBuild) { - builder.println("#include \"" + s + ".h\""); + optionMap.set( + "VISITOR_RETURN_TYPE_VOID", + Boolean.valueOf(NodeFiles.getVisitorReturnType().equals("void"))); + + try (CppCodeBuilder ccb = + generateOneTreeImpl + ? CppCodeBuilder.of(context, optionMap) + : CppCodeBuilder.ofHeader(context, optionMap)) { + ccb.setFile( + new File(NodeFiles.jjtreeIncludeFile(context.treeOptions().getJJTreeOutputDirectory()))); + ccb.setVersion(NodeFiles.nodeVersion).addTools(JJTreeGlobals.toolName); + ccb.addOption( + "MULTI", + "NODE_USES_PARSER", + "VISITOR", + "TRACK_TOKENS", + "NODE_PREFIX", + "NODE_EXTENDS", + "NODE_FACTORY", + "SUPPORT_CLASS_VISIBILITY_PUBLIC"); + + ccb.switchToIncludeFile(); + final String guard = "JAVACC_" + "ONE_TREE_H"; + ccb.println("#ifndef " + guard); + ccb.println("#define " + guard); + ccb.println(); + ccb.println("#include \"Node.h\""); + for (final String s : NodeFiles.nodesToBuild) { + ccb.println("#include \"" + s + ".h\""); if (generateOneTreeImpl) { - builder.switchToMainFile(); - builder.printTemplate("/templates/cpp/MultiNode.cc.template", + ccb.switchToMainFile(); + ccb.printTemplate( + "/templates/cpp/MultiNode.cc.template", CodeGeneratorSettings.create().set("NODE_TYPE", s)); - builder.switchToIncludeFile(); + ccb.switchToIncludeFile(); } } - builder.println("#endif"); - } catch (IOException e) { + ccb.println("#endif"); + } catch (final IOException e) { throw new Error(e.toString()); } } - private static void generateMultiTree(JJTreeContext context) { - for (String node : NodeFiles.nodesToBuild) { - if (new File(NodeFiles.jjtreeASTNodeImplFile(context.treeOptions().getASTNodeDirectory(), node)).exists()) { + private static void generateMultiTree(final JJTreeContext context) { + for (final String node : NodeFiles.nodesToBuild) { + if (new File( + NodeFiles.jjtreeASTNodeImplFile(context.treeOptions().getASTNodeDirectory(), node)) + .exists()) { continue; } - CodeGeneratorSettings optionMap = CodeGeneratorSettings.of(Options.getOptions()); - optionMap.set(Options.NONUSER_OPTION__PARSER_NAME, JJTreeGlobals.parserName); + final CodeGeneratorSettings optionMap = CodeGeneratorSettings.of(Options.getOptions()); + optionMap.set(Options.NUO__PARSER_NAME, JJTreeGlobals.parserName); optionMap.set("VISITOR_RETURN_TYPE", NodeFiles.getVisitorReturnType()); optionMap.set("VISITOR_DATA_TYPE", NodeFiles.getVisitorArgumentType()); - optionMap.set("VISITOR_RETURN_TYPE_VOID", Boolean.valueOf(NodeFiles.getVisitorReturnType().equals("void"))); + optionMap.set( + "VISITOR_RETURN_TYPE_VOID", + Boolean.valueOf(NodeFiles.getVisitorReturnType().equals("void"))); optionMap.set("NODE_TYPE", node); - try (CppCodeBuilder builder = CppCodeBuilder.of(context, optionMap)) { - builder.setFile(new File(NodeFiles.jjtreeImplFile(context.treeOptions().getJJTreeOutputDirectory(), node))); - builder.setVersion(NodeFiles.nodeVersion).addTools(JJTreeGlobals.toolName); - builder.addOption("MULTI", "NODE_USES_PARSER", "VISITOR", "TRACK_TOKENS", "NODE_PREFIX", "NODE_EXTENDS", - "NODE_FACTORY", Options.USEROPTION__SUPPORT_CLASS_VISIBILITY_PUBLIC); - - builder.printTemplate("/templates/cpp/MultiNode.cc.template"); - builder.switchToIncludeFile(); - builder.printTemplate("/templates/cpp/MultiNode.h.template"); - } catch (IOException e) { + try (CppCodeBuilder ccb = CppCodeBuilder.of(context, optionMap)) { + ccb.setFile( + new File( + NodeFiles.jjtreeImplFile(context.treeOptions().getJJTreeOutputDirectory(), node))); + ccb.setVersion(NodeFiles.nodeVersion).addTools(JJTreeGlobals.toolName); + ccb.addOption( + "MULTI", + "NODE_USES_PARSER", + "VISITOR", + "TRACK_TOKENS", + "NODE_PREFIX", + "NODE_EXTENDS", + "NODE_FACTORY", + Options.UO__SUPPORT_CLASS_VISIBILITY_PUBLIC); + + ccb.printTemplate("/templates/cpp/MultiNode.cc.template"); + ccb.switchToIncludeFile(); + ccb.printTemplate("/templates/cpp/MultiNode.h.template"); + } catch (final IOException e) { throw new Error(e.toString()); } } @@ -176,51 +247,53 @@ private static String nodeConstants() { return JJTreeGlobals.parserName + "TreeConstants"; } - private static void generateTreeConstants(JJTreeContext context) { - List nodeIds = ASTNodeDescriptor.getNodeIds(); - List nodeNames = ASTNodeDescriptor.getNodeNames(); + private static void generateTreeConstants(final JJTreeContext context) { + final List nodeIds = ASTNodeDescriptor.getNodeIds(); + final List nodeNames = ASTNodeDescriptor.getNodeNames(); - File file = new File(context.treeOptions().getJJTreeOutputDirectory(), NodeFiles.nodeConstants() + ".h"); + final File file = + new File( + context.treeOptions().getJJTreeOutputDirectory(), NodeFiles.nodeConstants() + ".h"); NodeFiles.headersForJJTreeH.add(file.getName()); - try (CppCodeBuilder builder = CppCodeBuilder.ofHeader(context, CodeGeneratorSettings.create())) { - builder.setFile(file); + try (CppCodeBuilder ccb = CppCodeBuilder.ofHeader(context, CodeGeneratorSettings.create())) { + ccb.setFile(file); - String guard = "JAVACC_" + nodeConstants().toUpperCase() + "_H"; - builder.println("#ifndef " + guard); - builder.println("#define " + guard); - builder.println(); - builder.println("#include \"JavaCC.h\""); + final String guard = "JAVACC_" + nodeConstants().toUpperCase() + "_H"; + ccb.println("#ifndef " + guard); + ccb.println("#define " + guard); + ccb.println(); + ccb.println("#include \"JavaCC.h\""); - if (Options.hasNamespace()) { - builder.println("namespace " + Options.stringValue("NAMESPACE_OPEN")); + if (Options.hasNamespace()) { + ccb.println("namespace " + Options.stringValue("NAMESPACE_OPEN")); } - builder.println("enum {"); + ccb.println("enum {"); for (int i = 0; i < nodeIds.size(); ++i) { - String n = nodeIds.get(i); - builder.println(" " + n + " = " + i + ","); + final String n = nodeIds.get(i); + ccb.println(" " + n + " = " + i + ","); } - builder.println("};"); - builder.println(); + ccb.println("};"); + ccb.println(); for (int i = 0; i < nodeNames.size(); ++i) { - builder.println(" static JJChar jjtNodeName_arr_", i, "[] = "); - builder.printCharArray(nodeNames.get(i)); - builder.println(";"); + ccb.println(" static JJChar jjtNodeName_arr_", i, "[] = "); + ccb.printCharArray(nodeNames.get(i)); + ccb.println(";"); } - builder.println(" static JJString jjtNodeName[] = {"); + ccb.println(" static JJString jjtNodeName[] = {"); for (int i = 0; i < nodeNames.size(); i++) { - builder.println("jjtNodeName_arr_", i, ", "); + ccb.println("jjtNodeName_arr_", i, ", "); } - builder.println(" };"); + ccb.println(" };"); if (Options.hasNamespace()) { - builder.println(Options.stringValue("NAMESPACE_CLOSE")); + ccb.println(Options.stringValue("NAMESPACE_CLOSE")); } - builder.println("#endif"); - } catch (IOException e) { + ccb.println("#endif"); + } catch (final IOException e) { throw new Error(e); } } @@ -229,8 +302,8 @@ private static String visitorClass() { return JJTreeGlobals.parserName + "Visitor"; } - private static String getVisitMethodName(String className) { - StringBuffer sb = new StringBuffer("visit"); + private static String getVisitMethodName(final String className) { + final StringBuffer sb = new StringBuffer("visit"); if (Options.booleanValue("VISITOR_METHOD_NAME_INCLUDES_TYPE_NAME")) { sb.append(Character.toUpperCase(className.charAt(0))); for (int i = 1; i < className.length(); i++) { @@ -242,109 +315,132 @@ private static String getVisitMethodName(String className) { } private static String getVisitorArgumentType() { - String ret = Options.stringValue("VISITOR_DATA_TYPE"); + final String ret = Options.stringValue("VISITOR_DATA_TYPE"); return (ret == null) || ret.equals("") || ret.equals("Object") ? "void *" : ret; } private static String getVisitorReturnType() { - String ret = Options.stringValue("VISITOR_RETURN_TYPE"); + final String ret = Options.stringValue("VISITOR_RETURN_TYPE"); return (ret == null) || ret.equals("") || ret.equals("Object") ? "void" : ret; } - private static void generateVisitors(JJTreeContext context) { + private static void generateVisitors(final JJTreeContext context) { if (!context.treeOptions().getVisitor()) { return; } - try (CppCodeBuilder builder = CppCodeBuilder.ofHeader(context, CodeGeneratorSettings.create())) { - builder.setFile(new File(NodeFiles.visitorIncludeFile(context.treeOptions().getJJTreeOutputDirectory()))); + try (CppCodeBuilder ccb = CppCodeBuilder.ofHeader(context, CodeGeneratorSettings.create())) { + ccb.setFile( + new File(NodeFiles.visitorIncludeFile(context.treeOptions().getJJTreeOutputDirectory()))); - String guard = "JAVACC_" + JJTreeGlobals.parserName.toUpperCase() + "_VISITOR_H"; - builder.println("#ifndef " + guard); - builder.println("#define " + guard); - builder.println(); - builder.println("#include \"JavaCC.h\""); - builder.println("#include \"" + JJTreeGlobals.parserName + "Tree.h" + "\""); + final String guard = "JAVACC_" + JJTreeGlobals.parserName.toUpperCase() + "_VISITOR_H"; + ccb.println("#ifndef " + guard); + ccb.println("#define " + guard); + ccb.println(); + ccb.println("#include \"JavaCC.h\""); + ccb.println("#include \"" + JJTreeGlobals.parserName + "Tree.h" + "\""); if (Options.hasNamespace()) { - builder.println("namespace " + Options.stringValue("NAMESPACE_OPEN")); + ccb.println("namespace " + Options.stringValue("NAMESPACE_OPEN")); } - NodeFiles.generateVisitorInterface(builder, context); - NodeFiles.generateDefaultVisitor(builder, context); + NodeFiles.generateVisitorInterface(ccb, context); + NodeFiles.generateDefaultVisitor(ccb, context); if (Options.hasNamespace()) { - builder.println(Options.stringValue("NAMESPACE_CLOSE")); + ccb.println(Options.stringValue("NAMESPACE_CLOSE")); } - builder.println("#endif"); - } catch (IOException e) { + ccb.println("#endif"); + } catch (final IOException e) { throw new Error(e); } } - private static void generateVisitorInterface(CppCodeBuilder builder, JJTreeContext context) { - String name = NodeFiles.visitorClass(); - List nodeNames = ASTNodeDescriptor.getNodeNames(); + private static void generateVisitorInterface( + final CppCodeBuilder ccb, final JJTreeContext context) { + final String name = NodeFiles.visitorClass(); + final List nodeNames = ASTNodeDescriptor.getNodeNames(); - builder.println("class " + name); - builder.println("{"); + ccb.println("class " + name); + ccb.println("{"); String argumentType = NodeFiles.getVisitorArgumentType(); - String returnType = NodeFiles.getVisitorReturnType(); + final String returnType = NodeFiles.getVisitorReturnType(); if (!context.treeOptions().getVisitorDataType().equals("")) { argumentType = context.treeOptions().getVisitorDataType(); } - builder.println("public:"); + ccb.println("public:"); - builder.println(" virtual " + returnType + " visit(const Node *node, " + argumentType + " data) = 0;"); + ccb.println( + " virtual " + returnType + " visit(const Node *node, " + argumentType + " data) = 0;"); if (context.treeOptions().getMulti()) { - for (String n : nodeNames) { + for (final String n : nodeNames) { if (n.equals("void")) { continue; } - String nodeType = context.treeOptions().getNodePrefix() + n; - builder.println(" virtual " + returnType + " " + NodeFiles.getVisitMethodName(nodeType) + "(const " + nodeType - + " *node, " + argumentType + " data) = 0;"); + final String nodeType = context.treeOptions().getNodePrefix() + n; + ccb.println( + " virtual " + + returnType + + " " + + NodeFiles.getVisitMethodName(nodeType) + + "(const " + + nodeType + + " *node, " + + argumentType + + " data) = 0;"); } } - builder.println(" virtual ~" + name + "() { }"); - builder.println("};"); + ccb.println(" virtual ~" + name + "() { }"); + ccb.println("};"); } private static String defaultVisitorClass() { return JJTreeGlobals.parserName + "DefaultVisitor"; } - private static void generateDefaultVisitor(CppCodeBuilder builder, JJTreeContext context) { - String className = NodeFiles.defaultVisitorClass(); - List nodeNames = ASTNodeDescriptor.getNodeNames(); + private static void generateDefaultVisitor( + final CppCodeBuilder ccb, final JJTreeContext context) { + final String className = NodeFiles.defaultVisitorClass(); + final List nodeNames = ASTNodeDescriptor.getNodeNames(); - builder.println("class " + className + " : public " + NodeFiles.visitorClass() + " {"); + ccb.println("class " + className + " : public " + NodeFiles.visitorClass() + " {"); - String argumentType = NodeFiles.getVisitorArgumentType(); - String ret = NodeFiles.getVisitorReturnType(); + final String argumentType = NodeFiles.getVisitorArgumentType(); + final String ret = NodeFiles.getVisitorReturnType(); - builder.println("public:"); - builder.println(" virtual " + ret + " defaultVisit(const Node *node, " + argumentType + " data) = 0;"); + ccb.println("public:"); + ccb.println( + " virtual " + ret + " defaultVisit(const Node *node, " + argumentType + " data) = 0;"); - builder.println(" virtual " + ret + " visit(const Node *node, " + argumentType + " data) {"); - builder.println(" " + (ret.trim().equals("void") ? "" : "return ") + "defaultVisit(node, data);"); - builder.println(" }"); + ccb.println(" virtual " + ret + " visit(const Node *node, " + argumentType + " data) {"); + ccb.println( + " " + (ret.trim().equals("void") ? "" : "return ") + "defaultVisit(node, data);"); + ccb.println(" }"); if (context.treeOptions().getMulti()) { - for (String n : nodeNames) { + for (final String n : nodeNames) { if (n.equals("void")) { continue; } - String nodeType = context.treeOptions().getNodePrefix() + n; - builder.println(" virtual " + ret + " " + NodeFiles.getVisitMethodName(nodeType) + "(const " + nodeType - + " *node, " + argumentType + " data) {"); - builder.println(" " + (ret.trim().equals("void") ? "" : "return ") + "defaultVisit(node, data);"); - builder.println(" }"); + final String nodeType = context.treeOptions().getNodePrefix() + n; + ccb.println( + " virtual " + + ret + + " " + + NodeFiles.getVisitMethodName(nodeType) + + "(const " + + nodeType + + " *node, " + + argumentType + + " data) {"); + ccb.println( + " " + (ret.trim().equals("void") ? "" : "return ") + "defaultVisit(node, data);"); + ccb.println(" }"); } } - builder.println(" ~" + className + "() { }"); - builder.println("};"); + ccb.println(" ~" + className + "() { }"); + ccb.println("};"); } } diff --git a/src/main/java/org/javacc/cpp/OtherFilesGenCPP.java b/src/main/java/org/javacc/cpp/OtherFilesGenCPP.java index 082d80f..def9e38 100644 --- a/src/main/java/org/javacc/cpp/OtherFilesGenCPP.java +++ b/src/main/java/org/javacc/cpp/OtherFilesGenCPP.java @@ -1,19 +1,19 @@ -// Copyright 2012 Google Inc. All Rights Reserved. -// Author: sreeni@google.com (Sreeni Viswanadha) - /* - * Copyright (c) 2006, Sun Microsystems, Inc. All rights reserved. + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. * Redistributions in binary - * form must reproduce the above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or other materials provided - * with the distribution. * Neither the name of the Sun Microsystems, Inc. nor - * the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -24,12 +24,14 @@ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ - package org.javacc.cpp; +import java.io.File; +import java.util.ArrayList; +import java.util.List; import org.javacc.parser.CodeGeneratorSettings; import org.javacc.parser.Context; import org.javacc.parser.JavaCCGlobals; @@ -41,146 +43,149 @@ import org.javacc.parser.TokenProduction; import org.javacc.parser.TokenizerData; -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -/** - * Generates the Constants file. - */ +/** Generates the Constants file. */ class OtherFilesGenCPP { - static void printTokenImages(CppCodeBuilder builder, Context context) { - builder.println(" /** Literal token image. */"); - int cnt = 0; - builder.println(" static const JJChar tokenImage_" + cnt + "[] = "); - OtherFilesGenCPP.printCharArray(builder, ""); - builder.println(";"); - - for (TokenProduction tp : context.globals().rexprlist) { - for (RegExprSpec res : tp.respecs) { - RegularExpression re = res.rexp; - builder.println(" static const JJChar tokenImage_" + ++cnt + "[] = "); - if (re instanceof RStringLiteral) { - String image = ((RStringLiteral) re).image; - OtherFilesGenCPP.printCharArray(builder, image); - } else if (!re.label.equals("")) { - OtherFilesGenCPP.printCharArray(builder, "<" + re.label + ">"); - } else { - if (re.tpContext.kind == TokenProduction.TOKEN) { - context.errors().warning(re, "Consider giving this non-string token a label for better error reporting."); - } - OtherFilesGenCPP.printCharArray(builder, ""); - } - builder.println(";"); - } - } - - builder.println(" static const JJChar* const tokenImages[] = {"); - for (int i = 0; i <= cnt; i++) { - builder.println("tokenImage_" + i + ", "); - } - builder.println(" };"); - builder.println(); - - } - static void printTokenLabels(CppCodeBuilder builder, Context context) { - builder.println(" /** Literal token label. */"); - int cnt = 0; - builder.println(" static const JJChar tokenLabel_" + cnt + "[] = "); - OtherFilesGenCPP.printCharArray(builder, ""); - builder.println(";"); - - for (TokenProduction tp : context.globals().rexprlist) { - for (RegExprSpec res : tp.respecs) { - RegularExpression re = res.rexp; - builder.println(" static const JJChar tokenLabel_" + ++cnt + "[] = "); - if (re instanceof RStringLiteral) { - String label = ((RStringLiteral) re).label; - OtherFilesGenCPP.printCharArray(builder, "<" + label + ">"); - } else if (!re.label.equals("")) { - OtherFilesGenCPP.printCharArray(builder, "<" + re.label + ">"); - } else { - if (re.tpContext.kind == TokenProduction.TOKEN) { - context.errors().warning(re, "Consider giving this non-string token a label for better error reporting."); - } - OtherFilesGenCPP.printCharArray(builder, ""); - } - builder.println(";"); - } - } - - builder.println(" static const JJChar* const tokenLabels[] = {"); - for (int i = 0; i <= cnt; i++) { - builder.println("tokenLabel_" + i + ", "); - } - builder.println(" };"); - builder.println(); - - } - static void start(Context context, TokenizerData tokenizerData) throws MetaParseException { - if (context.errors().get_error_count() != 0) { - throw new MetaParseException(); + static void printTokenImages(final CppCodeBuilder ccb, final Context context) { + ccb.println(" /** Literal token image. */"); + int cnt = 0; + ccb.println(" static const JJChar tokenImage_" + cnt + "[] = "); + OtherFilesGenCPP.printCharArray(ccb, ""); + ccb.println(";"); + + for (final TokenProduction tp : context.globals().rexprlist) { + for (final RegExprSpec res : tp.respecs) { + final RegularExpression re = res.rexp; + ccb.println(" static const JJChar tokenImage_" + ++cnt + "[] = "); + if (re instanceof RStringLiteral) { + final String image = ((RStringLiteral) re).image; + OtherFilesGenCPP.printCharArray(ccb, image); + } else if (!re.label.equals("")) { + OtherFilesGenCPP.printCharArray(ccb, "<" + re.label + ">"); + } else { + if (re.tpContext.kind == TokenProduction.TOKEN) { + context + .errors() + .warning( + re, + "Consider giving this non-string token a label for better error reporting."); + } + OtherFilesGenCPP.printCharArray(ccb, ""); + } + ccb.println(";"); + } } - List toolnames = new ArrayList<>(context.globals().toolNames); - toolnames.add(JavaCCGlobals.toolName); + ccb.println(" static const JJChar* const tokenImages[] = {"); + for (int i = 0; i <= cnt; i++) { + ccb.println("tokenImage_" + i + ", "); + } + ccb.println(" };"); + ccb.println(); + } + + static void printTokenLabels(final CppCodeBuilder ccb, final Context ctx) { + ccb.println(" /** Literal token label. */"); + int cnt = 0; + ccb.println(" static const JJChar tokenLabel_" + cnt + "[] = "); + OtherFilesGenCPP.printCharArray(ccb, ""); + ccb.println(";"); + + for (final TokenProduction tp : ctx.globals().rexprlist) { + for (final RegExprSpec res : tp.respecs) { + final RegularExpression re = res.rexp; + ccb.println(" static const JJChar tokenLabel_" + ++cnt + "[] = "); + if (re instanceof RStringLiteral) { + final String label = ((RStringLiteral) re).label; + OtherFilesGenCPP.printCharArray(ccb, "<" + label + ">"); + } else if (!re.label.equals("")) { + OtherFilesGenCPP.printCharArray(ccb, "<" + re.label + ">"); + } else { + if (re.tpContext.kind == TokenProduction.TOKEN) { + ctx.errors() + .warning( + re, + "Consider giving this non-string token a label for better error reporting."); + } + OtherFilesGenCPP.printCharArray(ccb, ""); + } + ccb.println(";"); + } + } + ccb.println(" static const JJChar* const tokenLabels[] = {"); + for (int i = 0; i <= cnt; i++) { + ccb.println("tokenLabel_" + i + ", "); + } + ccb.println(" };"); + ccb.println(); + } - try (CppCodeBuilder builder = CppCodeBuilder.ofHeader(context, CodeGeneratorSettings.create())) { - builder.setFile(new File(Options.getOutputDirectory(), context.globals().cu_name + "Constants.h")); - builder.addTools(toolnames.toArray(new String[toolnames.size()])); + static void start(final Context context, final TokenizerData tokenizerData) + throws MetaParseException { + if (context.errors().get_error_count() != 0) { + throw new MetaParseException(); + } - builder.println(); - builder.println("/**"); - builder.println(" * Token literal values and constants."); - builder.println(" * Generated by org.javacc.cpp.OtherFilesGenCPP#start()"); - builder.println(" */"); + final List toolnames = new ArrayList<>(context.globals().toolNames); + toolnames.add(JavaCCGlobals.toolName); - String guard = "JAVACC_" + context.globals().cu_name.toUpperCase() + "CONSTANTS_H"; - builder.println("#ifndef " + guard); - builder.println("#define " + guard); - builder.println(); - builder.println("#include \"JavaCC.h\""); - builder.println(); + try (CppCodeBuilder ccb = CppCodeBuilder.ofHeader(context, CodeGeneratorSettings.create())) { + ccb.setFile(new File(Options.getOutputDirectory(), context.globals().cu_name + "Constants.h")); + ccb.addTools(toolnames.toArray(new String[toolnames.size()])); + + ccb.println(); + ccb.println("/**"); + ccb.println(" * Token literal values and constants."); + ccb.println(" * Generated by org.javacc.cpp.OtherFilesGenCPP#start()"); + ccb.println(" */"); + + final String guard = "JAVACC_" + context.globals().cu_name.toUpperCase() + "CONSTANTS_H"; + ccb.println("#ifndef " + guard); + ccb.println("#define " + guard); + ccb.println(); + ccb.println("#include \"JavaCC.h\""); + ccb.println(); if (Options.hasNamespace()) { - builder.println("namespace " + Options.stringValue("NAMESPACE_OPEN")); + ccb.println("namespace " + Options.stringValue("NAMESPACE_OPEN")); } - String constPrefix = "const"; - builder.println(" /** End of File. */"); - builder.println(constPrefix + " int _EOF = 0;"); - for (RegularExpression re : context.globals().ordered_named_tokens) { - builder.println(" /** RegularExpression Id. */"); - builder.println(constPrefix + " int " + re.label + " = " + re.ordinal + ";"); + final String constPrefix = "const"; + ccb.println(" /** End of File. */"); + ccb.println(constPrefix + " int _EOF = 0;"); + for (final RegularExpression re : context.globals().ordered_named_tokens) { + ccb.println(" /** RegularExpression Id. */"); + ccb.println(constPrefix + " int " + re.label + " = " + re.ordinal + ";"); } - builder.println(); + ccb.println(); if (!Options.getUserTokenManager() && Options.getBuildTokenManager()) { for (int i = 0; i < tokenizerData.lexStateNames.length; i++) { - builder.println(" /** Lexical state. */"); - builder.println(constPrefix + " int " + tokenizerData.lexStateNames[i] + " = " + i + ";"); + ccb.println(" /** Lexical state. */"); + ccb.println(constPrefix + " int " + tokenizerData.lexStateNames[i] + " = " + i + ";"); } - builder.println(); + ccb.println(); } - printTokenImages(builder, context); - printTokenLabels(builder, context); - - if (Options.stringValue(Options.USEROPTION__CPP_NAMESPACE).length() > 0) { - builder.println(Options.stringValue("NAMESPACE_CLOSE")); + printTokenImages(ccb, context); + printTokenLabels(ccb, context); + + if (Options.stringValue(Options.UO__NAMESPACE).length() > 0) { + ccb.println(Options.stringValue("NAMESPACE_CLOSE")); } - builder.println("#endif"); - } catch (java.io.IOException e) { - context.errors().semantic_error("Could not open file " + context.globals().cu_name + "Constants.h for writing."); + ccb.println("#endif"); + } catch (final java.io.IOException e) { + context.errors() + .semantic_error( + "Could not open file " + context.globals().cu_name + "Constants.h for writing."); throw new Error(); } } - // Used by the CPP code generatror - private static void printCharArray(CppCodeBuilder builder, String s) { - builder.print("{"); + // Used by the CPP code generator + private static void printCharArray(final CppCodeBuilder ccb, final String s) { + ccb.print("{"); for (int i = 0; i < s.length(); i++) { - builder.print("0x" + Integer.toHexString(s.charAt(i)) + ", "); + ccb.print("0x" + Integer.toHexString(s.charAt(i)) + ", "); } - builder.print("0}"); + ccb.print("0}"); } } diff --git a/src/main/java/org/javacc/cpp/ParserCodeGenerator.java b/src/main/java/org/javacc/cpp/ParserCodeGenerator.java index 9e7ffff..c0b5441 100644 --- a/src/main/java/org/javacc/cpp/ParserCodeGenerator.java +++ b/src/main/java/org/javacc/cpp/ParserCodeGenerator.java @@ -1,19 +1,19 @@ -// Copyright 2011 Google Inc. All Rights Reserved. -// Author: sreeni@google.com (Sreeni Viswanadha) - /* - * Copyright (c) 2006, Sun Microsystems, Inc. All rights reserved. + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. * Redistributions in binary - * form must reproduce the above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or other materials provided - * with the distribution. * Neither the name of the Sun Microsystems, Inc. nor - * the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -24,13 +24,20 @@ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ - package org.javacc.cpp; - +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Map; import org.javacc.parser.Action; import org.javacc.parser.BNFProduction; import org.javacc.parser.Choice; @@ -57,924 +64,968 @@ import org.javacc.parser.ZeroOrOne; import org.javacc.utils.CodeBuilder; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -/** - * Generate the parser. - */ +/** Generate the parser. */ class ParserCodeGenerator implements org.javacc.parser.ParserCodeGenerator { - - /** - * These lists are used to maintain expansions for which code generation in - * phase 2 and phase 3 is required. Whenever a call is generated to a phase 2 - * or phase 3 routine, a corresponding entry is added here if it has not - * already been added. The phase 3 routines have been optimized in version - * 0.7pre2. Essentially only those methods (and only those portions of these - * methods) are generated that are required. The lookahead amount is used to - * determine this. This change requires the use of a hash table because it is - * now possible for the same phase 3 routine to be requested multiple times - * with different lookaheads. The hash table provides a easily searchable - * capability to determine the previous requests. The phase 3 routines now are - * performed in a two step process - the first step gathers the requests - * (replacing requests with lower lookaheads with those requiring larger - * lookaheads). The second step then generates these methods. This - * optimization and the hashtable makes it look like we do not need the flag - * "phase3done" any more. But this has not been removed yet. + /* + * These lists are used to maintain expansions for which code generation in phase 2 and phase 3 + * is required. + * Whenever a call is generated to a phase 2 or phase 3 routine, a corresponding entry is added + * here if it has not already been added. + * The phase 3 routines have been optimized in version 0.7pre2. + * Essentially only those methods (and only those portions of these methods) are generated + * that are required. + * The lookahead amount is used to determine this. + * This change requires the use of a hash table because it is now possible for the same phase 3 + * routine to be requested multiple times with different lookaheads. + * The hash table provides a easily searchable capability to determine the previous requests. + * The phase 3 routines nExpressionTreeConstantsow are performed in a two step process: + * - the first step gathers the requests (replacing requests with lower lookaheads with those + * requiring larger lookaheads), + * - the second step then generates these methods. */ - private final Context context; - private CppCodeBuilder codeGenerator; + private final List phase2list = new ArrayList<>(); + private final List phase3list = new ArrayList<>(); + private boolean jj2LA; + private final Hashtable phase3table = new Hashtable<>(); - private final Map internalNames = new HashMap<>(); + private final Context context; + private final Map internalNames = new HashMap<>(); private final Map internalIndexes = new HashMap<>(); - ParserCodeGenerator(Context context) { + private CppCodeBuilder ccb; + + ParserCodeGenerator(final Context context) { this.context = context; } - void printInclude(String include) { - if (include != null && include.length() > 0) { - if (include.charAt(0) == '<') { - codeGenerator.println("#include " + include); - } else { - codeGenerator.println("#include \"" + include + "\""); - } - } - } @Override - public void generateCode(CodeGeneratorSettings settings, ParserData parserData) { - List tn = new ArrayList<>(context.globals().toolNames); + public void generateCode(final CodeGeneratorSettings settings, final ParserData parserData) { + + final List tn = new ArrayList<>(context.globals().toolNames); tn.add(JavaCCGlobals.toolName); - File file = new File(Options.getOutputDirectory(), parserData.parserName + ".cc"); - codeGenerator = CppCodeBuilder.of(context, settings).setFile(file); + final File file = new File(Options.getOutputDirectory(), parserData.parserName + ".cc"); + ccb = CppCodeBuilder.of(context, settings).setFile(file); - if (context.globals().jjtreeGenerated) { - codeGenerator.switchToStaticsFile(); - codeGenerator.println("#include \"" + context.globals().cu_name + "Tree.h\"\n"); + ccb.switchToStaticsFile(); + ccb.println("#include \"" + context.globals().cu_name + "Tree.h\"\n"); } - codeGenerator.switchToIncludeFile(); - String guard = "JAVACC_" + parserData.parserName.toUpperCase() + "_H"; - codeGenerator.println("#ifndef " + guard); - codeGenerator.println("#define " + guard); - codeGenerator.println(); - + ccb.switchToIncludeFile(); + final String guard = "JAVACC_" + parserData.parserName.toUpperCase() + "_H"; + ccb.println("#ifndef " + guard); + ccb.println("#define " + guard); + ccb.println(); + if (!Options.getLibrary().isEmpty()) { - codeGenerator.println("#include \"ImportExport.h\""); - } - codeGenerator.println("#include \"JavaCC.h\""); - codeGenerator.println("#include \"CharStream.h\""); - codeGenerator.println("#include \"Token.h\""); - codeGenerator.println("#include \"TokenManager.h\""); - if (!Options.getTokenInclude().isEmpty()) { - codeGenerator.println("#include \"" + Options.getTokenInclude() +"\""); + ccb.println("#include \"ImportExport.h\""); } + ccb.println("#include \"JavaCC.h\""); + ccb.println("#include \"CharStream.h\""); + ccb.println("#include \"Token.h\""); + ccb.println("#include \"TokenManager.h\""); + printInclude(Options.getTokenInclude()); printInclude(Options.getParserInclude()); if (Options.getTokenConstantsInclude().isEmpty()) { - codeGenerator.println("#include \"" + context.globals().cu_name + "Constants.h\""); + ccb.println("#include \"" + context.globals().cu_name + "Constants.h\""); } else { - codeGenerator.println("#include \"" + Options.getTokenConstantsInclude() + "\""); + ccb.println("#include \"" + Options.getTokenConstantsInclude() + "\" // user defined option"); } - if (context.globals().jjtreeGenerated) { - codeGenerator.println("#include \"JJT" + context.globals().cu_name + "State.h\""); + ccb.println("#include \"JJT" + context.globals().cu_name + "State.h\""); } - - codeGenerator.println("#include \"DefaultParserErrorHandler.h\""); - + ccb.println("#include \"DefaultParserErrorHandler.h\""); if (context.globals().jjtreeGenerated) { - codeGenerator.println("#include \"" + context.globals().cu_name + "Tree.h\""); + ccb.println("#include \"" + context.globals().cu_name + "Tree.h\""); } + ccb.println(); if (Options.hasNamespace()) { - codeGenerator.println("namespace " + Options.stringValue("NAMESPACE_OPEN")); + ccb.println("namespace " + Options.stringValue("NAMESPACE_OPEN") + " // user defined option"); + ccb.println(); } - codeGenerator.print(" struct "); + ccb.println("/* Base code I (.h) */"); + ccb.println(); + ccb.print("struct "); if (!Options.getLibrary().isEmpty()) { - codeGenerator.print(parserData.parserName.toUpperCase() + "_API "); - } - codeGenerator.println("JJCalls {"); - codeGenerator.println(" int gen;"); - codeGenerator.println(" int arg;"); - codeGenerator.println(" JJCalls* next;"); - codeGenerator.println(" Token* first;"); - codeGenerator.println(" ~JJCalls() { if (next) delete next; }"); - codeGenerator.println(" JJCalls() { next = nullptr; arg = 0; gen = -1; first = nullptr; }"); - codeGenerator.println(" };"); - codeGenerator.println(""); - - - codeGenerator.genClassStart("", context.globals().cu_name, new String[] {}, new String[0]); - - codeGenerator.switchToMainFile(); + ccb.print(parserData.parserName.toUpperCase() + "_API "); + } + ccb.println("JJCalls {"); + ccb.println(" int arg;"); + ccb.println(" int gen;"); + ccb.println(" Token* first;"); + ccb.println(" JJCalls* next;"); + ccb.println(" JJCalls() {"); + ccb.println(" arg = 0;"); + ccb.println(" gen = -1;"); + ccb.println(" first = nullptr;"); + ccb.println(" next = nullptr;"); + ccb.println(" }"); + ccb.println(" ~JJCalls() {"); + ccb.println(" if (next) delete next;"); + ccb.println(" }"); + ccb.println("};"); + ccb.println(); + + ccb.genClassStart("", context.globals().cu_name, new String[] {}, new String[0]); + + ccb.switchToMainFile(); + ccb.println("/* User code (parser_begin-parser_end section) */"); if (context.globals().cu_to_insertion_point_2.size() != 0) { - codeGenerator.printTokenSetup(context.globals().cu_to_insertion_point_2.get(0)); - for (Token token : context.globals().cu_to_insertion_point_2) { - codeGenerator.printToken(token); + ccb.printTokenSetup(context.globals().cu_to_insertion_point_2.get(0)); + for (final Token token : context.globals().cu_to_insertion_point_2) { + ccb.printToken(token); } } - - codeGenerator.switchToMainFile(); - if (Options.hasNamespace()) { - codeGenerator.println("namespace " + Options.stringValue("NAMESPACE_OPEN")); - } - - codeGenerator.println(""); - codeGenerator.println(""); - - build(codeGenerator); - - codeGenerator.switchToIncludeFile(); - codeGenerator.println(""); - codeGenerator.println("public: "); - codeGenerator.println(" void setErrorHandler(ParserErrorHandler* eh) {"); - codeGenerator.println(" if (delete_eh) delete errorHandler;"); - codeGenerator.println(" errorHandler = eh;"); - codeGenerator.println(" delete_eh = false;"); - codeGenerator.println(" }"); - codeGenerator.println(" const ParserErrorHandler* getErrorHandler() {"); - codeGenerator.println(" return errorHandler;"); - codeGenerator.println(" }"); - codeGenerator.println(" static const JJChar* getTokenImage(int kind) {"); - codeGenerator.println(" return kind >= 0 ? " + getTokenImages() + "[kind] : " + getTokenImages() + "[0];"); - codeGenerator.println(" }"); - codeGenerator.println(" static const JJChar* getTokenLabel(int kind) {"); - codeGenerator.println(" return kind >= 0 ? " + getTokenLabels() + "[kind] : " + getTokenLabels() + "[0];"); - codeGenerator.println(" }"); - codeGenerator.println(""); - codeGenerator.println(" TokenManager* token_source = nullptr;"); - codeGenerator.println(" CharStream* jj_input_stream = nullptr;"); - codeGenerator.println(" Token* token = nullptr; // Current token."); - codeGenerator.println(" Token* jj_nt = nullptr; // Next token."); - codeGenerator.println(""); - codeGenerator.println("private: "); - codeGenerator.println(" int jj_ntk;"); - - codeGenerator.println(" JJCalls jj_2_rtns[" + (context.globals().jj2index + 1) + "];"); - codeGenerator.println(" bool jj_rescan;"); - codeGenerator.println(" int jj_gc;"); - codeGenerator.println(" Token* jj_scanpos;"); - codeGenerator.println(" Token* jj_lastpos;"); - codeGenerator.println(" int jj_la;"); - codeGenerator.println(" bool jj_lookingAhead; // Whether we are looking ahead."); - codeGenerator.println(" bool jj_semLA;"); - - codeGenerator.println(" int jj_gen;"); - codeGenerator.println(" int jj_la1[" + (context.globals().maskindex + 1) + "];"); - codeGenerator.println(" ParserErrorHandler* errorHandler = nullptr;"); - codeGenerator.println(""); - codeGenerator.println("protected: "); - codeGenerator.println(" bool delete_eh = false;"); - codeGenerator.println(" bool delete_tokens = true;"); - codeGenerator.println(" bool hasError;"); - codeGenerator.println(""); - int tokenMaskSize = ((context.globals().tokenCount - 1) / 32) + 1; - + ccb.println("namespace " + Options.stringValue("NAMESPACE_OPEN") + " // user defined option"); + } + ccb.println(); + ccb.println("/* Generated code for user productions (.cc) */"); + ccb.println(); + + ccb.switchToIncludeFile(); + ccb.println(); + ccb.println("/* Generated code for user productions (.h) */"); + ccb.println(); + + ccb.switchToMainFile(); + + build(); + + ccb.switchToMainFile(); + ccb.println(" /* Base code II (.cc) */"); + ccb.println(); + + ccb.switchToIncludeFile(); + ccb.println(); + ccb.println("/* Base code II (.h) */"); + ccb.println(); + ccb.println("public: "); + ccb.println(" void setErrorHandler(ParserErrorHandler* eh) {"); + ccb.println(" if (delete_eh) delete errorHandler;"); + ccb.println(" errorHandler = eh;"); + ccb.println(" delete_eh = false;"); + ccb.println(" }"); + ccb.println(); + ccb.println(" const ParserErrorHandler* getErrorHandler() {"); + ccb.println(" return errorHandler;"); + ccb.println(" }"); + ccb.println(); + ccb.println(" static const JJChar* getTokenImage(int kind) {"); + ccb.println( + " return kind >= 0 ? " + getTokenImages() + "[kind] : " + getTokenImages() + "[0];"); + ccb.println(" }"); + ccb.println(); + ccb.println(" static const JJChar* getTokenLabel(int kind) {"); + ccb.println( + " return kind >= 0 ? " + getTokenLabels() + "[kind] : " + getTokenLabels() + "[0];"); + ccb.println(" }"); + ccb.println(); + ccb.println(" TokenManager* token_source = nullptr;"); + ccb.println(" CharStream* jj_input_stream = nullptr;"); + ccb.println(" Token* token = nullptr; // Current token."); + ccb.println(" Token* jj_nt = nullptr; // Next token."); + ccb.println(); + ccb.println("private: "); + ccb.println(" int jj_ntk;"); + + ccb.println(" JJCalls jj_2_rtns[" + (context.globals().jj2index + 1) + "];"); + ccb.println(" bool jj_rescan;"); + ccb.println(" int jj_gc;"); + ccb.println(" Token* jj_scanpos;"); + ccb.println(" Token* jj_lastpos;"); + ccb.println(" int jj_la;"); + ccb.println(" bool jj_lookingAhead; // Whether we are looking ahead."); + ccb.println(" bool jj_semLA;"); + + ccb.println(" int jj_gen;"); + ccb.println(" int jj_la1[" + (context.globals().maskindex + 1) + "];"); + ccb.println(" ParserErrorHandler* errorHandler = nullptr;"); + ccb.println(); + ccb.println("protected: "); + ccb.println(" bool delete_eh = false;"); + ccb.println(" bool delete_tokens = true;"); + ccb.println(" bool hasError;"); + ccb.println(); + + final int tokenMaskSize = ((context.globals().tokenCount - 1) / 32) + 1; if (Options.getErrorReporting() && (tokenMaskSize > 0)) { - codeGenerator.switchToStaticsFile(); - codeGenerator.println("#include \"TokenManagerError.h\""); + ccb.switchToStaticsFile(); + ccb.println("#include \"TokenManagerError.h\""); + ccb.println(); + ccb.println("/* Base code I (.cc, static) */"); + ccb.println(); for (int i = 0; i < tokenMaskSize; i++) { if (context.globals().maskVals.size() > 0) { - codeGenerator.println("static unsigned int jj_la1_" + i + "[] = {"); - for (int[] tokenMask : context.globals().maskVals) { - codeGenerator.print("0x" + Integer.toHexString(tokenMask[i]) + ","); + ccb.println("static unsigned int jj_la1_" + i + "[] = {"); + int j = 0; + for (final int[] tokenMask : context.globals().maskVals) { + if (j > 0) { + ccb.print(", "); + } else { + j++; + ccb.print(" "); + } + ccb.print("0x" + Integer.toHexString(tokenMask[i])); } - codeGenerator.println("};"); + ccb.println(); + ccb.println("};"); } } + ccb.println(); } if (Options.getDepthLimit() > 0) { - codeGenerator.println(" private: int jj_depth;"); - codeGenerator.println(" private: bool jj_depth_error;"); - codeGenerator.println(" friend class __jj_depth_inc;"); - codeGenerator.println(" class __jj_depth_inc {public:"); - codeGenerator.println(" " + context.globals().cu_name + "* parent;"); - codeGenerator.println(" __jj_depth_inc(" + context.globals().cu_name + "* p): parent(p) { parent->jj_depth++; };"); - codeGenerator.println(" ~__jj_depth_inc(){ parent->jj_depth--; }"); - codeGenerator.println(" };"); + ccb.println(" private: int jj_depth;"); + ccb.println(" private: bool jj_depth_error;"); + ccb.println(" friend class __jj_depth_inc;"); + ccb.println(" class __jj_depth_inc {public:"); + ccb.println(" " + context.globals().cu_name + "* parent;"); + ccb.println( + " __jj_depth_inc(" + + context.globals().cu_name + + "* p): parent(p) { parent->jj_depth++; };"); + ccb.println(" ~__jj_depth_inc(){ parent->jj_depth--; }"); + ccb.println(" };"); + ccb.println(); } - if (!Options.getStackLimit().equals("")) { - codeGenerator.println(" public: size_t jj_stack_limit;"); - codeGenerator.println(" private: void* jj_stack_base;"); - codeGenerator.println(" private: bool jj_stack_error;"); - } - - codeGenerator.println(""); - - codeGenerator.println(" /** Constructor with user supplied TokenManager. */"); - codeGenerator.switchToIncludeFile(); // TEMP - codeGenerator.println(" Token* head;"); - codeGenerator.println(""); - codeGenerator.println("public: "); - codeGenerator.generateMethodDefHeader(" ", context.globals().cu_name, - context.globals().cu_name + "(TokenManager* tokenManager)"); - codeGenerator.println("{"); - codeGenerator.println(" head = nullptr;"); - codeGenerator.println(" ReInit(tokenManager);"); + if (!Options.getStackLimit().equals("")) { + ccb.println(" public: size_t jj_stack_limit;"); + ccb.println(" private: void* jj_stack_base;"); + ccb.println(" private: bool jj_stack_error;"); + ccb.println(); + } + + ccb.switchToIncludeFile(); // TEMP + ccb.println(" Token* head;"); + ccb.println(); + ccb.println("public: "); + + ccb.generateMethodDefHeader( + "", context.globals().cu_name, context.globals().cu_name + "(TokenManager* tokenManager)"); + ccb.println(" {"); + ccb.println(" head = nullptr;"); + ccb.println(" ReInit(tokenManager);"); if (Options.getTokenManagerUsesParser()) { - codeGenerator.println(" tokenManager->setParser(this);"); - } - codeGenerator.println("}"); - - codeGenerator.switchToIncludeFile(); - codeGenerator.println(" virtual ~" + context.globals().cu_name + "();"); - codeGenerator.switchToMainFile(); - codeGenerator.println(context.globals().cu_name + "::~" + context.globals().cu_name + "()"); - codeGenerator.println("{"); - codeGenerator.println(" clear();"); - codeGenerator.println("}"); - codeGenerator.generateMethodDefHeader("void", context.globals().cu_name, "ReInit(TokenManager* tokenManager)"); - codeGenerator.println("{"); - codeGenerator.println(" clear();"); - codeGenerator.println(" errorHandler = new DefaultParserErrorHandler();"); - codeGenerator.println(" delete_eh = true;"); - codeGenerator.println(" hasError = false;"); - codeGenerator.println(" token_source = tokenManager;"); - codeGenerator.println(" head = token = new " + getTokenType() + ";"); - codeGenerator.println(" jj_lookingAhead = false;"); - codeGenerator.println(" jj_rescan = false;"); - codeGenerator.println(" jj_done = false;"); - codeGenerator.println(" jj_scanpos = jj_lastpos = nullptr;"); - codeGenerator.println(" jj_gc = 0;"); - codeGenerator.println(" jj_kind = -1;"); - codeGenerator.println(" indent = 0;"); - codeGenerator.println(" trace = " + Options.getDebugParser() + ";"); + ccb.println(" tokenManager->setParser(this);"); + } + ccb.println("}"); + ccb.println(); + + ccb.switchToIncludeFile(); + ccb.println(" virtual ~" + context.globals().cu_name + "();"); + ccb.println(); + ccb.switchToMainFile(); + ccb.print(context.globals().cu_name + "::~" + context.globals().cu_name + "()"); + ccb.println(" {"); + ccb.println(" clear();"); + ccb.println("}"); + ccb.println(); + + ccb.generateMethodDefHeader( + "void", context.globals().cu_name, "ReInit(TokenManager* tokenManager)"); + ccb.println("{"); + ccb.println(" clear();"); + ccb.println(" errorHandler = new DefaultParserErrorHandler();"); + ccb.println(" delete_eh = true;"); + ccb.println(" hasError = false;"); + ccb.println(" token_source = tokenManager;"); + ccb.println(" head = token = new " + getTokenType() + ";"); + ccb.println(" jj_lookingAhead = false;"); + ccb.println(" jj_rescan = false;"); + ccb.println(" jj_done = false;"); + ccb.println(" jj_scanpos = jj_lastpos = nullptr;"); + ccb.println(" jj_gc = 0;"); + ccb.println(" jj_kind = -1;"); + ccb.println(" indent = 0;"); + ccb.println(" trace = " + Options.getDebugParser() + ";"); if (!Options.getStackLimit().equals("")) { - codeGenerator.println(" jj_stack_limit = " + Options.getStackLimit() + ";"); - codeGenerator.println(" jj_stack_error = jj_stack_check(true);"); + ccb.println(" jj_stack_limit = " + Options.getStackLimit() + ";"); + ccb.println(" jj_stack_error = jj_stack_check(true);"); } if (Options.getCacheTokens()) { - codeGenerator.println(" token->next() = jj_nt = token_source->getNextToken();"); + ccb.println(" token->next() = jj_nt = token_source->getNextToken();"); } else { - codeGenerator.println(" jj_ntk = -1;"); + ccb.println(" jj_ntk = -1;"); } if (context.globals().jjtreeGenerated) { - codeGenerator.println(" jjtree.reset();"); + ccb.println(" jjtree.reset();"); } if (Options.getDepthLimit() > 0) { - codeGenerator.println(" jj_depth = 0;"); - codeGenerator.println(" jj_depth_error = false;"); + ccb.println(" jj_depth = 0;"); + ccb.println(" jj_depth_error = false;"); } if (Options.getErrorReporting()) { - codeGenerator.println(" jj_gen = 0;"); + ccb.println(" jj_gen = 0;"); if (context.globals().maskindex > 0) { - codeGenerator.println(" for (int i = 0; i < " + context.globals().maskindex + "; i++) jj_la1[i] = -1;"); - } - } - codeGenerator.println(" }"); - codeGenerator.println(""); - - codeGenerator.generateMethodDefHeader("void", context.globals().cu_name, "clear()"); - codeGenerator.println("{"); - codeGenerator.println(" //Since token manager was generate from outside,"); - codeGenerator.println(" //parser should not take care of deleting"); - codeGenerator.println(" //if (token_source) delete token_source;"); - codeGenerator.println(" if (delete_tokens && head) {"); - codeGenerator.println(" Token* next;"); - codeGenerator.println(" Token* t = head;"); - codeGenerator.println(" while (t) {"); - codeGenerator.println(" next = t->next();"); - codeGenerator.println(" delete t;"); - codeGenerator.println(" t = next;"); - codeGenerator.println(" }"); - codeGenerator.println(" }"); - codeGenerator.println(" if (delete_eh) {"); - codeGenerator.println(" delete errorHandler, errorHandler = nullptr;"); - codeGenerator.println(" delete_eh = false;"); - codeGenerator.println(" }"); + ccb.println( + " for (int i = 0; i < " + context.globals().maskindex + "; i++) { jj_la1[i] = -1; }"); + } + } + ccb.println("}"); + ccb.println(); + + ccb.generateMethodDefHeader("void", context.globals().cu_name, "clear()"); + ccb.println("{"); + ccb.println( + " // Since token manager was generated from outside, parser should not take care of deleting it"); + ccb.println(" // if (token_source) delete token_source;"); + ccb.println(" if (delete_tokens && head) {"); + ccb.println(" Token* next;"); + ccb.println(" Token* t = head;"); + ccb.println(" while (t) {"); + ccb.println(" next = t->next();"); + ccb.println(" delete t;"); + ccb.println(" t = next;"); + ccb.println(" }"); + ccb.println(" }"); + ccb.println(" if (delete_eh) {"); + ccb.println(" delete errorHandler, errorHandler = nullptr;"); + ccb.println(" delete_eh = false;"); + ccb.println(" }"); if (Options.getDepthLimit() > 0) { - codeGenerator.println(" assert(jj_depth==0);"); + ccb.println(" assert(jj_depth==0);"); } - codeGenerator.println("}"); - codeGenerator.println(""); + ccb.println("}"); + ccb.println(); if (!Options.getStackLimit().equals("")) { - codeGenerator.println(""); - codeGenerator.switchToIncludeFile(); - codeGenerator.println(" virtual"); - codeGenerator.switchToMainFile(); - codeGenerator.generateMethodDefHeader("bool ", context.globals().cu_name, "jj_stack_check(bool init)"); - codeGenerator.println(" {"); - codeGenerator.println(" if(init) {"); - codeGenerator.println(" jj_stack_base = nullptr;"); - codeGenerator.println(" return false;"); - codeGenerator.println(" } else {"); - codeGenerator.println(" volatile int q = 0;"); - codeGenerator.println(" if(!jj_stack_base) {"); - codeGenerator.println(" jj_stack_base = (void*)&q;"); - codeGenerator.println(" return false;"); - codeGenerator.println(" } else {"); - codeGenerator.println(" // Stack can grow in both directions, depending on arch"); - codeGenerator.println(" std::ptrdiff_t used = (char*)jj_stack_base-(char*)&q;"); - codeGenerator.println(" return (std::abs(used) > jj_stack_limit);"); - codeGenerator.println(" }"); - codeGenerator.println(" }"); - codeGenerator.println(" }"); - } - - - codeGenerator.generateMethodDefHeader("Token* ", context.globals().cu_name, "jj_consume_token(int kind)"); - codeGenerator.println(" {"); + ccb.println(); + ccb.switchToIncludeFile(); + ccb.println(" virtual"); + ccb.switchToMainFile(); + ccb.generateMethodDefHeader("bool", context.globals().cu_name, "jj_stack_check(bool init)"); + ccb.println(" {"); + ccb.println(" if (init) {"); + ccb.println(" jj_stack_base = nullptr;"); + ccb.println(" return false;"); + ccb.println(" } else {"); + ccb.println(" volatile int q = 0;"); + ccb.println(" if (!jj_stack_base) {"); + ccb.println(" jj_stack_base = (void*)&q;"); + ccb.println(" return false;"); + ccb.println(" } else {"); + ccb.println(" // Stack can grow in both directions, depending on arch"); + ccb.println(" std::ptrdiff_t used = (char*)jj_stack_base-(char*)&q;"); + ccb.println(" return (std::abs(used) > jj_stack_limit);"); + ccb.println(" }"); + ccb.println(" }"); + ccb.println("}"); + } + + ccb.generateMethodDefHeader("Token*", context.globals().cu_name, "jj_consume_token(int kind)"); + ccb.println(" {"); if (!Options.getStackLimit().equals("")) { - codeGenerator.println(" if(kind != -1 && (jj_stack_error || jj_stack_check(false))) {"); - codeGenerator.println(" if (!jj_stack_error) {"); - codeGenerator.println(" errorHandler->otherError(\"Stack overflow while trying to parse\");"); - codeGenerator.println(" jj_stack_error=true;"); - codeGenerator.println(" }"); - codeGenerator.println(" return jj_consume_token(-1);"); - codeGenerator.println(" }"); + ccb.println(" if (kind != -1 && (jj_stack_error || jj_stack_check(false))) {"); + ccb.println(" if (!jj_stack_error) {"); + ccb.println(" errorHandler->otherError(\"Stack overflow while trying to parse\");"); + ccb.println(" jj_stack_error=true;"); + ccb.println(" }"); + ccb.println(" return jj_consume_token(-1);"); + ccb.println(" }"); } if (Options.getCacheTokens()) { - codeGenerator.println(" Token* oldToken = token;"); - codeGenerator.println(" if ((token = jj_nt)->next() != nullptr) jj_nt = jj_nt->next();"); - codeGenerator.println(" else jj_nt = jj_nt->next() = token_source->getNextToken();"); + ccb.println(" Token* oldToken = token;"); + ccb.println(" if ((token = jj_nt)->next() != nullptr) jj_nt = jj_nt->next();"); + ccb.println(" else jj_nt = jj_nt->next() = token_source->getNextToken();"); } else { - codeGenerator.println(" Token* oldToken;"); - codeGenerator.println(" if ((oldToken = token)->next() != nullptr) token = token->next();"); - codeGenerator.println(" else token = token->next() = token_source->getNextToken();"); - codeGenerator.println(" jj_ntk = -1;"); + ccb.println(" Token* oldToken;"); + ccb.println(" if ((oldToken = token)->next() != nullptr) token = token->next();"); + ccb.println(" else token = token->next() = token_source->getNextToken();"); + ccb.println(" jj_ntk = -1;"); } - codeGenerator.println(" if (token->kind() == kind) {"); + ccb.println(" if (token->kind() == kind) {"); if (Options.getErrorReporting()) { - codeGenerator.println(" jj_gen++;"); + ccb.println(" jj_gen++;"); if (context.globals().jj2index != 0) { - codeGenerator.println(" if (++jj_gc > 100) {"); - codeGenerator.println(" jj_gc = 0;"); - codeGenerator.println(" for (int i = 0; i < " + context.globals().jj2index + "; i++) {"); - codeGenerator.println(" JJCalls *c = &jj_2_rtns[i];"); - codeGenerator.println(" while (c != nullptr) {"); - codeGenerator.println(" if (c->gen < jj_gen) c->first = nullptr;"); - codeGenerator.println(" c = c->next;"); - codeGenerator.println(" }"); - codeGenerator.println(" }"); - codeGenerator.println(" }"); + ccb.println(" if (++jj_gc > 100) {"); + ccb.println(" jj_gc = 0;"); + ccb.println(" for (int i = 0; i < " + context.globals().jj2index + "; i++) {"); + ccb.println(" JJCalls *c = &jj_2_rtns[i];"); + ccb.println(" while (c != nullptr) {"); + ccb.println(" if (c->gen < jj_gen) c->first = nullptr;"); + ccb.println(" c = c->next;"); + ccb.println(" }"); + ccb.println(" }"); + ccb.println(" }"); } } if (Options.getDebugParser()) { - codeGenerator.println(" trace_token(token, \"\");"); + ccb.println(" trace_token(token, \"\");"); } - codeGenerator.println(" return token;"); - codeGenerator.println(" }"); + ccb.println(" return token;"); + ccb.println(" }"); if (Options.getCacheTokens()) { - codeGenerator.println(" jj_nt = token;"); + ccb.println(" jj_nt = token;"); } - codeGenerator.println(" token = oldToken;"); + ccb.println(" token = oldToken;"); if (Options.getErrorReporting()) { - codeGenerator.println(" jj_kind = kind;"); + ccb.println(" jj_kind = kind;"); } - // codeGenerator.genCodeLine(" throw generateParseException();"); + // codeGen.genCodeLine(" throw generateParseException();"); if (!Options.getStackLimit().equals("")) { - codeGenerator.println(" if (!jj_stack_error) {"); + ccb.println(" if (!jj_stack_error) {"); } - codeGenerator.println(" const JJString expectedImage = getTokenImage(kind);"); - codeGenerator.println(" const JJString expectedLabel = getTokenLabel(kind);"); + ccb.println(" const JJString expectedImage = getTokenImage(kind);"); + ccb.println(" const JJString expectedLabel = getTokenLabel(kind);"); - codeGenerator.println(" const Token* actualToken = getToken(1);"); - codeGenerator.println(" const JJString actualImage = getTokenImage(actualToken->kind());"); - codeGenerator.println(" const JJString actualLabel = getTokenLabel(actualToken->kind());"); - codeGenerator.println( - " errorHandler->unexpectedToken(expectedImage, expectedLabel, actualImage, actualLabel, actualToken);"); + ccb.println(" const Token* actualToken = getToken(1);"); + ccb.println(" const JJString actualImage = getTokenImage(actualToken->kind());"); + ccb.println(" const JJString actualLabel = getTokenLabel(actualToken->kind());"); + ccb.println( + " errorHandler->unexpectedToken(expectedImage, expectedLabel, actualImage, actualLabel, actualToken);"); if (!Options.getStackLimit().equals("")) { - codeGenerator.println(" }"); + ccb.println(" }"); } - codeGenerator.println(" hasError = true;"); - codeGenerator.println(" return token;"); - codeGenerator.println(" }"); - codeGenerator.println(""); + ccb.println(" hasError = true;"); + ccb.println(" return token;"); + ccb.println("}"); + ccb.println(); if (context.globals().jj2index != 0) { - codeGenerator.switchToMainFile(); - codeGenerator.generateMethodDefHeader("bool ", context.globals().cu_name, "jj_scan_token(int kind)"); - codeGenerator.println("{"); + ccb.switchToMainFile(); + ccb.generateMethodDefHeader("bool", context.globals().cu_name, "jj_scan_token(int kind)"); + ccb.println(" {"); if (!Options.getStackLimit().equals("")) { - codeGenerator.println(" if(kind != -1 && (jj_stack_error || jj_stack_check(false))) {"); - codeGenerator.println(" if (!jj_stack_error) {"); - codeGenerator - .println(" errorHandler->otherError(\"Stack overflow while trying to parse\");"); - codeGenerator.println(" jj_stack_error=true;"); - codeGenerator.println(" }"); - codeGenerator.println(" return jj_consume_token(-1);"); - codeGenerator.println(" }"); - } - codeGenerator.println(" if (jj_scanpos == jj_lastpos) {"); - codeGenerator.println(" jj_la--;"); - codeGenerator.println(" if (jj_scanpos->next() == nullptr) {"); - codeGenerator.println(" jj_lastpos = jj_scanpos = jj_scanpos->next() = token_source->getNextToken();"); - codeGenerator.println(" } else {"); - codeGenerator.println(" jj_lastpos = jj_scanpos = jj_scanpos->next();"); - codeGenerator.println(" }"); - codeGenerator.println(" } else {"); - codeGenerator.println(" jj_scanpos = jj_scanpos->next();"); - codeGenerator.println(" }"); + ccb.println(" if (kind != -1 && (jj_stack_error || jj_stack_check(false))) {"); + ccb.println(" if (!jj_stack_error) {"); + ccb.println(" errorHandler->otherError(\"Stack overflow while trying to parse\");"); + ccb.println(" jj_stack_error=true;"); + ccb.println(" }"); + ccb.println(" return jj_consume_token(-1);"); + ccb.println(" }"); + } + ccb.println(" if (jj_scanpos == jj_lastpos) {"); + ccb.println(" jj_la--;"); + ccb.println(" if (jj_scanpos->next() == nullptr) {"); + ccb.println( + " jj_lastpos = jj_scanpos = jj_scanpos->next() = token_source->getNextToken();"); + ccb.println(" } else {"); + ccb.println(" jj_lastpos = jj_scanpos = jj_scanpos->next();"); + ccb.println(" }"); + ccb.println(" } else {"); + ccb.println(" jj_scanpos = jj_scanpos->next();"); + ccb.println(" }"); if (Options.getErrorReporting()) { - codeGenerator.println(" if (jj_rescan) {"); - codeGenerator.println(" int i = 0; Token* tok = token;"); - codeGenerator.println(" while (tok != nullptr && tok != jj_scanpos) { i++; tok = tok->next(); }"); - codeGenerator.println(" if (tok != nullptr) jj_add_error_token(kind, i);"); + ccb.println(" if (jj_rescan) {"); + ccb.println(" int i = 0; Token* tok = token;"); + ccb.println(" while (tok != nullptr && tok != jj_scanpos) {"); + ccb.println(" i++;"); + ccb.println(" tok = tok->next();"); + ccb.println(" }"); + ccb.println(" if (tok != nullptr) jj_add_error_token(kind, i);"); if (Options.getDebugLookahead()) { - codeGenerator.println(" } else {"); - codeGenerator.println(" trace_scan(jj_scanpos, kind);"); + ccb.println(" } else {"); + ccb.println(" trace_scan(jj_scanpos, kind);"); } - codeGenerator.println(" }"); + ccb.println(" }"); } else if (Options.getDebugLookahead()) { - codeGenerator.println(" trace_scan(jj_scanpos, kind);"); + ccb.println(" trace_scan(jj_scanpos, kind);"); } - codeGenerator.println(" if (jj_scanpos->kind() != kind) return true;"); - // codeGenerator.genCodeLine(" if (jj_la == 0 && jj_scanpos == jj_lastpos) + ccb.println(" if (jj_scanpos->kind() != kind) return true;"); + // codeGen.genCodeLine(" if (jj_la == 0 && jj_scanpos == jj_lastpos) // throw jj_ls;"); - codeGenerator.println(" if (jj_la == 0 && jj_scanpos == jj_lastpos) { return jj_done = true; }"); - codeGenerator.println(" return false;"); - codeGenerator.println(" }"); - codeGenerator.println(""); - } - codeGenerator.println(""); - codeGenerator.println("/** Get the next Token. */"); - codeGenerator.generateMethodDefHeader("Token* ", context.globals().cu_name, "getNextToken()"); - codeGenerator.println("{"); + ccb.println(" if (jj_la == 0 && jj_scanpos == jj_lastpos) { return jj_done = true; }"); + ccb.println(" return false;"); + ccb.println("}"); + ccb.println(); + } + ccb.println(); + + ccb.println("/** Get the next Token. */"); + ccb.generateMethodDefHeader("Token*", context.globals().cu_name, "getNextToken()"); + ccb.println(" {"); if (Options.getCacheTokens()) { - codeGenerator.println(" if ((token = jj_nt)->next() != nullptr) jj_nt = jj_nt->next();"); - codeGenerator.println(" else jj_nt = jj_nt->next() = token_source->getNextToken();"); + ccb.println(" if ((token = jj_nt)->next() != nullptr) jj_nt = jj_nt->next();"); + ccb.println(" else jj_nt = jj_nt->next() = token_source->getNextToken();"); } else { - codeGenerator.println(" if (token->next() != nullptr) token = token->next();"); - codeGenerator.println(" else token = token->next() = token_source->getNextToken();"); - codeGenerator.println(" jj_ntk = -1;"); + ccb.println(" if (token->next() != nullptr) token = token->next();"); + ccb.println(" else token = token->next() = token_source->getNextToken();"); + ccb.println(" jj_ntk = -1;"); } if (Options.getErrorReporting()) { - codeGenerator.println(" jj_gen++;"); + ccb.println(" jj_gen++;"); } if (Options.getDebugParser()) { - codeGenerator.println(" trace_token(token, \" (in getNextToken)\");"); - } - codeGenerator.println(" return token;"); - codeGenerator.println(" }"); - codeGenerator.println(""); - codeGenerator.println("/** Get the specific Token. */"); - codeGenerator.generateMethodDefHeader("Token* ", context.globals().cu_name, "getToken(int index)"); - codeGenerator.println("{"); + ccb.println(" trace_token(token, \" (in getNextToken)\");"); + } + ccb.println(" return token;"); + ccb.println("}"); + ccb.println(); + + ccb.println("/** Get the specific Token. */"); + ccb.generateMethodDefHeader("Token*", context.globals().cu_name, "getToken(int index)"); + ccb.println(" {"); if (context.globals().lookaheadNeeded) { - codeGenerator.println(" Token* t = jj_lookingAhead ? jj_scanpos : token;"); + ccb.println(" Token* t = jj_lookingAhead ? jj_scanpos : token;"); } else { - codeGenerator.println(" Token* t = token;"); - } - codeGenerator.println(" for (int i = 0; i < index; i++) {"); - codeGenerator.println(" if (t->next() != nullptr) t = t->next();"); - codeGenerator.println(" else t = t->next() = token_source->getNextToken();"); - codeGenerator.println(" }"); - codeGenerator.println(" return t;"); - codeGenerator.println(" }"); - codeGenerator.println(""); + ccb.println(" Token* t = token;"); + } + ccb.println(" for (int i = 0; i < index; i++) {"); + ccb.println(" if (t->next() != nullptr) t = t->next();"); + ccb.println(" else t = t->next() = token_source->getNextToken();"); + ccb.println(" }"); + ccb.println(" return t;"); + ccb.println("}"); + ccb.println(); + if (!Options.getCacheTokens()) { - codeGenerator.generateMethodDefHeader("int", context.globals().cu_name, "jj_ntk_f()"); - codeGenerator.println("{"); + ccb.generateMethodDefHeader("int", context.globals().cu_name, "jj_ntk_f()"); + ccb.println(" {"); - codeGenerator.println(" if ((jj_nt=token->next()) == nullptr)"); - codeGenerator.println(" return (jj_ntk = (token->next()=token_source->getNextToken())->kind());"); - codeGenerator.println(" else"); - codeGenerator.println(" return (jj_ntk = jj_nt->kind());"); - codeGenerator.println(" }"); - codeGenerator.println(""); + ccb.println(" if ((jj_nt=token->next()) == nullptr)"); + ccb.println(" return (jj_ntk = (token->next() = token_source->getNextToken())->kind());"); + ccb.println(" else"); + ccb.println(" return (jj_ntk = jj_nt->kind());"); + ccb.println("}"); + ccb.println(); } - codeGenerator.switchToIncludeFile(); - codeGenerator.println("private:"); - codeGenerator.println(" int jj_kind;"); + ccb.switchToIncludeFile(); + ccb.println("private:"); + ccb.println(" int jj_kind;"); if (Options.getErrorReporting()) { - codeGenerator.println(" int** jj_expentries;"); - codeGenerator.println(" int* jj_expentry;"); + ccb.println(" int** jj_expentries;"); + ccb.println(" int* jj_expentry;"); + ccb.println(); if (context.globals().jj2index != 0) { - codeGenerator.switchToStaticsFile(); + ccb.switchToStaticsFile(); // For now we don't support ERROR_REPORTING in the C++ version. - // codeGenerator.genCodeLine(" static int *jj_lasttokens = new + // codeGen.genCodeLine(" static int *jj_lasttokens = new // int[100];"); - // codeGenerator.genCodeLine(" static int jj_endpos;"); - codeGenerator.println(""); + // codeGen.genCodeLine(" static int jj_endpos;"); + ccb.println(); - codeGenerator.generateMethodDefHeader(" void", context.globals().cu_name, "jj_add_error_token(int kind, int pos)"); - codeGenerator.println(" {"); + ccb.generateMethodDefHeader( + "void", context.globals().cu_name, "jj_add_error_token(int kind, int pos)"); + ccb.println(" {"); // For now we don't support ERROR_REPORTING in the C++ version. - // codeGenerator.genCodeLine(" if (pos >= 100) return;"); - // codeGenerator.genCodeLine(" if (pos == jj_endpos + 1) {"); - // codeGenerator.genCodeLine(" jj_lasttokens[jj_endpos++] = kind;"); - // codeGenerator.genCodeLine(" } else if (jj_endpos != 0) {"); - // codeGenerator.genCodeLine(" jj_expentry = new int[jj_endpos];"); - // codeGenerator.genCodeLine(" for (int i = 0; i < jj_endpos; i++) {"); - // codeGenerator.genCodeLine(" jj_expentry[i] = jj_lasttokens[i];"); - // codeGenerator.genCodeLine(" }"); - // codeGenerator.genCodeLine(" jj_entries_loop: for (java.util.Iterator + // codeGen.genCodeLine(" if (pos >= 100) return;"); + // codeGen.genCodeLine(" if (pos == jj_endpos + 1) {"); + // codeGen.genCodeLine(" jj_lasttokens[jj_endpos++] = kind;"); + // codeGen.genCodeLine(" } else if (jj_endpos != 0) {"); + // codeGen.genCodeLine(" jj_expentry = new int[jj_endpos];"); + // codeGen.genCodeLine(" for (int i = 0; i < jj_endpos; i++) {"); + // codeGen.genCodeLine(" jj_expentry[i] = jj_lasttokens[i];"); + // codeGen.genCodeLine(" }"); + // codeGen.genCodeLine(" jj_entries_loop: for (java.util.Iterator // it = jj_expentries.iterator(); it.hasNext();) {"); - // codeGenerator.genCodeLine(" int[] oldentry = (int[])(it->next());"); - // codeGenerator.genCodeLine(" if (oldentry.length == + // codeGen.genCodeLine(" int[] oldentry = (int[])(it->next());"); + // codeGen.genCodeLine(" if (oldentry.length == // jj_expentry.length) {"); - // codeGenerator.genCodeLine(" for (int i = 0; i < jj_expentry.length; + // codeGen.genCodeLine(" for (int i = 0; i < jj_expentry.length; // i++) {"); - // codeGenerator.genCodeLine(" if (oldentry[i] != jj_expentry[i]) {"); - // codeGenerator.genCodeLine(" continue jj_entries_loop;"); - // codeGenerator.genCodeLine(" }"); - // codeGenerator.genCodeLine(" }"); - // codeGenerator.genCodeLine(" jj_expentries.add(jj_expentry);"); - // codeGenerator.genCodeLine(" break jj_entries_loop;"); - // codeGenerator.genCodeLine(" }"); - // codeGenerator.genCodeLine(" }"); - // codeGenerator.genCodeLine(" if (pos != 0) jj_lasttokens[(jj_endpos = + // codeGen.genCodeLine(" if (oldentry[i] != jj_expentry[i]) {"); + // codeGen.genCodeLine(" continue jj_entries_loop;"); + // codeGen.genCodeLine(" }"); + // codeGen.genCodeLine(" }"); + // codeGen.genCodeLine(" jj_expentries.add(jj_expentry);"); + // codeGen.genCodeLine(" break jj_entries_loop;"); + // codeGen.genCodeLine(" }"); + // codeGen.genCodeLine(" }"); + // codeGen.genCodeLine(" if (pos != 0) jj_lasttokens[(jj_endpos = // pos) - 1] = kind;"); - // codeGenerator.genCodeLine(" }"); - codeGenerator.println(" }"); + // codeGen.genCodeLine(" }"); + ccb.println("}"); + ccb.println(); } - codeGenerator.println(""); - codeGenerator.switchToIncludeFile(); - codeGenerator.println("protected:"); - codeGenerator.println(" /** Generate ParseException. */"); - codeGenerator.generateMethodDefHeader(" virtual void ", context.globals().cu_name, "parseError()"); - codeGenerator.println(" {"); + ccb.switchToIncludeFile(); + ccb.println("protected:"); + ccb.println(" /** Generate ParseException. */"); + ccb.generateMethodDefHeader("virtual void", context.globals().cu_name, "parseError()"); + ccb.println(" {"); if (Options.getErrorReporting()) { - codeGenerator.println( - " JJERR << JJWIDE(Parse error at : ) << token->beginLine() << JJWIDE(:) << token->beginColumn() << JJWIDE( after token: ) << addUnicodeEscapes(token->image()) << JJWIDE( encountered: ) << addUnicodeEscapes(getToken(1)->image()) << std::endl;"); + ccb.println( + " JJERR << JJWIDE(Parse error at : ) << token->beginLine() << JJWIDE(:) << token->beginColumn() << JJWIDE( after token: ) << addUnicodeEscapes(token->image()) << JJWIDE( encountered: ) << addUnicodeEscapes(getToken(1)->image()) << std::endl;"); } - codeGenerator.println(" }"); + ccb.println("}"); /* * generateMethodDefHeader("ParseException", cu_name, - * "generateParseException()"); codeGenerator.genCodeLine(" {"); - * //codeGenerator.genCodeLine(" jj_expentries.clear();"); - * //codeGenerator.genCodeLine(" bool[] la1tokens = new boolean[" + + * "generateParseException()"); codeGen.genCodeLine(" {"); + * //codeGen.genCodeLine(" jj_expentries.clear();"); + * //codeGen.genCodeLine(" bool[] la1tokens = new boolean[" + * tokenCount + "];"); - * //codeGenerator.genCodeLine(" if (jj_kind >= 0) {"); - * //codeGenerator.genCodeLine(" la1tokens[jj_kind] = true;"); - * //codeGenerator.genCodeLine(" jj_kind = -1;"); - * //codeGenerator.genCodeLine(" }"); - * //codeGenerator.genCodeLine(" for (int i = 0; i < " + maskindex + + * //codeGen.genCodeLine(" if (jj_kind >= 0) {"); + * //codeGen.genCodeLine(" la1tokens[jj_kind] = true;"); + * //codeGen.genCodeLine(" jj_kind = -1;"); + * //codeGen.genCodeLine(" }"); + * //codeGen.genCodeLine(" for (int i = 0; i < " + maskindex + * "; i++) {"); - * //codeGenerator.genCodeLine(" if (jj_la1[i] == jj_gen) {"); - * //codeGenerator.genCodeLine(" for (int j = 0; j < 32; j++) {"); + * //codeGen.genCodeLine(" if (jj_la1[i] == jj_gen) {"); + * //codeGen.genCodeLine(" for (int j = 0; j < 32; j++) {"); * //for (int i = 0; i < (tokenCount-1)/32 + 1; i++) { - * //codeGenerator.genCodeLine(" if ((jj_la1_" + i + + * //codeGen.genCodeLine(" if ((jj_la1_" + i + * "[i] & (1<beginLine() << JJWIDE(:) " - + "<< token->beginColumn() << JJWIDE( after token: ) << addUnicodeEscapes(token->image())" - + " << JJWIDE( encountered: ) << addUnicodeEscapes(getToken(1)->image()) << std::endl;"); + ccb.println( + " JJERR << " + + "JJWIDE(Parse error at : ) << token->beginLine() << JJWIDE(:) " + + "<< token->beginColumn() << JJWIDE( after token: ) << addUnicodeEscapes(token->image())" + + " << JJWIDE( encountered: ) << addUnicodeEscapes(getToken(1)->image()) << std::endl;"); } - codeGenerator.println(" }"); + ccb.println("}"); /* * generateMethodDefHeader("ParseException", cu_name, - * "generateParseException()"); codeGenerator.genCodeLine(" {"); - * codeGenerator.genCodeLine(" Token* errortok = token->next();"); if - * (Options.getKeepLineColumn()) codeGenerator. + * "generateParseException()"); codeGen.genCodeLine(" {"); + * codeGen.genCodeLine(" Token* errortok = token->next();"); if + * (Options.getKeepLineColumn()) codeGen. * genCodeLine(" int line = errortok.beginLine, column = errortok.beginColumn;" - * ); codeGenerator. + * ); codeGen. * genCodeLine(" JJString mess = (errortok->kind() == 0) ? tokenImages[0] : errortok->image();" * ); if (Options.getKeepLineColumn()) - * codeGenerator.genCodeLine(" return new _ParseException();");// + + * codeGen.genCodeLine(" return new _ParseException();");// + * //"\"Parse error at line \" + line + \", column \" + column + \". " + * //"Encountered: \" + mess);"); else - * codeGenerator.genCodeLine(" return new _ParseException();");// + * codeGen.genCodeLine(" return new _ParseException();");// * \"Parse error at . " + - * //"Encountered: \" + mess);"); codeGenerator.genCodeLine(" }"); + * //"Encountered: \" + mess);"); codeGen.genCodeLine(" }"); */ } - codeGenerator.println(""); - - codeGenerator.switchToIncludeFile(); - codeGenerator.println("private:"); - codeGenerator.println(" int indent; // trace indentation"); - codeGenerator.println(" bool trace = " + Options.getDebugParser() + ";"); - codeGenerator.println(" bool trace_la = " + Options.getDebugLookahead() + ";" ); - codeGenerator.println(""); - codeGenerator.println("public:"); - codeGenerator.generateMethodDefHeader(" bool", context.globals().cu_name, "trace_enabled()"); - codeGenerator.println(" {"); - codeGenerator.println(" return trace;"); - codeGenerator.println(" }"); - codeGenerator.println(""); - codeGenerator.generateMethodDefHeader(" bool", context.globals().cu_name, "trace_la_enabled()"); - codeGenerator.println(" {"); - codeGenerator.println(" return trace_la;"); - codeGenerator.println(" }"); - codeGenerator.println(""); + ccb.println(); + + ccb.switchToIncludeFile(); + ccb.println("private:"); + ccb.println(" int indent; // trace indentation"); + ccb.println(" bool trace = " + Options.getDebugParser() + ";"); + ccb.println(" bool trace_la = " + Options.getDebugLookahead() + ";"); + ccb.println(); + ccb.println("public:"); + ccb.generateMethodDefHeader("bool", context.globals().cu_name, "trace_enabled()"); + ccb.println(" {"); + ccb.println(" return trace;"); + ccb.println("}"); + ccb.println(); + ccb.generateMethodDefHeader("bool", context.globals().cu_name, "trace_la_enabled()"); + ccb.println(" {"); + ccb.println(" return trace_la;"); + ccb.println("}"); + ccb.println(); if (Options.getDebugParser()) { - codeGenerator.switchToIncludeFile(); - codeGenerator.generateMethodDefHeader(" void", context.globals().cu_name, "enable_tracing()"); - codeGenerator.println("{"); - codeGenerator.println(" trace = true;"); - codeGenerator.println("}"); - codeGenerator.println(""); - - codeGenerator.switchToIncludeFile(); - codeGenerator.generateMethodDefHeader(" void", context.globals().cu_name, "disable_tracing()"); - codeGenerator.println("{"); - codeGenerator.println(" trace = false;"); - codeGenerator.println("}"); - codeGenerator.println(""); - - codeGenerator.switchToIncludeFile(); - codeGenerator.generateMethodDefHeader(" void", context.globals().cu_name, "trace_call(const char *s)"); - codeGenerator.println(" {"); - codeGenerator.println(" if (trace_enabled()) {"); - codeGenerator.println(" for (int no = 0; no < indent; no++) { JJLOG << JJSPACE; }"); - codeGenerator.println(" JJLOG << \"Call: \" << s << std::endl;"); - codeGenerator.println(" }"); - codeGenerator.println(" indent += 2;"); - codeGenerator.println(" }"); - codeGenerator.println(""); - - codeGenerator.switchToIncludeFile(); - codeGenerator.generateMethodDefHeader(" void", context.globals().cu_name, "trace_return(const char *s)"); - codeGenerator.println(" {"); - codeGenerator.println(" indent -= 2;"); - codeGenerator.println(" if (trace_enabled()) {"); - codeGenerator.println(" for (int no = 0; no < indent; no++) { JJLOG << JJSPACE; }"); - codeGenerator.println(" JJLOG << \"Return: \" << s << std::endl;"); - codeGenerator.println(" }"); - codeGenerator.println(" }"); - codeGenerator.println(""); - - codeGenerator.switchToIncludeFile(); - codeGenerator.generateMethodDefHeader(" void", context.globals().cu_name, "trace_token(const Token* token, const char* where)"); - codeGenerator.println(" {"); - codeGenerator.println(" if (trace_enabled()) {"); - codeGenerator.println(" for (int no = 0; no < indent; no++) { JJLOG << JJSPACE; }"); - codeGenerator.print(" JJLOG << JJWIDE(Consumed token: ) << addUnicodeEscapes("); - codeGenerator.print(getTokenLabels()); - codeGenerator.println("[token->kind()]) << JJCOMMA << JJSPACE << JJQUOTE << addUnicodeEscapes(token->image()) << JJQUOTE;"); - codeGenerator.println( - " JJLOG << JJSPACE << JJWIDE(at) << JJSPACE << token->beginLine() << JJWIDE(:) << token->beginColumn() << *where << std::endl;"); - codeGenerator.println(" }"); - codeGenerator.println(" }"); - codeGenerator.println(""); - - codeGenerator.switchToIncludeFile(); - codeGenerator.generateMethodDefHeader(" void", context.globals().cu_name, "trace_scan(const Token* token, int t2)"); - codeGenerator.println(" {"); - codeGenerator.println(" if (trace_la_enabled()) {"); - codeGenerator.println(" for (int no = 0; no < indent; no++) { JJLOG << JJSPACE; }"); - codeGenerator.print(" JJLOG << JJWIDE(Visited token: ) << addUnicodeEscapes("); - codeGenerator.print(getTokenLabels()); - codeGenerator.println("[token->kind()]) << JJCOMMA << JJSPACE << JJQUOTE << addUnicodeEscapes(token->image()) << JJQUOTE;"); - codeGenerator.println( - " JJLOG << JJSPACE << JJWIDE(at) << JJSPACE << token->beginLine() << JJWIDE(:) << token->beginColumn() << JJCOMMA << JJSPACE << JJWIDE(Expected token: ) << addUnicodeEscapes(" - + getTokenLabels() + "[t2]) << std::endl;"); - codeGenerator.println(" }"); - codeGenerator.println(" }"); - codeGenerator.println(""); - + ccb.switchToIncludeFile(); + ccb.generateMethodDefHeader("void", context.globals().cu_name, "enable_tracing()"); + ccb.println(" {"); + ccb.println(" trace = true;"); + ccb.println("}"); + ccb.println(); + + ccb.switchToIncludeFile(); + ccb.generateMethodDefHeader("void", context.globals().cu_name, "disable_tracing()"); + ccb.println(" {"); + ccb.println(" trace = false;"); + ccb.println("}"); + ccb.println(); + + ccb.switchToIncludeFile(); + ccb.generateMethodDefHeader("void", context.globals().cu_name, "trace_call(const char *s)"); + ccb.println(" {"); + ccb.println(" if (trace_enabled()) {"); + ccb.println(" for (int no = 0; no < indent; no++) { JJLOG << JJSPACE; }"); + ccb.println(" JJLOG << \"Call: \" << s << std::endl;"); + ccb.println(" }"); + ccb.println(" indent += 2;"); + ccb.println("}"); + ccb.println(); + + ccb.switchToIncludeFile(); + ccb.generateMethodDefHeader("void", context.globals().cu_name, "trace_return(const char *s)"); + ccb.println(" {"); + ccb.println(" indent -= 2;"); + ccb.println(" if (trace_enabled()) {"); + ccb.println(" for (int no = 0; no < indent; no++) { JJLOG << JJSPACE; }"); + ccb.println(" JJLOG << \"Return: \" << s << std::endl;"); + ccb.println(" }"); + ccb.println("}"); + ccb.println(); + + ccb.switchToIncludeFile(); + ccb.generateMethodDefHeader( + "void", context.globals().cu_name, "trace_token(const Token* token, const char* where)"); + ccb.println(" {"); + ccb.println(" if (trace_enabled()) {"); + ccb.println(" for (int no = 0; no < indent; no++) { JJLOG << JJSPACE; }"); + ccb.println(" JJLOG << JJWIDE(Consumed token: <) << token->kind() << JJCOMMA << JJSPACE"); + ccb.println( + " << JJDBQUOTE << addUnicodeEscapes(" + + getTokenImages() + + "[token->kind()]) << JJDBQUOTE;"); + ccb.println( + " if (token->kind() != 0 && " + + getTokenImages() + + "[token->kind()] != token->image()) {"); + ccb.println( + " JJLOG << JJSPACE << JJDBQUOTE << addUnicodeEscapes(token->image()) << JJDBQUOTE;"); + ccb.println(" }"); + ccb.println(" JJLOG << JJWIDE(> at) << JJSPACE << token->beginLine() << JJWIDE(:)"); + ccb.println(" << token->beginColumn() << *where << std::endl;"); + ccb.println(" }"); + ccb.println("}"); + ccb.println(); + + ccb.switchToIncludeFile(); + ccb.generateMethodDefHeader( + "void", context.globals().cu_name, "trace_scan(const Token* token, int t2)"); + ccb.println(" {"); + ccb.println(" if (trace_la_enabled()) {"); + ccb.println(" for (int no = 0; no < indent; no++) { JJLOG << JJSPACE; }"); + ccb.println(" JJLOG << JJWIDE(Visited token: <) << token->kind() << JJCOMMA << JJSPACE"); + ccb.println( + " << JJDBQUOTE << addUnicodeEscapes(" + + getTokenImages() + + "[token->kind()]) << JJDBQUOTE;"); + ccb.println( + " if (token->kind() != 0 && " + + getTokenImages() + + "[token->kind()] != token->image()) {"); + ccb.println( + " JJLOG << JJSPACE << JJDBQUOTE << addUnicodeEscapes(token->image()) << JJDBQUOTE;"); + ccb.println(" }"); + ccb.println(" JJLOG << JJWIDE(> at) << JJSPACE << token->beginLine() << JJWIDE(:)"); + ccb.print(" << token->beginColumn() << JJWIDE(; Expected token: <)"); + ccb.println(" << t2 << JJCOMMA << JJSPACE"); + ccb.println( + " << addUnicodeEscapes(" + + getTokenLabels() + + "[t2]) << JJWIDE(>) << std::endl;"); + ccb.println(" }"); + ccb.println("}"); + ccb.println(); + } else { - codeGenerator.switchToIncludeFile(); - codeGenerator.generateMethodDefHeader(" void", context.globals().cu_name, "enable_tracing()"); - codeGenerator.println(" {"); - codeGenerator.println(" }"); - codeGenerator.switchToIncludeFile(); - codeGenerator.generateMethodDefHeader(" void", context.globals().cu_name, "disable_tracing()"); - codeGenerator.println(" {"); - codeGenerator.println(" }"); - codeGenerator.println(""); - } + ccb.switchToIncludeFile(); + ccb.generateMethodDefHeader("void", context.globals().cu_name, "enable_tracing()"); + ccb.println(" {"); + ccb.println("}"); + ccb.switchToIncludeFile(); + ccb.generateMethodDefHeader("void", context.globals().cu_name, "disable_tracing()"); + ccb.println(" {"); + ccb.println("}"); + ccb.println(); + } if (Options.getDebugLookahead()) { - codeGenerator.switchToIncludeFile(); - codeGenerator.generateMethodDefHeader(" void", context.globals().cu_name, "enable_la_tracing()"); - codeGenerator.println("{"); - codeGenerator.println(" trace_la = true;"); - codeGenerator.println("}"); - codeGenerator.println(""); - - codeGenerator.switchToIncludeFile(); - codeGenerator.generateMethodDefHeader(" void", context.globals().cu_name, "disable_la_tracing()"); - codeGenerator.println("{"); - codeGenerator.println(" trace_la = false;"); - codeGenerator.println("}"); - codeGenerator.println(""); - - codeGenerator.switchToIncludeFile(); - codeGenerator.generateMethodDefHeader(" void", context.globals().cu_name, "trace_la_call(const char *s)"); - codeGenerator.println(" {"); - codeGenerator.println(" if (trace_la_enabled()) {"); - codeGenerator.println(" for (int no = 0; no < indent; no++) { JJLOG << JJSPACE; }"); - codeGenerator.println(" JJLOG << \"Call: \" << s << std::endl;"); - codeGenerator.println(" }"); - codeGenerator.println(" indent += 2;"); - codeGenerator.println(" }"); - codeGenerator.println(""); - - codeGenerator.switchToIncludeFile(); - codeGenerator.generateMethodDefHeader(" void", context.globals().cu_name, "trace_la_return(const char *s)"); - codeGenerator.println(" {"); - codeGenerator.println(" indent -= 2;"); - codeGenerator.println(" if (trace_la_enabled()) {"); - codeGenerator.println(" for (int no = 0; no < indent; no++) { JJLOG << JJSPACE; }"); - codeGenerator.println(" JJLOG << \"Return: \" << s << std::endl;"); - codeGenerator.println(" }"); - codeGenerator.println(" }"); - codeGenerator.println(""); + ccb.switchToIncludeFile(); + ccb.generateMethodDefHeader("void", context.globals().cu_name, "enable_la_tracing()"); + ccb.println(" {"); + ccb.println(" trace_la = true;"); + ccb.println("}"); + ccb.println(); + + ccb.switchToIncludeFile(); + ccb.generateMethodDefHeader("void", context.globals().cu_name, "disable_la_tracing()"); + ccb.println(" {"); + ccb.println(" trace_la = false;"); + ccb.println("}"); + ccb.println(); + + ccb.switchToIncludeFile(); + ccb.generateMethodDefHeader( + "void", context.globals().cu_name, "trace_la_call(const char *s)"); + ccb.println(" {"); + ccb.println(" if (trace_la_enabled()) {"); + ccb.println(" for (int no = 0; no < indent; no++) { JJLOG << JJSPACE; }"); + ccb.println(" JJLOG << \"Call: \" << s << std::endl;"); + ccb.println(" }"); + ccb.println(" indent += 2;"); + ccb.println("}"); + ccb.println(); + + ccb.switchToIncludeFile(); + ccb.generateMethodDefHeader( + "void", context.globals().cu_name, "trace_la_return(const char *s)"); + ccb.println(" {"); + ccb.println(" indent -= 2;"); + ccb.println(" if (trace_la_enabled()) {"); + ccb.println(" for (int no = 0; no < indent; no++) { JJLOG << JJSPACE; }"); + ccb.println(" JJLOG << \"Return: \" << s << std::endl;"); + ccb.println(" }"); + ccb.println("}"); + ccb.println(); } else { - codeGenerator.switchToIncludeFile(); - codeGenerator.generateMethodDefHeader(" void", context.globals().cu_name, "enable_la_tracing()"); - codeGenerator.println(" {"); - codeGenerator.println(" }"); - codeGenerator.switchToIncludeFile(); - codeGenerator.generateMethodDefHeader(" void", context.globals().cu_name, "disable_la_tracing()"); - codeGenerator.println(" {"); - codeGenerator.println(" }"); - codeGenerator.println(""); - } + ccb.switchToIncludeFile(); + ccb.generateMethodDefHeader("void", context.globals().cu_name, "enable_la_tracing()"); + ccb.println(" {"); + ccb.println("}"); + ccb.switchToIncludeFile(); + ccb.generateMethodDefHeader("void", context.globals().cu_name, "disable_la_tracing()"); + ccb.println(" {"); + ccb.println("}"); + ccb.println(); + } if ((context.globals().jj2index != 0) && Options.getErrorReporting()) { - codeGenerator.generateMethodDefHeader(" void", context.globals().cu_name, "jj_rescan_token()"); - codeGenerator.println("{"); - codeGenerator.println(" jj_rescan = true;"); - codeGenerator.println(" for (int i = 0; i < " + context.globals().jj2index + "; i++) {"); - // codeGenerator.genCodeLine(" try {"); - codeGenerator.println(" JJCalls *p = &jj_2_rtns[i];"); - codeGenerator.println(" do {"); - codeGenerator.println(" if (p->gen > jj_gen) {"); - codeGenerator.println(" jj_la = p->arg; jj_lastpos = jj_scanpos = p->first;"); - codeGenerator.println(" switch (i) {"); + ccb.generateMethodDefHeader("void", context.globals().cu_name, "jj_rescan_token()"); + ccb.println(" {"); + ccb.println(" jj_rescan = true;"); + ccb.println(" for (int i = 0; i < " + context.globals().jj2index + "; i++) {"); + // codeGen.genCodeLine(" try {"); + ccb.println(" JJCalls *p = &jj_2_rtns[i];"); + ccb.println(" do {"); + ccb.println(" if (p->gen > jj_gen) {"); + ccb.println(" jj_la = p->arg;"); + ccb.println(" jj_lastpos = jj_scanpos = p->first;"); + ccb.println(" switch (i) {"); for (int i = 0; i < context.globals().jj2index; i++) { - codeGenerator.println(" case " + i + ": jj_3_" + (i + 1) + "(); break;"); - } - codeGenerator.println(" }"); - codeGenerator.println(" }"); - codeGenerator.println(" p = p->next;"); - codeGenerator.println(" } while (p != nullptr);"); - // codeGenerator.genCodeLine(" } catch(LookaheadSuccess ls) { }"); - codeGenerator.println(" }"); - codeGenerator.println(" jj_rescan = false;"); - codeGenerator.println(" }"); - codeGenerator.println(""); - - codeGenerator.generateMethodDefHeader(" void", context.globals().cu_name, "jj_save(int index, int xla)"); - codeGenerator.println("{"); - codeGenerator.println(" JJCalls *p = &jj_2_rtns[index];"); - codeGenerator.println(" while (p->gen > jj_gen) {"); - codeGenerator.println(" if (p->next == nullptr) { p = p->next = new JJCalls(); break; }"); - codeGenerator.println(" p = p->next;"); - codeGenerator.println(" }"); - codeGenerator.println(" p->gen = jj_gen + xla - jj_la; p->first = token; p->arg = xla;"); - codeGenerator.println(" }"); - codeGenerator.println(""); + ccb.println(" case " + i + ":"); + ccb.println(" jj_3_" + (i + 1) + "();"); + ccb.println(" break;"); + } + ccb.println(" }"); + ccb.println(" }"); + ccb.println(" p = p->next;"); + ccb.println(" } while (p != nullptr);"); + // codeGen.genCodeLine(" } catch(LookaheadSuccess ls) { }"); + ccb.println(" }"); + ccb.println(" jj_rescan = false;"); + ccb.println("}"); + ccb.println(); + + ccb.generateMethodDefHeader("void", context.globals().cu_name, "jj_save(int index, int xla)"); + ccb.println(" {"); + ccb.println(" JJCalls *p = &jj_2_rtns[index];"); + ccb.println(" while (p->gen > jj_gen) {"); + ccb.println(" if (p->next == nullptr) {"); + ccb.println(" p = p->next = new JJCalls();"); + ccb.println(" break;"); + ccb.println(" }"); + ccb.println(" p = p->next;"); + ccb.println(" }"); + ccb.println(" p->gen = jj_gen + xla - jj_la;"); + ccb.println(" p->first = token;"); + ccb.println(" p->arg = xla;"); + ccb.println("}"); + ccb.println(); } if (context.globals().cu_from_insertion_point_2.size() != 0) { Token t = null; - codeGenerator.printTokenSetup((context.globals().cu_from_insertion_point_2.get(0))); - for (Iterator it = context.globals().cu_from_insertion_point_2.iterator(); it.hasNext();) { + ccb.printTokenSetup((context.globals().cu_from_insertion_point_2.get(0))); + for (final Iterator it = context.globals().cu_from_insertion_point_2.iterator(); + it.hasNext(); ) { t = it.next(); - codeGenerator.printToken(t); + ccb.printToken(t); } - codeGenerator.printTrailingComments(t); + ccb.printTrailingComments(t); + ccb.println(); } - codeGenerator.println(""); // in the include file close the class signature - codeGenerator.switchToIncludeFile(); + ccb.switchToIncludeFile(); // copy other stuff Token t1 = context.globals().otherLanguageDeclTokenBeg; - Token t2 = context.globals().otherLanguageDeclTokenEnd; + final Token t2 = context.globals().otherLanguageDeclTokenEnd; while (t1 != t2) { - codeGenerator.printToken(t1); + ccb.printToken(t1); t1 = t1.next; } - codeGenerator.println("\n"); + if (context.globals().jjtreeGenerated) { - codeGenerator.println(" JJT" + context.globals().cu_name + "State jjtree;"); + ccb.println(" JJT" + context.globals().cu_name + "State jjtree;"); + ccb.println(); } - codeGenerator.println("private:"); - codeGenerator.println(" bool jj_done;"); - codeGenerator.println("};"); + ccb.println("private:"); + ccb.println(" bool jj_done;"); + + ccb.println(); + ccb.println("};"); } -@Override - public void finish(CodeGeneratorSettings settings, ParserData parserData) { - if (Options.stringValue(Options.USEROPTION__CPP_NAMESPACE).length() > 0) { - codeGenerator.println(Options.stringValue("NAMESPACE_CLOSE")); - codeGenerator.println("#endif"); - codeGenerator.switchToMainFile(); - codeGenerator.println(Options.stringValue("NAMESPACE_CLOSE")); + void printInclude(final String userInclude) { + if (userInclude != null && userInclude.length() > 0) { + if (userInclude.charAt(0) == '<') { + ccb.println("#include " + userInclude + " // user defined option"); + } else { + ccb.println("#include \"" + userInclude + "\" // user defined option"); + } + } + } + + @Override + public void finish(final CodeGeneratorSettings settings, final ParserData parserData) { + if (Options.stringValue(Options.UO__NAMESPACE).length() > 0) { + ccb.println(Options.stringValue("NAMESPACE_CLOSE")); + ccb.println("#endif"); + ccb.switchToMainFile(); + ccb.println(Options.stringValue("NAMESPACE_CLOSE")); } else { - codeGenerator.println("#endif"); + ccb.println("#endif"); } try { - codeGenerator.close(); - } catch (IOException e) { + ccb.close(); + } catch (final IOException e) { throw new Error(e); } } - private int gensymindex = 0; - private int indentamt; - private boolean jj2LA; - - /** - * These lists are used to maintain expansions for which code generation in - * phase 2 and phase 3 is required. Whenever a call is generated to a phase 2 - * or phase 3 routine, a corresponding entry is added here if it has not - * already been added. The phase 3 routines have been optimized in version - * 0.7pre2. Essentially only those methods (and only those portions of these - * methods) are generated that are required. The lookahead amount is used to - * determine this. This change requires the use of a hash table because it is - * now possible for the same phase 3 routine to be requested multiple times - * with different lookaheads. The hash table provides a easily searchable - * capability to determine the previous requests. The phase 3 routines now are - * performed in a two step process - the first step gathers the requests - * (replacing requests with lower lookaheads with those requiring larger - * lookaheads). The second step then generates these methods. This - * optimization and the hashtable makes it look like we do not need the flag - * "phase3done" any more. But this has not been removed yet. + * Returns true if there is a JAVACODE production that the argument expansion may directly expand + * to (without consuming tokens or encountering lookahead). */ - private final List phase2list = new ArrayList<>(); - private final List phase3list = new ArrayList<>(); - private final Hashtable phase3table = new Hashtable<>(); - - /** - * The phase 1 routines generates their output into String's and dumps these - * String's once for each method. These String's contain the special - * characters '\u0001' to indicate a positive indent, and '\u0002' to indicate - * a negative indent. '\n' is used to indicate a line terminator. The - * characters '\u0003' and '\u0004' are used to delineate portions of text - * where '\n's should not be followed by an indentation. - */ - - /** - * Returns true if there is a JAVACODE production that the argument expansion - * may directly expand to (without consuming tokens or encountering - * lookahead). - */ - private boolean javaCodeCheck(Expansion exp) { + private boolean javaCodeCheck(final Expansion exp) { if (exp instanceof RegularExpression) { return false; } else if (exp instanceof NonTerminal) { - NormalProduction prod = ((NonTerminal) exp).getProd(); + final NormalProduction prod = ((NonTerminal) exp).getProd(); if (prod instanceof CodeProduction) { return true; } else { return javaCodeCheck(prod.getExpansion()); } } else if (exp instanceof Choice) { - Choice ch = (Choice) exp; - for (Expansion element : ch.getChoices()) { + final Choice ch = (Choice) exp; + for (final Expansion element : ch.getChoices()) { if (javaCodeCheck(element)) { return true; } } return false; } else if (exp instanceof Sequence) { - Sequence seq = (Sequence) exp; + final Sequence seq = (Sequence) exp; for (int i = 0; i < seq.units.size(); i++) { - Expansion[] units = seq.units.toArray(new Expansion[seq.units.size()]); + final Expansion[] units = seq.units.toArray(new Expansion[seq.units.size()]); if ((units[i] instanceof Lookahead) && ((Lookahead) units[i]).isExplicit()) { // An explicit lookahead (rather than one generated implicitly). // Assume @@ -989,16 +1040,16 @@ private boolean javaCodeCheck(Expansion exp) { } return false; } else if (exp instanceof OneOrMore) { - OneOrMore om = (OneOrMore) exp; + final OneOrMore om = (OneOrMore) exp; return javaCodeCheck(om.getExpansion()); } else if (exp instanceof ZeroOrMore) { - ZeroOrMore zm = (ZeroOrMore) exp; + final ZeroOrMore zm = (ZeroOrMore) exp; return javaCodeCheck(zm.getExpansion()); } else if (exp instanceof ZeroOrOne) { - ZeroOrOne zo = (ZeroOrOne) exp; + final ZeroOrOne zo = (ZeroOrOne) exp; return javaCodeCheck(zo.getExpansion()); } else if (exp instanceof TryBlock) { - TryBlock tb = (TryBlock) exp; + final TryBlock tb = (TryBlock) exp; return javaCodeCheck(tb.exp); } else { return false; @@ -1006,17 +1057,16 @@ private boolean javaCodeCheck(Expansion exp) { } /** - * An array used to store the first sets generated by the following method. A - * true entry means that the corresponding token is in the first set. + * An array used to store the first sets generated by the following method. A true entry means + * that the corresponding token is in the first set. */ private boolean[] firstSet; /** - * Sets up the array "firstSet" above based on the Expansion argument passed - * to it. Since this is a recursive function, it assumes that "firstSet" has - * been reset before the first call. + * Sets up the array "firstSet" above based on the Expansion argument passed to it. Since this is + * a recursive function, it assumes that "firstSet" has been reset before the first call. */ - private void genFirstSet(Expansion exp) { + private void genFirstSet(final Expansion exp) { if (exp instanceof RegularExpression) { firstSet[((RegularExpression) exp).ordinal] = true; } else if (exp instanceof NonTerminal) { @@ -1024,26 +1074,27 @@ private void genFirstSet(Expansion exp) { genFirstSet(((BNFProduction) ((NonTerminal) exp).getProd()).getExpansion()); } } else if (exp instanceof Choice) { - Choice ch = (Choice) exp; - for (Expansion element : ch.getChoices()) { + final Choice ch = (Choice) exp; + for (final Expansion element : ch.getChoices()) { genFirstSet(element); } } else if (exp instanceof Sequence) { - Sequence seq = (Sequence) exp; - Object obj = seq.units.get(0); + final Sequence seq = (Sequence) exp; + final Object obj = seq.units.get(0); if ((obj instanceof Lookahead) && (((Lookahead) obj).getActionTokens().size() != 0)) { jj2LA = true; } for (int i = 0; i < seq.units.size(); i++) { - Expansion unit = seq.units.get(i); + final Expansion unit = seq.units.get(i); // Javacode productions can not have FIRST sets. Instead we generate the // FIRST set // for the preceding LOOKAHEAD (the semantic checks should have made // sure that // the LOOKAHEAD is suitable). - if ((unit instanceof NonTerminal) && (((NonTerminal) unit).getProd() instanceof CodeProduction)) { + if ((unit instanceof NonTerminal) + && (((NonTerminal) unit).getProd() instanceof CodeProduction)) { if ((i > 0) && (seq.units.get(i - 1) instanceof Lookahead)) { - Lookahead la = (Lookahead) seq.units.get(i - 1); + final Lookahead la = (Lookahead) seq.units.get(i - 1); genFirstSet(la.getLaExpansion()); } } else { @@ -1054,51 +1105,61 @@ private void genFirstSet(Expansion exp) { } } } else if (exp instanceof OneOrMore) { - OneOrMore om = (OneOrMore) exp; + final OneOrMore om = (OneOrMore) exp; genFirstSet(om.getExpansion()); } else if (exp instanceof ZeroOrMore) { - ZeroOrMore zm = (ZeroOrMore) exp; + final ZeroOrMore zm = (ZeroOrMore) exp; genFirstSet(zm.getExpansion()); } else if (exp instanceof ZeroOrOne) { - ZeroOrOne zo = (ZeroOrOne) exp; + final ZeroOrOne zo = (ZeroOrOne) exp; genFirstSet(zo.getExpansion()); } else if (exp instanceof TryBlock) { - TryBlock tb = (TryBlock) exp; + final TryBlock tb = (TryBlock) exp; genFirstSet(tb.exp); } } - /** - * Constants used in the following method "buildLookaheadChecker". - */ - private final int NOOPENSTM = 0; - private final int OPENIF = 1; + /* Constants used in the following method "buildLookaheadChecker". */ + private final int NOOPENSTM = 0; + private final int OPENIF = 1; private final int OPENSWITCH = 2; + /* + * The phase 1 routines generates their output into String's and dumps these String's once for + * each method. + * These String's contain the special characters '\u0001' to indicate a positive indent, + * and '\u0002' to indicate a negative indent. + * '\n' is used to indicate a line terminator. + * The characters '\u0003' and '\u0004' are used to delineate portions of text where '\n's + * should not be followed by an indentation. + */ + /** - * This method takes two parameters - an array of Lookahead's "conds", and an - * array of String's "actions". "actions" contains exactly one element more - * than "conds". "actions" are Java source code, and "conds" translate to - * conditions - so lets say "f(conds[i])" is true if the lookahead required by - * "conds[i]" is indeed the case. This method returns a string corresponding - * to the Java code for: - * - * if (f(conds[0]) actions[0] else if (f(conds[1]) actions[1] . . . else - * actions[action.length-1] - * - * A particular action entry ("actions[i]") can be null, in which case, a noop - * is generated for that action. + * This method takes two parameters - an array of Lookahead's "conds", and an array + * of String's "actions".
+ * "actions" contains exactly one element more than "conds".
+ * "actions" are Java source code, and "conds" translate to conditions + *
+ * - so lets say "f(conds[i])" is true if the lookahead required by " + * conds[i] + * " is indeed the case.
+ * This method returns a string corresponding to the Java code for:
+ * + * if (f(conds[0]) actions[0]
else if (f(conds[1]) actions[1]
. . .
else actions[action.length-1] + *

+ * A particular action entry ("actions[i]") can be null, in which case, + * a noop is generated for that action. */ - private String buildLookaheadChecker(Lookahead[] conds, String[] actions) { + private String buildLookaheadChecker(final Lookahead[] conds, final String[] actions) { // The state variables. int state = NOOPENSTM; int indentAmt = 0; - boolean[] casedValues = new boolean[context.globals().tokenCount]; + final boolean[] casedValues = new boolean[context.globals().tokenCount]; String retval = ""; Lookahead la; Token t = null; - int tokenMaskSize = ((context.globals().tokenCount - 1) / 32) + 1; + final int tokenMaskSize = ((context.globals().tokenCount - 1) / 32) + 1; int[] tokenMask = null; // Iterate over all the conditions. @@ -1108,28 +1169,24 @@ private String buildLookaheadChecker(Lookahead[] conds, String[] actions) { la = conds[index]; jj2LA = false; - if ((la.getAmount() == 0) || Semanticize.emptyExpansionExists(la.getLaExpansion()) + if ((la.getAmount() == 0) + || Semanticize.emptyExpansionExists(la.getLaExpansion()) || javaCodeCheck(la.getLaExpansion())) { // This handles the following cases: - // . If syntactic lookahead is not wanted (and hence explicitly - // specified - // as 0). - // . If it is possible for the lookahead expansion to recognize the - // empty - // string - in which case the lookahead trivially passes. - // . If the lookahead expansion has a JAVACODE production that it - // directly - // expands to - in which case the lookahead trivially passes. + // . If syntactic lookahead is not wanted (and hence explicitly specified as 0). + // . If it is possible for the lookahead expansion to recognize the empty string + // - in which case the lookahead trivially passes. + // . If the lookahead expansion has a JAVACODE production that it directly expands to + // - in which case the lookahead trivially passes. if (la.getActionTokens().size() == 0) { - // In addition, if there is no semantic lookahead, then the - // lookahead trivially succeeds. So break the main loop and - // treat this case as the default last action. + // In addition, if there is no semantic lookahead, then the lookahead trivially succeeds. + // So break the main loop and treat this case as the default last action. break; } else { // This case is when there is only semantic lookahead - // (without any preceding syntactic lookahead). In this - // case, an "if" statement is generated. + // (without any preceding syntactic lookahead). + // In this case, an "if" statement is generated. switch (state) { case NOOPENSTM: retval += "\n" + "if ("; @@ -1139,7 +1196,7 @@ private String buildLookaheadChecker(Lookahead[] conds, String[] actions) { retval += "\u0002\n" + "} else if ("; break; case OPENSWITCH: - retval += "\u0002\n" + "default:" + "\u0001"; + retval += "\n" + "default:" + "\u0001"; if (Options.getErrorReporting()) { retval += "\njj_la1[" + context.globals().maskindex + "] = jj_gen;"; context.globals().maskindex++; @@ -1148,19 +1205,19 @@ private String buildLookaheadChecker(Lookahead[] conds, String[] actions) { retval += "\n" + "if ("; indentAmt++; } - codeGenerator.printTokenSetup(la.getActionTokens().get(0)); - for (Iterator it = la.getActionTokens().iterator(); it.hasNext();) { + ccb.printTokenSetup(la.getActionTokens().get(0)); + for (final Iterator it = la.getActionTokens().iterator(); it.hasNext(); ) { t = it.next(); retval += CodeBuilder.toString(t); } - retval += codeGenerator.getTrailingComments(t); + retval += ccb.getTrailingComments(t); retval += ") {\u0001" + actions[index]; state = OPENIF; } } else if ((la.getAmount() == 1) && (la.getActionTokens().size() == 0)) { - // Special optimal processing when the lookahead is exactly 1, and there - // is no semantic lookahead. + // Special optimal processing when the lookahead is exactly 1 + // and there is no semantic lookahead. if (firstSet == null) { firstSet = new boolean[context.globals().tokenCount]; @@ -1168,20 +1225,16 @@ private String buildLookaheadChecker(Lookahead[] conds, String[] actions) { for (int i = 0; i < context.globals().tokenCount; i++) { firstSet[i] = false; } - // jj2LA is set to false at the beginning of the containing "if" - // statement. - // It is checked immediately after the end of the same statement to - // determine - // if lookaheads are to be performed using calls to the jj2 methods. + // jj2LA is set to false at the beginning of the containing "if" statement. + // It is checked immediately after the end of the same statement to determine + // if lookaheads are to be performed using calls to the jj2 methods. genFirstSet(la.getLaExpansion()); - // genFirstSet may find that semantic attributes are appropriate for the - // next - // token. In which case, it sets jj2LA to true. + // genFirstSet may find that semantic attributes are appropriate for the next token. + // In which case, it sets jj2LA to true. if (!jj2LA) { - // This case is if there is no applicable semantic lookahead and the - // lookahead - // is one (excluding the earlier cases such as JAVACODE, etc.). + // This case is if there is no applicable semantic lookahead and the lookahead is one + // (excluding the earlier cases such as JAVACODE, etc.). switch (state) { case OPENIF: retval += "\u0002\n" + "} else {\u0001"; @@ -1208,39 +1261,37 @@ private String buildLookaheadChecker(Lookahead[] conds, String[] actions) { if (firstSet[i]) { if (!casedValues[i]) { casedValues[i] = true; - retval += "\u0002\ncase "; - int j1 = i / 32; - int j2 = i % 32; + retval += "\ncase "; + final int j1 = i / 32; + final int j2 = i % 32; tokenMask[j1] |= 1 << j2; - String s = addTokenNamespace(context.globals().names_of_tokens.get(Integer.valueOf(i))); + final String s = + addTokenNamespace(context.globals().names_of_tokens.get(Integer.valueOf(i))); if (s == null) { retval += i; } else { retval += s; } - retval += ":\u0001"; + retval += " : \u0001"; } } } retval += "{"; retval += actions[index]; - retval += "\nbreak;\n}"; + retval += "\nbreak;\u0002\n}"; state = OPENSWITCH; - } } else { - // This is the case when lookahead is determined through calls to - // jj2 methods. The other case is when lookahead is 1, but semantic - // attributes need to be evaluated. Hence this crazy control structure. + // This is the case when lookahead is determined through calls to jj2 methods. + // The other case is when lookahead is 1, but semantic attributes need to be evaluated. + // Hence this crazy control structure. jj2LA = true; - } if (jj2LA) { // In this case lookahead is determined by the jj2 methods. - switch (state) { case NOOPENSTM: retval += "\n" + "if ("; @@ -1250,7 +1301,7 @@ private String buildLookaheadChecker(Lookahead[] conds, String[] actions) { retval += "\u0002\n" + "} else if ("; break; case OPENSWITCH: - retval += "\u0002\n" + "default:" + "\u0001"; + retval += "\n" + "default:" + "\u0001"; if (Options.getErrorReporting()) { retval += "\njj_la1[" + context.globals().maskindex + "] = jj_gen;"; context.globals().maskindex++; @@ -1266,22 +1317,22 @@ private String buildLookaheadChecker(Lookahead[] conds, String[] actions) { phase2list.add(la); String amount; if (la.getAmount() == Integer.MAX_VALUE) { - amount = "INT_MAX"; + amount = "INT_MAX"; } else { - amount = Integer.toString(la.getAmount()); + amount = Integer.toString(la.getAmount()); } - + retval += "jj_2" + internalNames.get(la.getLaExpansion()) + "(" + amount + ")"; if (la.getActionTokens().size() != 0) { - // In addition, there is also a semantic lookahead. So concatenate - // the semantic check with the syntactic one. + // In addition, there is also a semantic lookahead. + // So concatenate the semantic check with the syntactic one. retval += " && ("; - codeGenerator.printTokenSetup(la.getActionTokens().get(0)); - for (Iterator it = la.getActionTokens().iterator(); it.hasNext();) { + ccb.printTokenSetup(la.getActionTokens().get(0)); + for (final Iterator it = la.getActionTokens().iterator(); it.hasNext(); ) { t = it.next(); retval += CodeBuilder.toString(t); } - retval += codeGenerator.getTrailingComments(t); + retval += ccb.getTrailingComments(t); retval += ")"; } retval += ") {\u0001" + actions[index]; @@ -1291,9 +1342,8 @@ private String buildLookaheadChecker(Lookahead[] conds, String[] actions) { index++; } - // Generate code for the default case. Note this may not - // be the last entry of "actions" if any condition can be - // statically determined to be always "true". + // Generate code for the default case. Note this may not be the last entry of "actions" + // if any condition can be statically determined to be always "true". switch (state) { case NOOPENSTM: @@ -1303,23 +1353,25 @@ private String buildLookaheadChecker(Lookahead[] conds, String[] actions) { retval += "\u0002\n" + "} else {\u0001" + actions[index]; break; case OPENSWITCH: - retval += "\u0002\n" + "default:" + "\u0001"; + retval += "\n" + "default:" + "\u0001"; if (Options.getErrorReporting()) { retval += "\njj_la1[" + context.globals().maskindex + "] = jj_gen;"; context.globals().maskVals.add(tokenMask); context.globals().maskindex++; } retval += actions[index]; + retval += "\u0002"; } for (int i = 0; i < indentAmt; i++) { retval += "\u0002\n}"; } return retval; - } - private void dumpFormattedString(String str) { + private int indentamt; + + private void dumpFormattedString(final String str) { char ch = ' '; char prevChar; boolean indentOn = true; @@ -1333,7 +1385,7 @@ private void dumpFormattedString(String str) { if (indentOn) { phase1NewLine(); } else { - codeGenerator.println(""); + ccb.println(); } } else if (ch == '\u0001') { indentamt += 2; @@ -1344,22 +1396,22 @@ private void dumpFormattedString(String str) { } else if (ch == '\u0004') { indentOn = true; } else { - codeGenerator.print(ch); + ccb.print(ch); } } } - // Print method header and return the ERROR_RETURN string. - private String generateCPPMethodheader(BNFProduction p, Token t) { - StringBuffer sig = new StringBuffer(); + /** Print method header and return the ERROR_RETURN string. */ + private String generateCPPMethodheader(final BNFProduction p, Token t) { + final StringBuffer sig = new StringBuffer(); String ret, params; - String method_name = p.getLhs(); + final String method_name = p.getLhs(); boolean void_ret = false; boolean ptr_ret = false; - codeGenerator.printTokenSetup(t); - codeGenerator.getLeadingComments(t); + ccb.printTokenSetup(t); + ccb.getLeadingComments(t); sig.append(t.image); if (t.kind == JavaCCParserConstants.VOID) { void_ret = true; @@ -1379,24 +1431,25 @@ private String generateCPPMethodheader(BNFProduction p, Token t) { } } - codeGenerator.getTrailingComments(t); + ccb.getTrailingComments(t); ret = sig.toString(); sig.setLength(0); sig.append("("); if (p.getParameterListTokens().size() != 0) { - codeGenerator.printTokenSetup(p.getParameterListTokens().get(0)); - for (Iterator it = p.getParameterListTokens().iterator(); it.hasNext();) { + ccb.printTokenSetup(p.getParameterListTokens().get(0)); + for (final Iterator it = p.getParameterListTokens().iterator(); it.hasNext(); ) { t = it.next(); sig.append(CodeBuilder.toString(t)); } - sig.append(codeGenerator.getTrailingComments(t)); + sig.append(ccb.getTrailingComments(t)); } sig.append(")"); params = sig.toString(); // For now, just ignore comments - codeGenerator.generateMethodDefHeader(ret, context.globals().cu_name, p.getLhs() + params, sig.toString()); + ccb.generateMethodDefHeader( + ret, context.globals().cu_name, p.getLhs() + params, sig.toString()); // Generate a default value for error return. String default_return; @@ -1408,7 +1461,7 @@ private String generateCPPMethodheader(BNFProduction p, Token t) { default_return = "0"; // 0 converts to most (all?) basic types. } - StringBuffer ret_val = new StringBuffer("\n#if !defined ERROR_RET_" + method_name + "\n"); + final StringBuffer ret_val = new StringBuffer("\n#if !defined ERROR_RET_" + method_name + "\n"); ret_val.append("#define ERROR_RET_" + method_name + " " + default_return + "\n"); ret_val.append("#endif\n"); ret_val.append("#define __ERROR_RET__ ERROR_RET_" + method_name + "\n"); @@ -1416,31 +1469,7 @@ private String generateCPPMethodheader(BNFProduction p, Token t) { return ret_val.toString(); } - - private void genStackCheck(boolean voidReturn) { - if (Options.getDepthLimit() > 0) { - if (!voidReturn) { - codeGenerator.println("if(jj_depth_error){ return __ERROR_RET__; }"); - } else { - codeGenerator.println("if(jj_depth_error){ return; }"); - } - codeGenerator.println("__jj_depth_inc __jj_depth_counter(this);"); - codeGenerator.println("if(jj_depth > " + Options.getDepthLimit() + ") {"); - codeGenerator.println(" jj_depth_error = true;"); - codeGenerator.println(" jj_consume_token(-1);"); - codeGenerator - .println(" errorHandler->parseError(token, getToken(1), __FUNCTION__), hasError = true;"); - if (!voidReturn) { - codeGenerator.println(" return __ERROR_RET__;"); // Non-recoverable - // error - } else { - codeGenerator.println(" return;"); // Non-recoverable error - } - codeGenerator.println("}"); - } - } - - private void buildPhase1Routine(BNFProduction p) { + private void buildPhase1Routine(final BNFProduction p) { Token t = p.getReturnTypeTokens().get(0); boolean voidReturn = false; if (t.kind == JavaCCParserConstants.VOID) { @@ -1449,85 +1478,94 @@ private void buildPhase1Routine(BNFProduction p) { String error_ret = null; error_ret = generateCPPMethodheader(p, t); - codeGenerator.print(" {"); + ccb.print(" {"); - if ((Options.booleanValue(Options.USEROPTION__CPP_STOP_ON_FIRST_ERROR) && (error_ret != null)) + if ((Options.getStopOnFirstError() && (error_ret != null)) || ((Options.getDepthLimit() > 0) && !voidReturn)) { - codeGenerator.print(error_ret); + ccb.print(error_ret); } else { error_ret = null; } genStackCheck(voidReturn); - indentamt = 4; + indentamt = 2; if (Options.getDebugParser()) { - codeGenerator.println(""); - codeGenerator.println(" JJEnter> jjenter([this]() {trace_call (\"" - + codeGenerator.escapeToUnicode(p.getLhs()) + "\"); });"); - codeGenerator.println(" JJExit > jjexit ([this]() {trace_return(\"" - + codeGenerator.escapeToUnicode(p.getLhs()) + "\"); });"); - codeGenerator.println(" try {"); - indentamt = 6; - } - - if (!Options.booleanValue(Options.USEROPTION__IGNORE_ACTIONS) && (p.getDeclarationTokens().size() != 0)) { - codeGenerator.printTokenSetup(p.getDeclarationTokens().get(0)); - for (Iterator it = p.getDeclarationTokens().iterator(); it.hasNext();) { + ccb.println(); + ccb.println( + " JJEnter> jjenter([this]() {trace_call (\"" + + ccb.escapeToUnicode(p.getLhs()) + + "\"); });"); + ccb.println( + " JJExit > jjexit ([this]() {trace_return(\"" + + ccb.escapeToUnicode(p.getLhs()) + + "\"); });"); + // codeGen.println(" try {"); + ccb.print(" try {"); + indentamt += 2; + } + + if (!Options.booleanValue(Options.UO__IGNORE_ACTIONS) + && (p.getDeclarationTokens().size() != 0)) { + ccb.printTokenSetup(p.getDeclarationTokens().get(0)); + for (final Iterator it = p.getDeclarationTokens().iterator(); it.hasNext(); ) { t = it.next(); - codeGenerator.printToken(t); + ccb.printToken(t); } - codeGenerator.printTrailingComments(t); + ccb.printTrailingComments(t); } - String code = phase1ExpansionGen(p.getExpansion()); + final String code = phase1ExpansionGen(p.getExpansion()); dumpFormattedString(code); - codeGenerator.println(""); + ccb.println(); if (p.isJumpPatched() && !voidReturn) { - codeGenerator.println(" throw \"Missing return statement in function\";"); + ccb.println(" throw \"Missing return statement in function\";"); } if (Options.getDebugParser()) { - codeGenerator.println(" } catch(...) { }"); + ccb.println(" } catch(...) { }"); + indentamt -= 2; } if (!voidReturn) { - codeGenerator.println("assert(false);"); + ccb.println("assert(false);"); } if (error_ret != null) { - codeGenerator.println("\n#undef __ERROR_RET__\n"); + ccb.println("\n#undef __ERROR_RET__\n"); } - codeGenerator.println("}"); - codeGenerator.println(""); + ccb.println("}"); + ccb.println(); } private void phase1NewLine() { - codeGenerator.println(""); + ccb.println(); for (int i = 0; i < indentamt; i++) { - codeGenerator.print(" "); + ccb.print(' '); } } - private String phase1ExpansionGen(Expansion e) { + private int gensymindex = 0; + + private String phase1ExpansionGen(final Expansion e) { String retval = ""; Token t = null; Lookahead[] conds; String[] actions; if (e instanceof RegularExpression) { - RegularExpression e_nrw = (RegularExpression) e; + final RegularExpression e_nrw = (RegularExpression) e; retval += "\n"; if (e_nrw.lhsTokens.size() != 0) { - codeGenerator.printTokenSetup(e_nrw.lhsTokens.get(0)); - for (Iterator it = e_nrw.lhsTokens.iterator(); it.hasNext();) { + ccb.printTokenSetup(e_nrw.lhsTokens.get(0)); + for (final Iterator it = e_nrw.lhsTokens.iterator(); it.hasNext(); ) { t = it.next(); retval += CodeBuilder.toString(t); } - retval += codeGenerator.getTrailingComments(t); + retval += ccb.getTrailingComments(t); retval += " = "; } - String tail = e_nrw.rhsToken == null ? ");" : ")->" + e_nrw.rhsToken.image + ";"; + final String tail = e_nrw.rhsToken == null ? ");" : ")->" + e_nrw.rhsToken.image + ";"; if (e_nrw.label.equals("")) { - Object label = context.globals().names_of_tokens.get(Integer.valueOf(e_nrw.ordinal)); + final Object label = context.globals().names_of_tokens.get(Integer.valueOf(e_nrw.ordinal)); if (label != null) { retval += "jj_consume_token(" + addTokenNamespace((String) label + tail); } else { @@ -1537,58 +1575,59 @@ private String phase1ExpansionGen(Expansion e) { retval += "jj_consume_token(" + addTokenNamespace(e_nrw.label + tail); } - if (Options.booleanValue(Options.USEROPTION__CPP_STOP_ON_FIRST_ERROR)) { + if (Options.getStopOnFirstError()) { retval += "\n { if (hasError) { return __ERROR_RET__; } }\n"; } } else if (e instanceof NonTerminal) { - NonTerminal e_nrw = (NonTerminal) e; + final NonTerminal e_nrw = (NonTerminal) e; retval += "\n"; if (e_nrw.getLhsTokens().size() != 0) { - codeGenerator.printTokenSetup(e_nrw.getLhsTokens().get(0)); - for (Iterator it = e_nrw.getLhsTokens().iterator(); it.hasNext();) { + ccb.printTokenSetup(e_nrw.getLhsTokens().get(0)); + for (final Iterator it = e_nrw.getLhsTokens().iterator(); it.hasNext(); ) { t = it.next(); retval += CodeBuilder.toString(t); } - retval += codeGenerator.getTrailingComments(t); + retval += ccb.getTrailingComments(t); retval += " = "; } retval += e_nrw.getName() + "("; if (e_nrw.getArgumentTokens().size() != 0) { - codeGenerator.printTokenSetup(e_nrw.getArgumentTokens().get(0)); - for (Iterator it = e_nrw.getArgumentTokens().iterator(); it.hasNext();) { + ccb.printTokenSetup(e_nrw.getArgumentTokens().get(0)); + for (final Iterator it = e_nrw.getArgumentTokens().iterator(); it.hasNext(); ) { t = it.next(); retval += CodeBuilder.toString(t); } - retval += codeGenerator.getTrailingComments(t); + retval += ccb.getTrailingComments(t); } retval += ");"; - if (Options.booleanValue(Options.USEROPTION__CPP_STOP_ON_FIRST_ERROR)) { + if (Options.getStopOnFirstError()) { retval += "\n { if (hasError) { return __ERROR_RET__; } }\n"; } } else if (e instanceof Action) { - Action e_nrw = (Action) e; + final Action e_nrw = (Action) e; retval += "\u0003\n"; - if (!Options.booleanValue(Options.USEROPTION__IGNORE_ACTIONS) && (e_nrw.getActionTokens().size() != 0)) { - codeGenerator.printTokenSetup(e_nrw.getActionTokens().get(0)); - for (Iterator it = e_nrw.getActionTokens().iterator(); it.hasNext();) { + if (!Options.booleanValue(Options.UO__IGNORE_ACTIONS) + && (e_nrw.getActionTokens().size() != 0)) { + ccb.printTokenSetup(e_nrw.getActionTokens().get(0)); + for (final Iterator it = e_nrw.getActionTokens().iterator(); it.hasNext(); ) { t = it.next(); retval += CodeBuilder.toString(t); } - retval += codeGenerator.getTrailingComments(t); + retval += ccb.getTrailingComments(t); } retval += "\u0004"; } else if (e instanceof Choice) { - Choice e_nrw = (Choice) e; + final Choice e_nrw = (Choice) e; conds = new Lookahead[e_nrw.getChoices().size()]; actions = new String[e_nrw.getChoices().size() + 1]; - actions[e_nrw.getChoices().size()] = "\n" + "jj_consume_token(-1);\n" - + "errorHandler->parseError(token, getToken(1), __FUNCTION__), hasError = true;" - + (Options.booleanValue(Options.USEROPTION__CPP_STOP_ON_FIRST_ERROR) ? "return __ERROR_RET__;\n" : ""); - - // In previous line, the "throw" never throws an exception since the - // evaluation of jj_consume_token(-1) causes ParseException to be - // thrown first. + actions[e_nrw.getChoices().size()] = + "\n" + + "jj_consume_token(-1);\n" + + "errorHandler->parseError(token, getToken(1), __FUNCTION__), hasError = true;" + + (Options.getStopOnFirstError() ? "\nreturn __ERROR_RET__;" : ""); + // In previous line, the "throw" never throws an exception since the evaluation of + // jj_consume_token(-1) causes ParseException to be thrown first. Sequence nestedSeq; for (int i = 0; i < e_nrw.getChoices().size(); i++) { nestedSeq = (Sequence) e_nrw.getChoices().get(i); @@ -1597,29 +1636,30 @@ private String phase1ExpansionGen(Expansion e) { } retval = buildLookaheadChecker(conds, actions); } else if (e instanceof Sequence) { - Sequence e_nrw = (Sequence) e; - // We skip the first element in the following iteration since it is the - // Lookahead object. + final Sequence e_nrw = (Sequence) e; + // We skip the first element in the following iteration since it is the Lookahead object. for (int i = 1; i < e_nrw.units.size(); i++) { // For C++, since we are not using exceptions, we will protect all the - // expansion choices with if (!error) + // expansion choices with if (!error) boolean wrap_in_block = false; if (!context.globals().jjtreeGenerated) { // for the last one, if it's an action, we will not protect it. - Expansion elem = e_nrw.units.get(i); - if (!(elem instanceof Action) || !(e.parent instanceof BNFProduction) || (i != (e_nrw.units.size() - 1))) { + final Expansion elem = e_nrw.units.get(i); + if (!(elem instanceof Action) + || !(e.parent instanceof BNFProduction) + || (i != (e_nrw.units.size() - 1))) { wrap_in_block = true; - retval += "\nif (!hasError) {"; + retval += "\nif (!hasError) {\u0001"; } } retval += phase1ExpansionGen(e_nrw.units.get(i)); if (wrap_in_block) { - retval += "\n}"; + retval += "\u0002\n}"; } } } else if (e instanceof OneOrMore) { - OneOrMore e_nrw = (OneOrMore) e; - Expansion nested_e = e_nrw.getExpansion(); + final OneOrMore e_nrw = (OneOrMore) e; + final Expansion nested_e = e_nrw.getExpansion(); Lookahead la; if (nested_e instanceof Sequence) { la = (Lookahead) ((Sequence) nested_e).units.get(0); @@ -1629,7 +1669,7 @@ private String phase1ExpansionGen(Expansion e) { la.setLaExpansion(nested_e); } retval += "\n"; - int labelIndex = ++gensymindex; + final int labelIndex = ++gensymindex; retval += "while (!hasError) {\u0001"; retval += phase1ExpansionGen(nested_e); conds = new Lookahead[1]; @@ -1642,8 +1682,8 @@ private String phase1ExpansionGen(Expansion e) { retval += "\u0002\n" + "}"; retval += "\nend_label_" + labelIndex + ": ;"; } else if (e instanceof ZeroOrMore) { - ZeroOrMore e_nrw = (ZeroOrMore) e; - Expansion nested_e = e_nrw.getExpansion(); + final ZeroOrMore e_nrw = (ZeroOrMore) e; + final Expansion nested_e = e_nrw.getExpansion(); Lookahead la; if (nested_e instanceof Sequence) { la = (Lookahead) ((Sequence) nested_e).units.get(0); @@ -1653,7 +1693,7 @@ private String phase1ExpansionGen(Expansion e) { la.setLaExpansion(nested_e); } retval += "\n"; - int labelIndex = ++gensymindex; + final int labelIndex = ++gensymindex; retval += "while (!hasError) {\u0001"; conds = new Lookahead[1]; conds[0] = la; @@ -1665,8 +1705,8 @@ private String phase1ExpansionGen(Expansion e) { retval += "\u0002\n" + "}"; retval += "\nend_label_" + labelIndex + ": ;"; } else if (e instanceof ZeroOrOne) { - ZeroOrOne e_nrw = (ZeroOrOne) e; - Expansion nested_e = e_nrw.getExpansion(); + final ZeroOrOne e_nrw = (ZeroOrOne) e; + final Expansion nested_e = e_nrw.getExpansion(); Lookahead la; if (nested_e instanceof Sequence) { la = (Lookahead) ((Sequence) nested_e).units.get(0); @@ -1682,8 +1722,8 @@ private String phase1ExpansionGen(Expansion e) { actions[1] = "\n;"; retval += buildLookaheadChecker(conds, actions); } else if (e instanceof TryBlock) { - TryBlock e_nrw = (TryBlock) e; - Expansion nested_e = e_nrw.exp; + final TryBlock e_nrw = (TryBlock) e; + final Expansion nested_e = e_nrw.exp; List list; retval += "\n"; retval += "try {\u0001"; @@ -1693,27 +1733,27 @@ private String phase1ExpansionGen(Expansion e) { retval += " catch ("; list = e_nrw.types.get(i); if (list.size() != 0) { - codeGenerator.printTokenSetup(list.get(0)); - for (Iterator it = list.iterator(); it.hasNext();) { + ccb.printTokenSetup(list.get(0)); + for (final Iterator it = list.iterator(); it.hasNext(); ) { t = it.next(); retval += CodeBuilder.toString(t); } - retval += codeGenerator.getTrailingComments(t); + retval += ccb.getTrailingComments(t); } // retval += " "; // t = (Token)(e_nrw.ids.get(i)); - // codeGenerator.printTokenSetup(t); - // retval += codeGenerator.getStringToPrint(t); - // retval += codeGenerator.getTrailingComments(t); + // codeGen.printTokenSetup(t); + // retval += codeGen.getStringToPrint(t); + // retval += codeGen.getTrailingComments(t); // retval += ") {\u0003\n"; list = e_nrw.catchblks.get(i); if (list.size() != 0) { - codeGenerator.printTokenSetup((list.get(0))); - for (Iterator it = list.iterator(); it.hasNext();) { + ccb.printTokenSetup((list.get(0))); + for (final Iterator it = list.iterator(); it.hasNext(); ) { t = it.next(); retval += CodeBuilder.toString(t); } - retval += codeGenerator.getTrailingComments(t); + retval += ccb.getTrailingComments(t); } retval += "\u0004\n" + "}"; } @@ -1721,12 +1761,12 @@ private String phase1ExpansionGen(Expansion e) { retval += " finally {\u0003\n"; if (e_nrw.finallyblk.size() != 0) { - codeGenerator.printTokenSetup(e_nrw.finallyblk.get(0)); - for (Iterator it = e_nrw.finallyblk.iterator(); it.hasNext();) { + ccb.printTokenSetup(e_nrw.finallyblk.get(0)); + for (final Iterator it = e_nrw.finallyblk.iterator(); it.hasNext(); ) { t = it.next(); retval += CodeBuilder.toString(t); } - retval += codeGenerator.getTrailingComments(t); + retval += ccb.getTrailingComments(t); } retval += "\u0004\n" + "}"; } @@ -1734,43 +1774,55 @@ private String phase1ExpansionGen(Expansion e) { return retval; } - private void buildPhase2Routine(Lookahead la) { - Expansion e = la.getLaExpansion(); - codeGenerator.println(" inline bool ", "jj_2" + internalNames.get(e) + "(int xla)"); - codeGenerator.println(" {"); - codeGenerator.println(" jj_la = xla; jj_lastpos = jj_scanpos = token;"); + private void buildPhase2Routine(final Lookahead la) { + final Expansion e = la.getLaExpansion(); + ccb.println(" inline bool ", "jj_2" + internalNames.get(e) + "(int xla) {"); + ccb.println(" jj_la = xla; jj_lastpos = jj_scanpos = token;"); String ret_suffix = ""; if (Options.getDepthLimit() > 0) { ret_suffix = " && !jj_depth_error"; } - codeGenerator.println(" jj_done = false;"); - codeGenerator.println(" return (!jj_3" + internalNames.get(e) + "() || jj_done)" + ret_suffix + ";"); + ccb.println(" jj_done = false;"); + ccb.println(" return (!jj_3" + internalNames.get(e) + "() || jj_done)" + ret_suffix + ";"); if (Options.getErrorReporting()) { - codeGenerator.println(" { jj_save(" + (Integer.parseInt(internalNames.get(e).substring(1)) - 1) + ", xla); }"); + ccb.println( + " jj_save(" + (Integer.parseInt(internalNames.get(e).substring(1)) - 1) + ", xla);"); } - codeGenerator.println(" }"); - codeGenerator.println(""); - Phase3Data p3d = new Phase3Data(e, la.getAmount()); + ccb.println(" }"); + ccb.println(); + final Phase3Data p3d = new Phase3Data(e, la.getAmount()); phase3list.add(p3d); phase3table.put(e, p3d); } - private boolean xsp_declared; + private boolean xsp_declared; private Expansion jj3_expansion; - private String genReturn(boolean value) { - String retval = value ? "true" : "false"; + private String genReturn(final boolean value) { + final String retval = value ? "true" : "false"; if (Options.getDebugLookahead() && (jj3_expansion != null)) { + String ind = ""; + for (int i = 0; i < indentamt; i++) { + ind += " "; + } + String str = ""; String tracecode = - "trace_la_return(\"" + codeGenerator.escapeToUnicode(((NormalProduction) jj3_expansion.parent).getLhs()) - + "(LOOKAHEAD " + (value ? "FAILED" : "SUCCEEDED") + ")\");"; + "trace_la_return(\"" + + ccb.escapeToUnicode(((NormalProduction) jj3_expansion.parent).getLhs()) + + "(LOOKAHEAD " + + (value ? "FAILED" : "SUCCEEDED") + + ")\");"; if (Options.getErrorReporting()) { tracecode = "if (!jj_rescan) " + tracecode; } - return "{ " + tracecode + " return " + retval + "; }"; + str += "{\n " + ind; + str += tracecode + "\n " + ind; + str += "return " + retval + ";\n" + ind; + str += "}"; + return str; } else { return "return " + retval + ";"; } @@ -1784,15 +1836,15 @@ private static String getTokenLabels() { return addTokenNamespace("tokenLabels"); } - private void generate3R(Expansion e, Phase3Data inf) { + private void generate3R(final Expansion e, final Phase3Data inf) { Expansion seq = e; if (!internalNames.containsKey(e) || internalNames.get(e).equals("")) { while (true) { if ((seq instanceof Sequence) && (((Sequence) seq).units.size() == 2)) { seq = ((Sequence) seq).units.get(1); } else if (seq instanceof NonTerminal) { - NonTerminal e_nrw = (NonTerminal) seq; - NormalProduction ntprod = context.globals().production_table.get(e_nrw.getName()); + final NonTerminal e_nrw = (NonTerminal) seq; + final NormalProduction ntprod = context.globals().production_table.get(e_nrw.getName()); if (ntprod instanceof CodeProduction) { break; // nothing to do here } else { @@ -1804,10 +1856,10 @@ private void generate3R(Expansion e, Phase3Data inf) { } if (seq instanceof RegularExpression) { - RegularExpression re = (RegularExpression) seq; + final RegularExpression re = (RegularExpression) seq; String jj_scan_token = "jj_scan_token"; if (re.label.equals("")) { - Object label = context.globals().names_of_tokens.get(Integer.valueOf(re.ordinal)); + final Object label = context.globals().names_of_tokens.get(Integer.valueOf(re.ordinal)); if (label != null) { jj_scan_token += "(" + addTokenNamespace((String) label) + ")"; } else { @@ -1823,11 +1875,20 @@ private void generate3R(Expansion e, Phase3Data inf) { gensymindex++; // if (gensymindex == 100) // { - // new Error().codeGenerator.printStackTrace(); + // new Error().codeGen.printStackTrace(); // System.out.println(" ***** seq: " + seq.internal_name + "; size: " + // ((Sequence)seq).units.size()); // } - internalNames.put(e, "R_" + e.getProductionName() + "_" + e.getLine() + "_" + e.getColumn() + "_" + gensymindex); + internalNames.put( + e, + "R_" + + e.getProductionName() + + "_" + + e.getLine() + + "_" + + e.getColumn() + + "_" + + gensymindex); internalIndexes.put(e, gensymindex); } Phase3Data p3d = phase3table.get(e); @@ -1838,34 +1899,32 @@ private void generate3R(Expansion e, Phase3Data inf) { } } - private void setupPhase3Builds(Phase3Data inf) { - Expansion e = inf.exp; + private void setupPhase3Builds(final Phase3Data inf) { + final Expansion e = inf.exp; if (e instanceof RegularExpression) { // nothing to here } else if (e instanceof NonTerminal) { - // All expansions of non-terminals have the "name" fields set. So - // there's no need to check it below for "e_nrw" and "ntexp". In - // fact, we rely here on the fact that the "name" fields of both these - // variables are the same. - NonTerminal e_nrw = (NonTerminal) e; - NormalProduction ntprod = context.globals().production_table.get(e_nrw.getName()); + // All expansions of non-terminals have the "name" fields set. + // So there's no need to check it below for "e_nrw" and "ntexp". + // We rely here on the fact that the "name" fields of both these variables are the same. + final NonTerminal e_nrw = (NonTerminal) e; + final NormalProduction ntprod = context.globals().production_table.get(e_nrw.getName()); if (ntprod instanceof CodeProduction) { // nothing to do here } else { generate3R(ntprod.getExpansion(), inf); } } else if (e instanceof Choice) { - Choice e_nrw = (Choice) e; - for (Expansion element : e_nrw.getChoices()) { + final Choice e_nrw = (Choice) e; + for (final Expansion element : e_nrw.getChoices()) { generate3R(element, inf); } } else if (e instanceof Sequence) { - Sequence e_nrw = (Sequence) e; - // We skip the first element in the following iteration since it is the - // Lookahead object. + final Sequence e_nrw = (Sequence) e; + // We skip the first element in the following iteration since it is the Lookahead object. int cnt = inf.count; for (int i = 1; i < e_nrw.units.size(); i++) { - Expansion eseq = e_nrw.units.get(i); + final Expansion eseq = e_nrw.units.get(i); setupPhase3Builds(new Phase3Data(eseq, cnt)); cnt -= minimumSize(eseq); if (cnt <= 0) { @@ -1873,48 +1932,49 @@ private void setupPhase3Builds(Phase3Data inf) { } } } else if (e instanceof TryBlock) { - TryBlock e_nrw = (TryBlock) e; + final TryBlock e_nrw = (TryBlock) e; setupPhase3Builds(new Phase3Data(e_nrw.exp, inf.count)); } else if (e instanceof OneOrMore) { - OneOrMore e_nrw = (OneOrMore) e; + final OneOrMore e_nrw = (OneOrMore) e; generate3R(e_nrw.getExpansion(), inf); } else if (e instanceof ZeroOrMore) { - ZeroOrMore e_nrw = (ZeroOrMore) e; + final ZeroOrMore e_nrw = (ZeroOrMore) e; generate3R(e_nrw.getExpansion(), inf); } else if (e instanceof ZeroOrOne) { - ZeroOrOne e_nrw = (ZeroOrOne) e; + final ZeroOrOne e_nrw = (ZeroOrOne) e; generate3R(e_nrw.getExpansion(), inf); } } - + private static String addTokenNamespace(String token) { - if (token != null) { - if (!Options.getTokenConstantsNamespace().isEmpty()) { - token = Options.getTokenConstantsNamespace() + "::" + token; - } + if (token != null) { + if (!Options.getTokenConstantsNamespace().isEmpty()) { + token = Options.getTokenConstantsNamespace() + "::" + token; } - return token; + } + return token; } private String getTokenType() { - String type = "Token"; - if (Options.getTokenClass().isEmpty()) { - type = "Token"; - } else { - type = Options.getTokenClass(); - } - - if (!Options.getTokenNamespace().isEmpty()) { - type = Options.getTokenNamespace() + "::" + type; - } - return type; + String type = "Token"; + if (Options.getTokenClass().isEmpty()) { + type = "Token"; + } else { + type = Options.getTokenClass(); + } + + if (!Options.getTokenNamespace().isEmpty()) { + type = Options.getTokenNamespace() + "::" + type; + } + return type; } + @SuppressWarnings("unused") private String getTokenTypePointer() { - return getTokenType() + "*"; + return getTokenType() + "*"; } - private String genjj_3Call(Expansion e) { + private String genjj_3Call(final Expansion e) { if (internalNames.containsKey(e) && internalNames.get(e).startsWith("jj_scan_token")) { return internalNames.get(e); } else { @@ -1922,124 +1982,142 @@ private String genjj_3Call(Expansion e) { } } - - private void buildPhase3Routine(Phase3Data inf, boolean recursive_call) { - Expansion e = inf.exp; + private void buildPhase3Routine(final Phase3Data inf, final boolean recursive_call) { + final Expansion e = inf.exp; Token t = null; if (internalNames.containsKey(e) && internalNames.get(e).startsWith("jj_scan_token")) { return; } if (!recursive_call) { - codeGenerator.println(" inline bool ", "jj_3" + internalNames.get(e) + "()"); - - codeGenerator.println(" {"); - codeGenerator.println(" if (jj_done) return true;"); + ccb.println(" inline bool ", "jj_3" + internalNames.get(e) + "() {"); + ccb.println(" if (jj_done) return true;"); if (Options.getDepthLimit() > 0) { - codeGenerator.println("#define __ERROR_RET__ true"); + ccb.println("#define __ERROR_RET__ true"); } genStackCheck(false); xsp_declared = false; if (Options.getDebugLookahead() && (e.parent instanceof NormalProduction)) { - codeGenerator.print(" "); + ccb.print(" "); if (Options.getErrorReporting()) { - codeGenerator.print("if (!jj_rescan) "); + ccb.print("if (!jj_rescan) "); } - codeGenerator.println("trace_la_call(\"" + codeGenerator.escapeToUnicode(((NormalProduction) e.parent).getLhs()) - + "(LOOKING AHEAD...)\");"); + ccb.println( + "trace_la_call(\"" + + ccb.escapeToUnicode(((NormalProduction) e.parent).getLhs()) + + "(LOOKING AHEAD...)\");"); jj3_expansion = e; } else { jj3_expansion = null; } } if (e instanceof RegularExpression) { - RegularExpression e_nrw = (RegularExpression) e; + final RegularExpression e_nrw = (RegularExpression) e; if (e_nrw.label.equals("")) { - Object label = context.globals().names_of_tokens.get(Integer.valueOf(e_nrw.ordinal)); + final Object label = context.globals().names_of_tokens.get(Integer.valueOf(e_nrw.ordinal)); if (label != null) { - codeGenerator.println(" if (jj_scan_token(" + addTokenNamespace((String) label) + ")) " + genReturn(true)); + indentamt += 2; + ccb.println( + " if (jj_scan_token(" + + addTokenNamespace((String) label) + + ")) " + + genReturn(true)); + indentamt -= 2; } else { - codeGenerator.println(" if (jj_scan_token(" + e_nrw.ordinal + ")) " + genReturn(true)); + indentamt += 2; + ccb.println(" if (jj_scan_token(" + e_nrw.ordinal + ")) " + genReturn(true)); + indentamt -= 2; } } else { - codeGenerator.println(" if (jj_scan_token(" + addTokenNamespace(e_nrw.label) + ")) " + genReturn(true)); + indentamt += 2; + ccb.println( + " if (jj_scan_token(" + addTokenNamespace(e_nrw.label) + ")) " + genReturn(true)); + indentamt -= 2; } - // codeGenerator.genCodeLine(" if (jj_la == 0 && jj_scanpos == jj_lastpos) - // " + genReturn(false)); + // codeGen.genCodeLine(" if (jj_la == 0 && jj_scanpos == jj_lastpos) " + genReturn(false)); } else if (e instanceof NonTerminal) { - // All expansions of non-terminals have the "name" fields set. So - // there's no need to check it below for "e_nrw" and "ntexp". In - // fact, we rely here on the fact that the "name" fields of both these - // variables are the same. - NonTerminal e_nrw = (NonTerminal) e; - NormalProduction ntprod = context.globals().production_table.get(e_nrw.getName()); + // All expansions of non-terminals have the "name" fields set. + // So there's no need to check it below for "e_nrw" and "ntexp". + // We rely here on the fact that the "name" fields of both these variables are the same. + final NonTerminal e_nrw = (NonTerminal) e; + final NormalProduction ntprod = context.globals().production_table.get(e_nrw.getName()); if (ntprod instanceof CodeProduction) { - codeGenerator.println(" if (true) { jj_la = 0; jj_scanpos = jj_lastpos; " + genReturn(false) + "}"); + ccb.println( + " if (true) { jj_la = 0; jj_scanpos = jj_lastpos; " + genReturn(false) + "}"); } else { - Expansion ntexp = ntprod.getExpansion(); - // codeGenerator.genCodeLine(" if (jj_3" + ntexp.internal_name + "()) " - // + genReturn(true)); - codeGenerator.println(" if (" + genjj_3Call(ntexp) + ") " + genReturn(true)); - // codeGenerator.genCodeLine(" if (jj_la == 0 && jj_scanpos == - // jj_lastpos) " + genReturn(false)); + final Expansion ntexp = ntprod.getExpansion(); + // codeGen.genCodeLine(" if (jj_3" + ntexp.internal_name + "()) " + genReturn(true)); + ccb.println(" if (" + genjj_3Call(ntexp) + ") " + genReturn(true)); + // codeGen.genCodeLine(" if (jj_la == 0 && jj_scanpos == jj_lastpos) " + genReturn(false)); } } else if (e instanceof Choice) { Sequence nested_seq; - Choice e_nrw = (Choice) e; + final Choice e_nrw = (Choice) e; if (e_nrw.getChoices().size() != 1) { if (!xsp_declared) { xsp_declared = true; - codeGenerator.println(" Token* xsp;"); + ccb.println(" Token* xsp;"); } - codeGenerator.println(" xsp = jj_scanpos;"); + ccb.println(" xsp = jj_scanpos;"); } for (int i = 0; i < e_nrw.getChoices().size(); i++) { nested_seq = (Sequence) e_nrw.getChoices().get(i); - Lookahead la = (Lookahead) nested_seq.units.get(0); + final Lookahead la = (Lookahead) nested_seq.units.get(0); if (la.getActionTokens().size() != 0) { // We have semantic lookahead that must be evaluated. context.globals().lookaheadNeeded = true; - codeGenerator.println(" jj_lookingAhead = true;"); - codeGenerator.print(" jj_semLA = "); - codeGenerator.printTokenSetup(la.getActionTokens().get(0)); - for (Iterator it = la.getActionTokens().iterator(); it.hasNext();) { + ccb.println(" jj_lookingAhead = true;"); + ccb.print(" jj_semLA = "); + ccb.printTokenSetup(la.getActionTokens().get(0)); + for (final Iterator it = la.getActionTokens().iterator(); it.hasNext(); ) { t = it.next(); - codeGenerator.printToken(t); + ccb.printToken(t); } - codeGenerator.printTrailingComments(t); - codeGenerator.println(";"); - codeGenerator.println(" jj_lookingAhead = false;"); + ccb.printTrailingComments(t); + ccb.println(";"); + ccb.println(" jj_lookingAhead = false;"); + } + for (int k = 0; k < indentamt; k++) { + ccb.print(' '); } - codeGenerator.print(" if ("); + ccb.print(" if ("); if (la.getActionTokens().size() != 0) { - codeGenerator.print("!jj_semLA || "); + ccb.print("!jj_semLA || "); } if (i != (e_nrw.getChoices().size() - 1)) { - // codeGenerator.genCodeLine("jj_3" + nested_seq.internal_name + "()) + // codeGen.genCodeLine("jj_3" + nested_seq.internal_name + "()) // {"); - // codeGenerator.println(genjj_3Call(nested_seq) + ") {"); - codeGenerator.println(genjj_3Call(nested_seq) + ") {"); - codeGenerator.println(" jj_scanpos = xsp;"); + // codeGen.println(genjj_3Call(nested_seq) + ") {"); + ccb.println(genjj_3Call(nested_seq) + ") {"); + indentamt += 2; + ccb.println(" jj_scanpos = xsp;"); } else { - // codeGenerator.genCodeLine("jj_3" + nested_seq.internal_name + "()) + // codeGen.genCodeLine("jj_3" + nested_seq.internal_name + "()) // " + genReturn(true)); - codeGenerator.println(genjj_3Call(nested_seq) + ") " + genReturn(true)); - // codeGenerator.genCodeLine(" if (jj_la == 0 && jj_scanpos == + ccb.print(genjj_3Call(nested_seq) + ") "); + indentamt += 2; + ccb.println(genReturn(true)); + indentamt -= 2; + // codeGen.genCodeLine(" if (jj_la == 0 && jj_scanpos == // jj_lastpos) " + genReturn(false)); } } - for (int i = 1; i < e_nrw.getChoices().size(); i++) { - // codeGenerator.genCodeLine(" } else if (jj_la == 0 && jj_scanpos == - // jj_lastpos) " + genReturn(false)); - codeGenerator.println(" }"); - } + for (int i = 1; i < e_nrw.getChoices().size(); i++) { + // codeGen.genCodeLine(" } else if (jj_la == 0 && jj_scanpos == + // jj_lastpos) " + genReturn(false)); + indentamt -= 2; + for (int k = 0; k < indentamt; k++) { + ccb.print(' '); + } + ccb.println(" }"); + } } else if (e instanceof Sequence) { - Sequence e_nrw = (Sequence) e; + final Sequence e_nrw = (Sequence) e; // We skip the first element in the following iteration since it is the // Lookahead object. int cnt = inf.count; for (int i = 1; i < e_nrw.units.size(); i++) { - Expansion eseq = e_nrw.units.get(i); + final Expansion eseq = e_nrw.units.get(i); buildPhase3Routine(new Phase3Data(eseq, cnt), true); // System.out.println("minimumSize: line: " + eseq.line + ", column: " + @@ -2052,75 +2130,75 @@ private void buildPhase3Routine(Phase3Data inf, boolean recursive_call) { } } } else if (e instanceof TryBlock) { - TryBlock e_nrw = (TryBlock) e; + final TryBlock e_nrw = (TryBlock) e; buildPhase3Routine(new Phase3Data(e_nrw.exp, inf.count), true); } else if (e instanceof OneOrMore) { if (!xsp_declared) { xsp_declared = true; - codeGenerator.println(" Token* xsp;"); + ccb.println(" Token* xsp;"); } - OneOrMore e_nrw = (OneOrMore) e; - Expansion nested_e = e_nrw.getExpansion(); - // codeGenerator.genCodeLine(" if (jj_3" + nested_internalNames.get(e) + + final OneOrMore e_nrw = (OneOrMore) e; + final Expansion nested_e = e_nrw.getExpansion(); + // codeGen.genCodeLine(" if (jj_3" + nested_internalNames.get(e) + // "()) " + genReturn(true)); - codeGenerator.println(" if (" + genjj_3Call(nested_e) + ") " + genReturn(true)); - // codeGenerator.genCodeLine(" if (jj_la == 0 && jj_scanpos == jj_lastpos) + ccb.println(" if (" + genjj_3Call(nested_e) + ") " + genReturn(true)); + // codeGen.genCodeLine(" if (jj_la == 0 && jj_scanpos == jj_lastpos) // " + genReturn(false)); - codeGenerator.println(" while (true) {"); - codeGenerator.println(" xsp = jj_scanpos;"); - // codeGenerator.genCodeLine(" if (jj_3" + nested_internalNames.get(e) + + ccb.println(" while (true) {"); + ccb.println(" xsp = jj_scanpos;"); + // codeGen.genCodeLine(" if (jj_3" + nested_internalNames.get(e) + // "()) { jj_scanpos = xsp; break; }"); - codeGenerator.println(" if (" + genjj_3Call(nested_e) + ") { jj_scanpos = xsp; break; }"); - // codeGenerator.genCodeLine(" if (jj_la == 0 && jj_scanpos == jj_lastpos) + ccb.println(" if (" + genjj_3Call(nested_e) + ") { jj_scanpos = xsp; break; }"); + // codeGen.genCodeLine(" if (jj_la == 0 && jj_scanpos == jj_lastpos) // " + genReturn(false)); - codeGenerator.println(" }"); + ccb.println(" }"); } else if (e instanceof ZeroOrMore) { if (!xsp_declared) { xsp_declared = true; - codeGenerator.println(" Token* xsp;"); + ccb.println(" Token* xsp;"); } - ZeroOrMore e_nrw = (ZeroOrMore) e; - Expansion nested_e = e_nrw.getExpansion(); - codeGenerator.println(" while (true) {"); - codeGenerator.println(" xsp = jj_scanpos;"); - // codeGenerator.genCodeLine(" if (jj_3" + nested_internalNames.get(e) + + final ZeroOrMore e_nrw = (ZeroOrMore) e; + final Expansion nested_e = e_nrw.getExpansion(); + ccb.println(" while (true) {"); + ccb.println(" xsp = jj_scanpos;"); + // codeGen.genCodeLine(" if (jj_3" + nested_internalNames.get(e) + // "()) { jj_scanpos = xsp; break; }"); - codeGenerator.println(" if (" + genjj_3Call(nested_e) + ") { jj_scanpos = xsp; break; }"); - // codeGenerator.genCodeLine(" if (jj_la == 0 && jj_scanpos == jj_lastpos) + ccb.println(" if (" + genjj_3Call(nested_e) + ") { jj_scanpos = xsp; break; }"); + // codeGen.genCodeLine(" if (jj_la == 0 && jj_scanpos == jj_lastpos) // " + genReturn(false)); - codeGenerator.println(" }"); + ccb.println(" }"); } else if (e instanceof ZeroOrOne) { if (!xsp_declared) { xsp_declared = true; - codeGenerator.println(" Token* xsp;"); + ccb.println(" Token* xsp;"); } - ZeroOrOne e_nrw = (ZeroOrOne) e; - Expansion nested_e = e_nrw.getExpansion(); - codeGenerator.println(" xsp = jj_scanpos;"); - // codeGenerator.genCodeLine(" if (jj_3" + nested_internalNames.get(e) + + final ZeroOrOne e_nrw = (ZeroOrOne) e; + final Expansion nested_e = e_nrw.getExpansion(); + ccb.println(" xsp = jj_scanpos;"); + // codeGen.genCodeLine(" if (jj_3" + nested_internalNames.get(e) + // "()) jj_scanpos = xsp;"); - codeGenerator.println(" if (" + genjj_3Call(nested_e) + ") jj_scanpos = xsp;"); - // codeGenerator.genCodeLine(" else if (jj_la == 0 && jj_scanpos == + ccb.println(" if (" + genjj_3Call(nested_e) + ") jj_scanpos = xsp;"); + // codeGen.genCodeLine(" else if (jj_la == 0 && jj_scanpos == // jj_lastpos) " + genReturn(false)); } if (!recursive_call) { - codeGenerator.println(" " + genReturn(false)); + indentamt += 2; + ccb.println(" " + genReturn(false)); if (Options.getDepthLimit() > 0) { - codeGenerator.println("#undef __ERROR_RET__"); + ccb.println("#undef __ERROR_RET__"); } - codeGenerator.println(" }"); - codeGenerator.println(""); + indentamt -= 2; + ccb.println(" }"); + ccb.println(); } } - private int minimumSize(Expansion e) { + private int minimumSize(final Expansion e) { return minimumSize(e, Integer.MAX_VALUE); } - /* - * Returns the minimum number of tokens that can parse to this expansion. - */ - private int minimumSize(Expansion e, int oldMin) { + /** Returns the minimum number of tokens that can parse to this expansion. */ + private int minimumSize(final Expansion e, final int oldMin) { int retval = 0; // should never be used. Will be bad if it is. if (e.inMinimumSize) { // recursive search for minimum size unnecessary. @@ -2130,24 +2208,24 @@ private int minimumSize(Expansion e, int oldMin) { if (e instanceof RegularExpression) { retval = 1; } else if (e instanceof NonTerminal) { - NonTerminal e_nrw = (NonTerminal) e; - NormalProduction ntprod = context.globals().production_table.get(e_nrw.getName()); + final NonTerminal e_nrw = (NonTerminal) e; + final NormalProduction ntprod = context.globals().production_table.get(e_nrw.getName()); if (ntprod instanceof CodeProduction) { retval = Integer.MAX_VALUE; // Make caller think this is unending (for we do not go beyond JAVACODE // during // phase3 execution). } else { - Expansion ntexp = ntprod.getExpansion(); + final Expansion ntexp = ntprod.getExpansion(); retval = minimumSize(ntexp); } } else if (e instanceof Choice) { int min = oldMin; Expansion nested_e; - Choice e_nrw = (Choice) e; + final Choice e_nrw = (Choice) e; for (int i = 0; (min > 1) && (i < e_nrw.getChoices().size()); i++) { nested_e = e_nrw.getChoices().get(i); - int min1 = minimumSize(nested_e, min); + final int min1 = minimumSize(nested_e, min); if (min > min1) { min = min1; } @@ -2155,12 +2233,12 @@ private int minimumSize(Expansion e, int oldMin) { retval = min; } else if (e instanceof Sequence) { int min = 0; - Sequence e_nrw = (Sequence) e; + final Sequence e_nrw = (Sequence) e; // We skip the first element in the following iteration since it is the // Lookahead object. for (int i = 1; i < e_nrw.units.size(); i++) { - Expansion eseq = e_nrw.units.get(i); - int mineseq = minimumSize(eseq); + final Expansion eseq = e_nrw.units.get(i); + final int mineseq = minimumSize(eseq); if ((min == Integer.MAX_VALUE) || (mineseq == Integer.MAX_VALUE)) { min = Integer.MAX_VALUE; // Adding infinity to something results in // infinity. @@ -2173,10 +2251,10 @@ private int minimumSize(Expansion e, int oldMin) { } retval = min; } else if (e instanceof TryBlock) { - TryBlock e_nrw = (TryBlock) e; + final TryBlock e_nrw = (TryBlock) e; retval = minimumSize(e_nrw.exp); } else if (e instanceof OneOrMore) { - OneOrMore e_nrw = (OneOrMore) e; + final OneOrMore e_nrw = (OneOrMore) e; retval = minimumSize(e_nrw.getExpansion()); } else if (e instanceof ZeroOrMore) { retval = 0; @@ -2191,23 +2269,46 @@ private int minimumSize(Expansion e, int oldMin) { return retval; } - private void build(CppCodeBuilder codeGenerator) { + private void genStackCheck(final boolean voidReturn) { + if (Options.getDepthLimit() > 0) { + if (!voidReturn) { + ccb.println("if (jj_depth_error) { return __ERROR_RET__; }"); + } else { + ccb.println("if (jj_depth_error) { return; }"); + } + ccb.println("__jj_depth_inc __jj_depth_counter(this);"); + ccb.println("if (jj_depth > " + Options.getDepthLimit() + ") {"); + ccb.println(" jj_depth_error = true;"); + ccb.println(" jj_consume_token(-1);"); + ccb.println(" errorHandler->parseError(token, getToken(1), __FUNCTION__), hasError = true;"); + if (!voidReturn) { + ccb.println(" return __ERROR_RET__;"); // Non-recoverable + // error + } else { + ccb.println(" return;"); // Non-recoverable error + } + ccb.println("}"); + } + } + + private void build() { NormalProduction p; CppCodeProduction cp; - this.codeGenerator = codeGenerator; - for (Iterator prodIterator = context.globals().bnfproductions.iterator(); prodIterator.hasNext();) { + for (final Iterator prodIterator = + context.globals().bnfproductions.iterator(); + prodIterator.hasNext(); ) { p = prodIterator.next(); if (p instanceof CppCodeProduction) { cp = (CppCodeProduction) p; - StringBuffer sig = new StringBuffer(); + final StringBuffer sig = new StringBuffer(); String ret, params; Token t = null; p.getLhs(); - for (Token element : p.getReturnTypeTokens()) { + for (final Token element : p.getReturnTypeTokens()) { t = element; CodeBuilder.toString(t); sig.append(t.toString()); @@ -2215,44 +2316,49 @@ private void build(CppCodeBuilder codeGenerator) { } if (t != null) { - codeGenerator.getTrailingComments(t); + ccb.getTrailingComments(t); } ret = sig.toString(); sig.setLength(0); sig.append("("); if (p.getParameterListTokens().size() != 0) { - codeGenerator.printTokenSetup(p.getParameterListTokens().get(0)); - for (Iterator it = p.getParameterListTokens().iterator(); it.hasNext();) { + ccb.printTokenSetup(p.getParameterListTokens().get(0)); + for (final Iterator it = p.getParameterListTokens().iterator(); it.hasNext(); ) { t = it.next(); sig.append(CodeBuilder.toString(t)); } - sig.append(codeGenerator.getTrailingComments(t)); + sig.append(ccb.getTrailingComments(t)); } sig.append(")"); params = sig.toString(); // For now, just ignore comments - codeGenerator.generateMethodDefHeader(ret, context.globals().cu_name, p.getLhs() + params, sig.toString()); - codeGenerator.println(" {"); + ccb.generateMethodDefHeader( + ret, context.globals().cu_name, p.getLhs() + params, sig.toString()); + ccb.println(" {"); if (Options.getDebugParser()) { - codeGenerator.println(""); - codeGenerator.println(" JJEnter> jjenter([this]() {trace_call (\"" - + codeGenerator.escapeToUnicode(cp.getLhs()) + "\"); });"); - codeGenerator.println(" JJExit > jjexit ([this]() {trace_return(\"" - + codeGenerator.escapeToUnicode(cp.getLhs()) + "\"); });"); - codeGenerator.println(" try {"); + ccb.println(); + ccb.println( + " JJEnter> jjenter([this]() {trace_call (\"" + + ccb.escapeToUnicode(cp.getLhs()) + + "\"); });"); + ccb.println( + " JJExit > jjexit ([this]() {trace_return(\"" + + ccb.escapeToUnicode(cp.getLhs()) + + "\"); });"); + ccb.println(" try {"); } if (cp.getCodeTokens().size() != 0) { - codeGenerator.printTokenSetup(cp.getCodeTokens().get(0)); - codeGenerator.printTokenList(cp.getCodeTokens()); + ccb.printTokenSetup(cp.getCodeTokens().get(0)); + ccb.printTokenList(cp.getCodeTokens()); } - codeGenerator.println(""); + ccb.println(); if (Options.getDebugParser()) { - codeGenerator.println(" } catch(...) { }"); + ccb.println(" } catch(...) { }"); } - codeGenerator.println(" }"); - codeGenerator.println(""); + ccb.println(" }"); + ccb.println(); } else if (p instanceof JavaCodeProduction) { context.errors().semantic_error("Cannot use JAVACODE productions with C++ output (yet)."); continue; @@ -2261,8 +2367,8 @@ private void build(CppCodeBuilder codeGenerator) { } } - codeGenerator.switchToIncludeFile(); - for (Lookahead element : phase2list) { + ccb.switchToIncludeFile(); + for (final Lookahead element : phase2list) { buildPhase2Routine(element); } @@ -2274,33 +2380,28 @@ private void build(CppCodeBuilder codeGenerator) { } } - for (Enumeration enumeration = phase3table.elements(); enumeration.hasMoreElements();) { + for (final Enumeration enumeration = phase3table.elements(); + enumeration.hasMoreElements(); ) { buildPhase3Routine(enumeration.nextElement(), false); } - codeGenerator.switchToMainFile(); + ccb.switchToMainFile(); } } - -/** - * This class stores information to pass from phase 2 to phase 3. - */ +/** This class stores information to pass from phase 2 to phase 3. */ class Phase3Data { - /* - * This is the expansion to generate the jj3 method for. - */ + /** The expansion to generate the jj3 method for. */ Expansion exp; - /* - * This is the number of tokens that can still be consumed. This number is - * used to limit the number of jj3 methods generated. + /** + * The number of tokens that can still be consumed.
+ * This number is used to limit the number of jj3 methods generated. */ int count; - Phase3Data(Expansion e, int c) { + Phase3Data(final Expansion e, final int c) { exp = e; count = c; } } - diff --git a/src/main/java/org/javacc/cpp/TokenCodeGenerator.java b/src/main/java/org/javacc/cpp/TokenCodeGenerator.java index f42ac5a..f596b12 100644 --- a/src/main/java/org/javacc/cpp/TokenCodeGenerator.java +++ b/src/main/java/org/javacc/cpp/TokenCodeGenerator.java @@ -1,64 +1,67 @@ - +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ package org.javacc.cpp; +import java.io.File; +import java.io.IOException; import org.javacc.parser.CodeGeneratorSettings; import org.javacc.parser.Context; import org.javacc.parser.JavaCCGlobals; import org.javacc.parser.Options; -import java.io.File; -import java.io.IOException; - class TokenCodeGenerator implements org.javacc.parser.TokenCodeGenerator { private final Context context; - TokenCodeGenerator(Context context) { + TokenCodeGenerator(final Context context) { this.context = context; } - /** - * The Token class generator. - */ - /* + /** The Token class generator. */ @Override - public boolean generateCodeForToken(CodeGeneratorSettings settings) { - try (CppCodeBuilder builder = CppCodeBuilder.ofHeader(context, settings)) { - - builder.setFile(new File((String) settings.get("OUTPUT_DIRECTORY"), "Token.h")); - builder.addTools(JavaCCGlobals.toolName); - builder.addOption( - Options.USEROPTION__STATIC, - Options.USEROPTION__SUPPORT_CLASS_VISIBILITY_PUBLIC); + public boolean generateCodeForToken(final CodeGeneratorSettings settings) { + // if (Options.getUserTokenManager()) { + // return true; + // } + try (CppCodeBuilder ccb = CppCodeBuilder.of(context, settings)) { + ccb.setFile(new File((String) settings.get("OUTPUT_DIRECTORY"), "Token.cc")); + ccb.addTools(JavaCCGlobals.toolName); + ccb.addOption( + Options.UO__STATIC, Options.UO__SUPPORT_CLASS_VISIBILITY_PUBLIC); - builder.switchToIncludeFile(); - builder.printTemplate("/templates/cpp/Token.h.template"); - } catch (IOException e) { + ccb.printTemplate("/templates/cpp/Token.cc.template"); + ccb.switchToIncludeFile(); + ccb.printTemplate("/templates/cpp/Token.h.template"); + } catch (final IOException e) { return false; } - return true; + return true; } -*/ - -@Override -public boolean generateCodeForToken(CodeGeneratorSettings settings) { -// if (Options.getUserTokenManager()) { -// return true; -// } - try (CppCodeBuilder builder = CppCodeBuilder.of(context, settings)) { - builder.setFile(new File((String) settings.get("OUTPUT_DIRECTORY"), "Token.cc")); - builder.addTools(JavaCCGlobals.toolName); - builder.addOption( - Options.USEROPTION__STATIC, - Options.USEROPTION__SUPPORT_CLASS_VISIBILITY_PUBLIC); - - builder.printTemplate("/templates/cpp/Token.cc.template"); - builder.switchToIncludeFile(); - builder.printTemplate("/templates/cpp/Token.h.template"); - } catch (IOException e) { - return false; - } - return true; - } } - diff --git a/src/main/java/org/javacc/cpp/TokenManagerCodeGenerator.java b/src/main/java/org/javacc/cpp/TokenManagerCodeGenerator.java index 470918c..fbb6b6d 100644 --- a/src/main/java/org/javacc/cpp/TokenManagerCodeGenerator.java +++ b/src/main/java/org/javacc/cpp/TokenManagerCodeGenerator.java @@ -1,3 +1,32 @@ +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ package org.javacc.cpp; import java.io.File; @@ -6,7 +35,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; - import org.javacc.parser.CodeGeneratorSettings; import org.javacc.parser.Context; import org.javacc.parser.Options; @@ -15,13 +43,13 @@ /** Class that implements a table driven code generator for the token manager in C++. */ class TokenManagerCodeGenerator implements org.javacc.parser.TokenManagerCodeGenerator { - private static final String TokenManagerTemplate = - "/templates/cpp/TableDrivenTokenManager.cc.template"; - private static final String TokenManagerTemplateH = - "/templates/cpp/TableDrivenTokenManager.h.template"; + private static final String tokenManagerTemplateCC = + "/templates/cpp/TokenManagerDriver.cc.template"; + private static final String tokenManagerTemplateH = + "/templates/cpp/TokenManagerDriver.h.template"; private final Context context; - private CppCodeBuilder codeGenerator; + private CppCodeBuilder ccb; TokenManagerCodeGenerator(final Context context) { this.context = context; @@ -30,9 +58,11 @@ class TokenManagerCodeGenerator implements org.javacc.parser.TokenManagerCodeGen @Override public void generateCode( final CodeGeneratorSettings settings, final TokenizerData tokenizerData) { + settings.putAll(Options.getOptions()); + settings.put( - Options.NONUSER_OPTION__PARSER_NAME_UPPER_CASE, tokenizerData.parserName.toUpperCase()); + Options.NUO__PARSER_NAME_UPPER_CASE, tokenizerData.parserName.toUpperCase()); settings.put("maxOrdinal", tokenizerData.allMatches.size()); settings.put("firstLexState", tokenizerData.lexStateNames[0]); @@ -47,8 +77,10 @@ public void generateCode( settings.put("charStreamName", Options.getCharStreamName()); settings.put("defaultLexState", tokenizerData.defaultLexState); settings.put("decls", tokenizerData.decls); - settings.put("noDfa", Options.getNoDfa()); settings.put("generatedStates", tokenizerData.nfa.size()); + + settings.put("noDfa", Options.getNoDfa()); + if (Options.getTokenClass().isEmpty()) { settings.put("tokenClass", "Token"); } else { @@ -60,35 +92,56 @@ public void generateCode( settings.put("tokenInclude", Options.getTokenInclude()); } - final File file = - new File(Options.getOutputDirectory(), tokenizerData.parserName + "TokenManager.cc"); try { - codeGenerator = CppCodeBuilder.of(context, settings).setFile(file); + final File file = + new File(Options.getOutputDirectory(), tokenizerData.parserName + "TokenManager.cc"); + ccb = CppCodeBuilder.of(context, settings).setFile(file); if (Options.hasNamespace()) { - codeGenerator.println("namespace " + Options.stringValue("NAMESPACE_OPEN")); + ccb.println( + "namespace " + Options.stringValue("NAMESPACE_OPEN") + " // user defined option"); + ccb.println(); } - codeGenerator.printTemplate(TokenManagerTemplate); - - codeGenerator.switchToIncludeFile(); // remaining variables - - codeGenerator.printTemplate(TokenManagerTemplateH, settings); - codeGenerator.switchToStaticsFile(); - codeGenerator.println("#include \"TokenManagerError.h\""); - codeGenerator.println("#include \"DefaultTokenManagerErrorHandler.h\""); + ccb.println("/* Beginning of code from " + tokenManagerTemplateCC + " */"); + ccb.println(); + ccb.printTemplate(tokenManagerTemplateCC); + ccb.println(); + ccb.println("/* End of code from " + tokenManagerTemplateCC + " */"); + ccb.println(); + + ccb.switchToIncludeFile(); // remaining variables + ccb.println("/* Beginning of code from " + tokenManagerTemplateH + " */"); + ccb.println(); + ccb.printTemplate(tokenManagerTemplateH, settings); + ccb.println(); + ccb.println("/* End of code from " + tokenManagerTemplateH + " */"); + ccb.println(); + + ccb.switchToStaticsFile(); + ccb.println("#include \"TokenManagerError.h\""); + ccb.println("#include \"DefaultTokenManagerErrorHandler.h\""); final String tmi = Options.getTokenManagerInclude(); - if (tmi != null && tmi.length() != 0) { - codeGenerator.println("#include \"" + tmi + "\""); + if (!tmi.isEmpty()) { + if (tmi.charAt(0) == '<') { + ccb.println("#include " + tmi + " // user defined option"); + } else { + ccb.println("#include \"" + tmi + "\" // user defined option"); + } } if (!Options.getNoDfa()) { - dumpDfaTables(codeGenerator, tokenizerData); + ccb.println(); + ccb.println("/* no user defined NO_DFA option */"); + dumpDfaTables(ccb, tokenizerData); } - dumpNfaTables(codeGenerator, tokenizerData); - dumpMatchInfo(codeGenerator, tokenizerData); + + dumpNfaTables(ccb, tokenizerData); + dumpMatchInfo(ccb, tokenizerData); + } catch (final IOException ioe) { + ioe.printStackTrace(); assert (false); } } @@ -99,25 +152,24 @@ public void finish(final CodeGeneratorSettings settings, final TokenizerData tok return; } - if (Options.stringValue(Options.USEROPTION__CPP_NAMESPACE).length() > 0) { - codeGenerator.switchToMainFile(); - codeGenerator.println(Options.stringValue("NAMESPACE_CLOSE")); + if (Options.stringValue(Options.UO__NAMESPACE).length() > 0) { + ccb.switchToMainFile(); + ccb.println(Options.stringValue("NAMESPACE_CLOSE")); } try { - codeGenerator.close(); - } catch (final IOException e) { - throw new Error(e); + ccb.close(); + } catch (final IOException ioe) { + ioe.printStackTrace(); + throw new Error(ioe); } } - private void dumpDfaTables( - final CppCodeBuilder codeGenerator, final TokenizerData tokenizerData) { + private static void dumpDfaTables(final CppCodeBuilder ccb, final TokenizerData tokenizerData) { final Map startAndSize = new HashMap<>(); int i = 0; - codeGenerator.println(); - codeGenerator.println("static const long long stringLiterals[] = {"); + ccb.println("static const long long stringLiterals[] = {"); for (final int key : tokenizerData.literalSequence.keySet()) { final int[] arr = new int[2]; final List l = tokenizerData.literalSequence.get(key); @@ -126,60 +178,62 @@ private void dumpDfaTables( arr[1] = l.size(); int j = 0; if (i > 0) { - codeGenerator.println(", "); + ccb.println(","); } for (final String s : l) { if (j > 0) { - codeGenerator.println(", "); + ccb.println(", "); } final int kind = kinds.get(j); final boolean ignoreCase = tokenizerData.ignoreCaseKinds.contains(kind); - codeGenerator.print(s.length() + "LL"); - codeGenerator.print(", "); - codeGenerator.print(ignoreCase ? 1 : 0); + ccb.print(" "); + ccb.print(s.length() + "LL"); + ccb.print(", "); + ccb.print(ignoreCase ? 1 : 0); for (int k = 0; k < s.length(); k++) { - codeGenerator.print(", "); - codeGenerator.print((int) s.charAt(k) + "LL"); + ccb.print(", "); + ccb.print((int) s.charAt(k) + "LL"); i++; } if (ignoreCase) { for (int k = 0; k < s.length(); k++) { - codeGenerator.print(", "); - codeGenerator.print((int) s.toUpperCase().charAt(k) + "LL"); + ccb.print(", "); + ccb.print((int) s.toUpperCase().charAt(k) + "LL"); i++; } } - codeGenerator.print(", " + kind + "LL"); - codeGenerator.print(", " + tokenizerData.kindToNfaStartState.get(kind) + "LL"); + ccb.print(", " + kind + "LL"); + ccb.print(", " + tokenizerData.kindToNfaStartState.get(kind) + "LL"); i += 4; j++; } startAndSize.put(key, arr); } - codeGenerator.println("};"); - codeGenerator.println(); + ccb.println(); + ccb.println("};"); + ccb.println(); - codeGenerator.switchToMainFile(); + ccb.switchToMainFile(); // Token actions. - codeGenerator.println( + ccb.println( "int " + tokenizerData.parserName + "TokenManager::getStartAndSize(int index, int isCount)\n{"); - codeGenerator.println(" switch(index) {"); + ccb.println(" switch(index) {"); for (final int key : tokenizerData.literalSequence.keySet()) { final int[] arr = startAndSize.get(key); - codeGenerator.println( + ccb.println( " case " + key + ": { return (isCount == 0) ? " + arr[0] + " : " + arr[1] + ";}"); } - codeGenerator.println(" }"); - codeGenerator.println(" return -1;"); - codeGenerator.println("}\n"); + ccb.println(" }"); + ccb.println(" return -1;"); + ccb.println("}"); + ccb.println(); - codeGenerator.switchToStaticsFile(); + ccb.switchToStaticsFile(); } - private void dumpNfaTables( - final CppCodeBuilder codeGenerator, final TokenizerData tokenizerData) { + private static void dumpNfaTables(final CppCodeBuilder ccb, final TokenizerData tokenizerData) { // WE do the following for java so that the generated code is reasonable // size and can be compiled. May not be needed for other languages. final Map nfa = tokenizerData.nfa; @@ -209,46 +263,47 @@ private void dumpNfaTables( } if (Options.getCppUseArray()) { - codeGenerator.print("static const Array<"); - codeGenerator.print(length + 1); - codeGenerator.println(", long long> jjCharData[] = {"); + ccb.print("static const Array<"); + ccb.print(length + 1); + ccb.println(", long long> jjCharData[] = {"); } else { - codeGenerator.println("static const long long jjCharData[][" + length + 1 + "] = {"); + ccb.println("static const long long jjCharData[][" + length + 1 + "] = {"); } for (int i = 0; i < nfa.size(); i++) { final TokenizerData.NfaState tmp = nfa.get(i); if (i > 0) { - codeGenerator.println(","); + ccb.println(","); } if (tmp == null) { - codeGenerator.print("{}"); + ccb.print(" {}"); continue; } - codeGenerator.print("{"); + ccb.print(" {"); final BitSet bits = new BitSet(); for (final char c : tmp.characters) { bits.set(c); } final long[] longs = bits.toLongArray(); - codeGenerator.print(lengths[i] + "LL"); + ccb.print(lengths[i] + "LL"); for (int k = 0; k < longs.length; k++) { int rep = 1; while (((k + rep) < longs.length) && (longs[k + rep] == longs[k])) { rep++; } - codeGenerator.print(", ", rep + "LL, "); + ccb.print(", ", rep + "LL, "); if (longs[k] == Long.MIN_VALUE) { - codeGenerator.print("LLONG_MIN"); + ccb.print("LLONG_MIN"); } else { - codeGenerator.print("" + Long.toString(longs[k]) + "LL"); + ccb.print("" + Long.toString(longs[k]) + "LL"); } k += rep - 1; } - codeGenerator.print("}"); + ccb.print("}"); } - codeGenerator.println("};"); - codeGenerator.println(); + ccb.println(); + ccb.println("};"); + ccb.println(); length = 0; for (int i = 0; i < nfa.size(); i++) { @@ -259,49 +314,51 @@ private void dumpNfaTables( length = Math.max(length, tmp.compositeStates.size()); } if (Options.getCppUseArray()) { - codeGenerator.print("static const Array<"); - codeGenerator.print(length); - codeGenerator.println(", int> jjcompositeState[] = {"); + ccb.print("static const Array<"); + ccb.print(length); + ccb.println(", int> jjcompositeState[] = {"); } else { - codeGenerator.println("static const int jjcompositeState[][" + length + "] = {"); + ccb.println("static const int jjcompositeState[][" + length + "] = {"); } for (int i = 0; i < nfa.size(); i++) { final TokenizerData.NfaState tmp = nfa.get(i); if (i > 0) { - codeGenerator.println(", "); + ccb.println(", "); } if (tmp == null) { - codeGenerator.print("{}"); + ccb.print(" {}"); continue; } - codeGenerator.print("{"); + ccb.print(" {"); int k = 0; for (final int st : tmp.compositeStates) { if (k++ > 0) { - codeGenerator.print(", "); + ccb.print(", "); } - codeGenerator.print(st); + ccb.print(st); } - codeGenerator.print("}"); + ccb.print("}"); } - codeGenerator.println("};"); - codeGenerator.println(); + ccb.println(); + ccb.println("};"); + ccb.println(); - codeGenerator.println("static const int jjmatchKinds[] = {"); + ccb.println("static const int jjmatchKinds[] = {"); for (int i = 0; i < nfa.size(); i++) { final TokenizerData.NfaState tmp = nfa.get(i); if (i > 0) { - codeGenerator.println(", "); + ccb.println(", "); } // TODO(sreeni) : Fix this mess. if (tmp == null) { - codeGenerator.print("ALLBITSUP"); + ccb.print(" ALLBITSUP"); continue; } - codeGenerator.print(tmp.kind); + ccb.print(" " + tmp.kind); } - codeGenerator.println("};"); - codeGenerator.println(); + ccb.println(); + ccb.println("};"); + ccb.println(); length = 0; for (int i = 0; i < nfa.size(); i++) { @@ -312,77 +369,81 @@ private void dumpNfaTables( length = Math.max(length, tmp.nextStates.size()); } if (Options.getCppUseArray()) { - codeGenerator.print("static const Array<"); - codeGenerator.print(length + 1); - codeGenerator.println(", int> jjnextStateSet[] = {"); + ccb.print("static const Array<"); + ccb.print(length + 1); + ccb.println(", int> jjnextStateSet[] = {"); } else { - codeGenerator.println("static const int jjnextStateSet[][" + (length + 1) + "] = {"); + ccb.println("static const int jjnextStateSet[][" + (length + 1) + "] = {"); } for (int i = 0; i < nfa.size(); i++) { final TokenizerData.NfaState tmp = nfa.get(i); if (i > 0) { - codeGenerator.println(", "); + ccb.println(", "); } if (tmp == null) { - codeGenerator.print("{0}"); + ccb.print(" {0}"); continue; } - codeGenerator.print("{"); - codeGenerator.print(tmp.nextStates.size()); + ccb.print(" {"); + ccb.print(tmp.nextStates.size()); for (final int s : tmp.nextStates) { - codeGenerator.print(", "); - codeGenerator.print(s); + ccb.print(", "); + ccb.print(s); } - codeGenerator.print("}"); + ccb.print("}"); } - codeGenerator.println("};"); - codeGenerator.println(); + ccb.println(); + ccb.println("};"); + ccb.println(); - codeGenerator.println("static const int jjInitStates[] = {"); + ccb.println("static const int jjInitStates[] = {"); int k = 0; for (final int i : tokenizerData.initialStates.keySet()) { if (k++ > 0) { - codeGenerator.print(", "); + ccb.print(", "); + } else { + ccb.print(" "); } - codeGenerator.print(tokenizerData.initialStates.get(i)); + ccb.print(tokenizerData.initialStates.get(i)); } - codeGenerator.println("};"); - codeGenerator.println(); + ccb.println("};"); + ccb.println(); - codeGenerator.println("static const int canMatchAnyChar[] = {"); + ccb.println("static const int canMatchAnyChar[] = {"); k = 0; for (int i = 0; i < tokenizerData.wildcardKind.size(); i++) { if (k++ > 0) { - codeGenerator.print(", "); + ccb.print(", "); + } else { + ccb.print(" "); } - codeGenerator.print(tokenizerData.wildcardKind.get(i)); + ccb.print(tokenizerData.wildcardKind.get(i)); } - codeGenerator.println("};"); - codeGenerator.println(); + ccb.println("};"); + ccb.println(); } - private void printWide(final String image) { + private static void printWide(final CppCodeBuilder ccb, final String image) { if (image != null) { - codeGenerator.print("JJWIDE("); + ccb.print("JJWIDE("); for (int j = 0; j < image.length(); j++) { if (image.charAt(j) <= 0xff) { - codeGenerator.print("\\" + Integer.toOctalString(image.charAt(j))); + ccb.print("\\" + Integer.toOctalString(image.charAt(j))); } else { String hexVal = Integer.toHexString(image.charAt(j)); if (hexVal.length() == 3) { hexVal = "0" + hexVal; } - codeGenerator.print("\\u" + hexVal); + ccb.print("\\u" + hexVal); } } - codeGenerator.print(")"); + ccb.print(")"); } else { - codeGenerator.print("JJEMPTY"); + ccb.print("JJEMPTY"); } } - private void dumpMatchInfo( - final CppCodeBuilder codeGenerator, final TokenizerData tokenizerData) { + private static void dumpMatchInfo(final CppCodeBuilder ccb, final TokenizerData tokenizerData) { final Map allMatches = tokenizerData.allMatches; // A bit ugly. @@ -397,7 +458,7 @@ private void dumpMatchInfo( toMore.set(allMatches.size() + 1, true); toSpecial.set(allMatches.size() + 1, true); // Kind map. - codeGenerator.println("static const JJString jjstrLiteralImages[] = {"); + ccb.println("static const JJString jjstrLiteralImages[] = {"); int k = 0; for (final int i : allMatches.keySet()) { final TokenizerData.MatchInfo matchInfo = allMatches.get(i); @@ -418,68 +479,76 @@ private void dumpMatchInfo( newStates[i] = matchInfo.newLexState; final String image = matchInfo.image; if (k++ > 0) { - codeGenerator.println(", "); + ccb.println(","); } - printWide(image); + ccb.print(" "); + printWide(ccb, image); } - codeGenerator.println(); - codeGenerator.println("};"); - codeGenerator.println(); + ccb.println(); + ccb.println("};"); + ccb.println(); // Now generate the bit masks. - TokenManagerCodeGenerator.generateBitVector("jjtoSkip", toSkip, codeGenerator); - TokenManagerCodeGenerator.generateBitVector("jjtoSpecial", toSpecial, codeGenerator); - TokenManagerCodeGenerator.generateBitVector("jjtoMore", toMore, codeGenerator); - TokenManagerCodeGenerator.generateBitVector("jjtoToken", toToken, codeGenerator); - - codeGenerator.println("static const int jjnewLexState[] = {"); + generateBitVector(ccb, "jjtoSkip", toSkip); + ccb.println(); + generateBitVector(ccb, "jjtoSpecial", toSpecial); + ccb.println(); + generateBitVector(ccb, "jjtoMore", toMore); + ccb.println(); + generateBitVector(ccb, "jjtoToken", toToken); + ccb.println(); + + ccb.println("static const int jjnewLexState[] = {"); for (int i = 0; i < newStates.length; i++) { if (i > 0) { - codeGenerator.print(", "); + ccb.print(", "); + } else { + ccb.print(" "); } // codeGenerator.genCode("0x" + Integer.toHexString(newStates[i])); - codeGenerator.print("" + Integer.toString(newStates[i])); + ccb.print(Integer.toString(newStates[i])); } - codeGenerator.println("};"); - codeGenerator.println(); + ccb.println(); + ccb.println("};"); + ccb.println(); // Action functions. // Token actions. - codeGenerator.switchToMainFile(); - codeGenerator.println( + ccb.switchToMainFile(); + ccb.println( "void " + tokenizerData.parserName + "TokenManager::tokenLexicalActions(Token* matchedToken) {"); - dumpLexicalActions( - allMatches, TokenizerData.MatchType.TOKEN, "matchedToken->kind()", codeGenerator); - codeGenerator.println("}"); + dumpLexicalActions(ccb, allMatches, TokenizerData.MatchType.TOKEN, "matchedToken->kind()"); + ccb.println("}"); + ccb.println(); - codeGenerator.println( + ccb.println( "void " + tokenizerData.parserName + "TokenManager::skipLexicalActions(const Token* matchedToken) {"); - dumpLexicalActions(allMatches, TokenizerData.MatchType.SKIP, "jjmatchedKind", codeGenerator); - dumpLexicalActions( - allMatches, TokenizerData.MatchType.SPECIAL_TOKEN, "jjmatchedKind", codeGenerator); - codeGenerator.println("}"); + dumpLexicalActions(ccb, allMatches, TokenizerData.MatchType.SKIP, "jjmatchedKind"); + dumpLexicalActions(ccb, allMatches, TokenizerData.MatchType.SPECIAL_TOKEN, "jjmatchedKind"); + ccb.println("}"); + ccb.println(); // More actions. - codeGenerator.println( - "void " + tokenizerData.parserName + "TokenManager::moreLexicalActions() {"); - codeGenerator.println("jjimageLen += (lengthOfMatch = jjmatchedPos + 1);"); - dumpLexicalActions(allMatches, TokenizerData.MatchType.MORE, "jjmatchedKind", codeGenerator); - codeGenerator.println("}"); - codeGenerator.switchToStaticsFile(); - - codeGenerator.printLiteralArray("lexStateNames", tokenizerData.lexStateNames); + ccb.println("void " + tokenizerData.parserName + "TokenManager::moreLexicalActions() {"); + ccb.println("jjimageLen += (lengthOfMatch = jjmatchedPos + 1);"); + dumpLexicalActions(ccb, allMatches, TokenizerData.MatchType.MORE, "jjmatchedKind"); + ccb.println("}"); + ccb.println(); + + ccb.switchToStaticsFile(); + ccb.printLiteralArray("lexStateNames", tokenizerData.lexStateNames); } - private void dumpLexicalActions( + private static void dumpLexicalActions( + final CppCodeBuilder ccb, final Map allMatches, final TokenizerData.MatchType matchType, - final String kindString, - final CppCodeBuilder codeGenerator) { + final String kindString) { switch (matchType) { case SKIP: break; @@ -489,32 +558,32 @@ private void dumpLexicalActions( default: break; } - codeGenerator.println(" switch(" + kindString + ") {"); + ccb.println(" switch(" + kindString + ") {"); for (final int i : allMatches.keySet()) { final TokenizerData.MatchInfo matchInfo = allMatches.get(i); if ((matchInfo.action == null) || (matchInfo.matchType != matchType)) { continue; } - codeGenerator.println(" case " + i + ": {\n"); - codeGenerator.println(" " + matchInfo.action); - codeGenerator.println(" break;"); - codeGenerator.println(" }"); + ccb.println(" case " + i + ": {"); + ccb.println(" " + matchInfo.action.trim()); + ccb.println(" break;"); + ccb.println(" }"); } - codeGenerator.println(" default: break;"); - codeGenerator.println(" }"); + ccb.println(" default: break;"); + ccb.println(" }"); } private static void generateBitVector( - final String name, final BitSet bits, final CppCodeBuilder codeGenerator) { - codeGenerator.println("static const unsigned long long " + name + "[] = {"); - codeGenerator.print(" "); + final CppCodeBuilder ccb, final String name, final BitSet bits) { + ccb.println("static const unsigned long long " + name + "[] = {"); final long[] longs = bits.toLongArray(); for (int i = 0; i < longs.length; i++) { if (i > 0) { - codeGenerator.print(", "); + ccb.print(", "); } - codeGenerator.print("" + Long.toUnsignedString(longs[i]) + "ULL"); + ccb.print(" " + Long.toUnsignedString(longs[i]) + "ULL"); } - codeGenerator.println("};"); + ccb.println(); + ccb.println("};"); } } diff --git a/src/main/resources/templates/cpp/CharStream.h.template b/src/main/resources/templates/cpp/CharStream.h.template index db8840b..02b8a5b 100644 --- a/src/main/resources/templates/cpp/CharStream.h.template +++ b/src/main/resources/templates/cpp/CharStream.h.template @@ -10,92 +10,114 @@ namespace ${NAMESPACE_OPEN} #fi -/** - * This class describes a character stream that maintains line and - * column number positions of the characters. It also has the capability - * to backup the stream to some extent. An implementation of this - * class is used in the TokenManager implementation generated by - * JavaCCParser. - * - * All the methods except backup can be implemented in any fashion. backup - * needs to be implemented correctly for the correct operation of the lexer. - * Rest of the methods are all used to get information like line number, - * column number and the string that constitutes a token and are not used - * by the lexer. Hence their implementation won't affect the generated lexer's - * operation. +/* + * The class (declarations) generated by Javacc/cpp (by CppCodeGenerator.java with + * CharStream.h.template) that describes the interface for a character stream that maintains line + * and column number positions of the characters. + * It also has the capability to backup the stream to some extent. + * An implementation of this interface is used in the TokenManager implementation generated by + * JavaCC. + * All the methods except backup() can be implemented in any fashion. + * backup() needs to be implemented correctly for the correct operation of the lexer. + * Rest of the methods are all used to get information like line number, column number + * and the String that constitutes a token and are not used by the lexer. + * Hence their implementation won't affect the generated lexer's operation. */ - #if LIBRARY class ${PARSER_NAME_UPPER_CASE}_API CharStream { #else class CharStream { #fi + public: - virtual ~CharStream() {} - - virtual void setTabSize(int i) = 0; - virtual int getTabSize() = 0; - virtual int getColumn() = 0; - virtual int getLine() = 0; - virtual int getEndColumn() = 0; - virtual int getEndLine() = 0; - virtual int getBeginColumn() = 0; - virtual int getBeginLine() = 0; + /* + * Returns the next character that marks the beginning of the next token. + * All characters must remain in the buffer between two successive calls + * to this method to implement backup correctly. + */ + virtual JJChar beginToken() = 0; - virtual bool getTrackLineColumn() = 0; - virtual void setTrackLineColumn(bool val) = 0; + /* + * Returns the next character from the selected input. + * The method of selecting the input is the responsibility of the class implementing + * this interface. Can throw any java.io.IOException. + */ + virtual inline JJChar readChar() = 0; -/** - * Backs up the input stream by amount steps. Lexer calls this method if it - * had already read some characters, but could not use them to match a - * (longer) token. So, they will be used again as the prefix of the next - * token and it is the implementation's responsibility to do this right. - */ + /* + * Backs up the input stream by amount steps. + * The lexer calls this method if it had already read some characters but could not use them + * to match a (longer) token. So, they will be used again as the prefix of the next + * token and it is the implementation's responsibility to do this right. + */ virtual void backup(int amount) = 0; -/** - * Returns the next character that marks the beginning of the next token. - * All characters must remain in the buffer between two successive calls - * to this method to implement backup correctly. - */ - virtual JJChar beginToken() = 0; - - -/** - * Returns the next character from the selected input. The method - * of selecting the input is the responsibility of the class - * implementing this class. - */ - virtual inline JJChar readChar() = 0; - - virtual void expandBuff(bool wrapAround) = 0; - virtual void fillBuff() = 0; + /* + * The lexer calls this function to indicate that it is done with the stream + * and hence implementations can free any resources held by this class. + * Again, the body of this function can be just empty and it will not affect + * the lexer's operation. + */ + virtual void deleteBuffers() = 0; - /** + /* * Returns a string made up of characters from the marked token beginning - * to the current buffer position. Implementations can return - * anything that they want to. For example, for efficiency, one might decide - * to just return NULL, which is a valid implementation. + * to the current buffer position. + * Implementations have the choice of returning anything that they want to. For example, + * for efficiency, one might decide to just return null, which is a valid implementation. */ virtual JJString getImage() = 0; - /** - * Returns an array of characters that make up the suffix of length 'len' for - * the currently matched token. This is used to build up the matched string - * for use in actions in the case of MORE. A simple and inefficient - * implementation of this is as follows : + /* + * Returns an array of characters that make up the suffix of length 'len' + * for the currently matched token. + * This is used to build up the matched string for use in actions in the case of MORE. + * A simple and inefficient implementation of this is as follows : + * { + * String t = GetImage(); + * return t.substring(t.length() - len, t.length()).toCharArray(); + * } */ virtual JJString getSuffix(int len) = 0; - /** - * The lexer calls this function to indicate that it is done with the stream - * and hence implementations can free any resources held by this class. + /* + * Returns the line number of the first character for current token + * (being matched after the last call to BeginToken). */ - virtual void deleteBuffers() = 0; + virtual int getBeginLine() = 0; + + /* + * Returns the column number of the first character for current token + * (being matched after the last call to BeginToken). + */ + virtual int getBeginColumn() = 0; + + /* + * Returns the line number of the last character for current token + * (being matched after the last call to BeginToken). + */ + virtual int getEndLine() = 0; + + /* + * Returns the column number of the last character for current token + * (being matched after the last call to BeginToken). + */ + virtual int getEndColumn() = 0; + + //virtual int getLine() = 0; + //virtual int getColumn() = 0; + + //virtual bool getTrackLineColumn() = 0; + //virtual void setTrackLineColumn(bool val) = 0; + + virtual int getTabSize() = 0; + virtual void setTabSize(int i) = 0; virtual bool endOfInput() = 0; + virtual ~CharStream() {} + virtual void ReInit(ReaderStream *input_stream) = 0; virtual void ReInit(ReaderStream *input_stream, int startline, int startcolumn) = 0; virtual void ReInit(ReaderStream *input_stream, int startline, int startcolumn, int buffersize) = 0; @@ -103,16 +125,18 @@ public: virtual void ReInit(const JJString& str, int startline, int startcolumn) = 0; virtual void ReInit(const JJString& str, int startline, int startcolumn, int buffersize) = 0; - virtual void adjustBeginLineColumn(int newLine, int newCol) = 0; - protected: + + virtual void expandBuff(bool wrapAround) = 0; + virtual void fillBuff() = 0; + + virtual void adjustBeginLineColumn(int newLine, int newCol) = 0; virtual void updateLineColumn(JJChar c) = 0; -}; +}; // end class #if NAMESPACE -${NAMESPACE_CLOSE} +${NAMESPACE_CLOSE} // end namespace #fi - \#endif diff --git a/src/main/resources/templates/cpp/DefaultCharStream.cc.template b/src/main/resources/templates/cpp/DefaultCharStream.cc.template index c1a12e3..7799319 100644 --- a/src/main/resources/templates/cpp/DefaultCharStream.cc.template +++ b/src/main/resources/templates/cpp/DefaultCharStream.cc.template @@ -1,14 +1,46 @@ - +#if PRINT_LICENSE +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#fi namespace { + template void ArrayCopy(T* src, int src_offset, T* dest, int dest_offset, int len) { - for (int i = 0; i < len; i++) { - dest[dest_offset + i] = src[src_offset + i]; - } + for (int i = 0; i < len; i++) { + dest[dest_offset + i] = src[src_offset + i]; + } } class StringReaderStream : public ReaderStream { - public: + +public: StringReaderStream(const JJString& str) : str_(str), cur_(0), max_(str.size()) {} virtual size_t read(JJChar *bufptr, int offset, size_t len) { size_t count = str_.copy(bufptr + offset, len > max_ ? max_ : len, cur_); @@ -21,205 +53,203 @@ class StringReaderStream : public ReaderStream { return max_ == 0; } - private: +private: const JJString str_; size_t cur_; size_t max_; -}; -} + +}; // end class StringReaderStream + +} // end first namespace #if NAMESPACE namespace ${NAMESPACE_OPEN} #fi -void DefaultCharStream::init() { - bufline = nullptr; - bufcolumn = nullptr; - buffer = nullptr; - bufpos = 0; - bufsize = 0; - tokenBegin = 0; - column = 0; - line = 0; - prevCharIsCR = false; - prevCharIsLF = false; - available = 0; - maxNextCharInd = 0; - inBuf = 0; - tabSize = 8; - trackLineColumn = true; - inputStream = nullptr; - deleteStream = false; + +/* + * The class definitions generated by Javacc/cpp (by CppCodeGenerator.java with + * DefaultCharStream.cc.template) that implement the CharStream interface for a character stream + * that maintains line and column number positions of the characters. + * It also has the capability to backup the stream to some extent. + * An implementation of this interface is used in the TokenManager implementation generated by + * JavaCC. + * All the methods except backup() can be implemented in any fashion. + * backup() needs to be implemented correctly for the correct operation of the lexer. + * Rest of the methods are all used to get information like line number, column number + * and the String that constitutes a token and are not used by the lexer. + * Hence their implementation won't affect the generated lexer's operation. + */ + +JJChar DefaultCharStream::beginToken() { + tokenBegin = -1; + JJChar c = readChar(); + tokenBegin = bufpos; + return c; +} + +JJChar DefaultCharStream::readChar() { + if (inBuf > 0) { + --inBuf; ++bufpos; + if (bufpos == bufsize) { + bufpos = 0; + } + return buffer[bufpos]; + } + + ++bufpos; + if (bufpos >= maxNextCharInd) { + fillBuff(); + } + JJChar c = buffer[bufpos]; +#if KEEP_LINE_COLUMN + //if (trackLineColumn) { + updateLineColumn(c); + //} +#fi + return c; } -DefaultCharStream::DefaultCharStream(const JJChar *buf, int sz, int startline, int startcolumn, int buffersize) -{ + +void DefaultCharStream::backup(int amount) { + inBuf += amount; bufpos -= amount; + if (bufpos < 0) { + bufpos += bufsize; + } +} + +void DefaultCharStream::deleteBuffers() { + delete[] buffer; + delete[] bufline; + delete[] bufcolumn; +} + +JJString DefaultCharStream::getImage() { + if (bufpos >= tokenBegin) { + return JJString(buffer + tokenBegin, bufpos - tokenBegin + 1); + } else { + return JJString(buffer + tokenBegin, bufsize - tokenBegin).append(buffer, bufpos + 1); + } +} + +JJString DefaultCharStream::getSuffix(int len) { + if ((bufpos + 1) >= len) { + return JJString(buffer + bufpos - len + 1, len); + } + return JJString(buffer + bufsize - (len - bufpos - 1), len - bufpos - 1).append(buffer, bufpos + 1); +} + +#if KEEP_LINE_COLUMN +int DefaultCharStream::getBufline(int pos) { + if (/*trackLineColumn &&*/ pos>=0) { + return bufline[pos]; + } else { + return -1; + } +} + +int DefaultCharStream::getBufcolumn(int pos) { + if (/*trackLineColumn &&*/ pos>=0) { + return bufcolumn[pos]; + } else { + return -1; + } +} + +#fi +bool DefaultCharStream::endOfInput() { + return inBuf == 0 && bufpos + 1 >= maxNextCharInd && inputStream->endOfInput(); +} + +DefaultCharStream::~DefaultCharStream() { + if (deleteStream) { + delete inputStream; + } + deleteBuffers(); +} + +DefaultCharStream::DefaultCharStream(const JJChar *buf, int sz, + int startline, int startcolumn, int buffersize) { init(); ReInit(JJString(buf, sz), startline, startcolumn, buffersize); } -DefaultCharStream::DefaultCharStream(const JJChar *buf, int sz, int startline, int startcolumn) -{ +DefaultCharStream::DefaultCharStream(const JJChar *buf, + int sz, int startline, int startcolumn) { init(); ReInit(JJString(buf, sz), startline, startcolumn, InitialBufferSize); } -DefaultCharStream::DefaultCharStream(const JJString& str, int startline, int startcolumn, int buffersize) -{ +DefaultCharStream::DefaultCharStream(const JJString& str, + int startline, int startcolumn, int buffersize) { init(); ReInit(str, startline, startcolumn, buffersize); } -DefaultCharStream::DefaultCharStream(const JJString& str, int startline, int startcolumn) -{ +DefaultCharStream::DefaultCharStream(const JJString& str, + int startline, int startcolumn) { init(); ReInit(str, startline, startcolumn, InitialBufferSize); } -DefaultCharStream::DefaultCharStream(ReaderStream *input_stream, int startline, int startcolumn, int buffersize) -{ +DefaultCharStream::DefaultCharStream(ReaderStream *input_stream, + int startline, int startcolumn, int buffersize) { init(); ReInit(input_stream, startline, startcolumn, buffersize); } -DefaultCharStream::DefaultCharStream(ReaderStream *input_stream, int startline, int startcolumn) -{ +DefaultCharStream::DefaultCharStream(ReaderStream *input_stream, + int startline, int startcolumn) { init(); ReInit(input_stream, startline, startcolumn, InitialBufferSize); } -DefaultCharStream::DefaultCharStream(ReaderStream *input_stream) -{ +DefaultCharStream::DefaultCharStream(ReaderStream *input_stream) { init(); ReInit(input_stream, 1, 1, InitialBufferSize); } -void DefaultCharStream::ReInit(const JJString& str, int startline, int startcolumn) { +void DefaultCharStream::ReInit(const JJString& str, + int startline, int startcolumn) { init(); ReInit(str, startline, startcolumn, InitialBufferSize); } -DefaultCharStream::~DefaultCharStream() { - if (deleteStream) { - delete inputStream; - } - deleteBuffers(); -} - - void DefaultCharStream::ReInit(ReaderStream *input_stream, int startline, int startcolumn) { ReInit(input_stream, startline, startcolumn, InitialBufferSize); } - + void DefaultCharStream::ReInit(ReaderStream *input_stream) { ReInit(input_stream, 1, 1, InitialBufferSize); -} - -#if KEEP_LINE_COLUMN -int DefaultCharStream::getBufcolumn(int pos) { - if (trackLineColumn && pos>=0) { - return bufcolumn[pos]; - } else { - return -1; - } } -int DefaultCharStream::getBufline(int pos) { - if (trackLineColumn && pos>=0) { - return bufline[pos]; - } else { - return -1; - } -} -#fi - -void DefaultCharStream::ReInit(const JJString& str, int startline, int startcolumn, int buffersize) { +void DefaultCharStream::ReInit(const JJString& str, + int startline, int startcolumn, int buffersize) { StringReaderStream *stream = new StringReaderStream(str); ReInit(stream, startline, startcolumn, buffersize); deleteStream = true; } -void DefaultCharStream::ReInit(ReaderStream *input_stream, int startline, int startcolumn, int buffersize) { +void DefaultCharStream::ReInit(ReaderStream *input_stream, + int startline, int startcolumn, int buffersize) { if (deleteStream) { delete inputStream; } - if (buffer) { deleteBuffers(); } + inputStream = input_stream; - available = bufsize = buffersize; - buffer = new JJChar[buffersize]; - bufline = new int[buffersize]; - bufcolumn = new int[buffersize]; - - column = startcolumn - 1; - inputStream = input_stream; - line = startline; - prevCharIsLF = prevCharIsCR = false; - tokenBegin = inBuf = maxNextCharInd = 0; - bufpos = -1; deleteStream = false; -} - -void DefaultCharStream::backup(int amount) { - inBuf += amount; bufpos -= amount; - if (bufpos < 0) { - bufpos += bufsize; - } -} - -JJChar DefaultCharStream::beginToken() { - tokenBegin = -1; - JJChar c = readChar(); - tokenBegin = bufpos; - return c; -} - -JJChar DefaultCharStream::readChar() { - if (inBuf > 0) { - --inBuf; ++bufpos; - if (bufpos == bufsize) { - bufpos = 0; - } - return buffer[bufpos]; - } + available = bufsize = buffersize; + tokenBegin = inBuf = maxNextCharInd = 0; + bufpos = -1; - ++bufpos; - if (bufpos >= maxNextCharInd) { - fillBuff(); - } - - JJChar c = buffer[bufpos]; - -#if KEEP_LINE_COLUMN - if (trackLineColumn) { - updateLineColumn(c); - } -#fi - return c; -} - -JJString DefaultCharStream::getImage() { - if (bufpos >= tokenBegin) - return JJString(buffer + tokenBegin, bufpos - tokenBegin + 1); - else - return JJString(buffer + tokenBegin, bufsize - tokenBegin).append(buffer, bufpos + 1); -} + buffer = new JJChar[buffersize]; -JJString DefaultCharStream::getSuffix(int len) { - if ((bufpos + 1) >= len) { - return JJString(buffer + bufpos - len + 1, len); - } - return JJString(buffer + bufsize - (len - bufpos - 1), len - bufpos - 1).append(buffer, bufpos + 1); -} - -bool DefaultCharStream::endOfInput() { - return inBuf == 0 && bufpos + 1 >= maxNextCharInd && inputStream->endOfInput(); -} - -void DefaultCharStream::deleteBuffers() { - delete[] buffer; - delete[] bufline; - delete[] bufcolumn; + bufline = new int[buffersize]; + bufcolumn = new int[buffersize]; + line = startline; + column = startcolumn - 1; + prevCharIsLF = prevCharIsCR = false; } void DefaultCharStream::adjustBeginLineColumn(int newLine, int newCol) { @@ -262,6 +292,30 @@ void DefaultCharStream::adjustBeginLineColumn(int newLine, int newCol) { column = bufcolumn[j]; } +void DefaultCharStream::init() { + inputStream = nullptr; + deleteStream = false; + + bufsize = 0; + available = 0; + tokenBegin = 0; + bufpos = 0; + + buffer = nullptr; + maxNextCharInd = 0; + inBuf = 0; + + //trackLineColumn = true; + bufline = nullptr; + bufcolumn = nullptr; + line = 0; + column = 0; + prevCharIsCR = false; + prevCharIsLF = false; + + tabSize = 1; +} + void DefaultCharStream::expandBuff(bool wrapAround) { JJChar *newbuffer = new JJChar[bufsize + 2048]; int *newbufline = new int[bufsize + 2048]; @@ -311,7 +365,6 @@ void DefaultCharStream::fillBuff() { available = tokenBegin; } } - size_t i = inputStream->read(buffer, maxNextCharInd, available - maxNextCharInd); if (i > 0) { maxNextCharInd += i; @@ -339,7 +392,6 @@ void DefaultCharStream::updateLineColumn(JJChar c) { line++; } } - switch (c) { case '\r' : prevCharIsCR = true; @@ -354,11 +406,10 @@ void DefaultCharStream::updateLineColumn(JJChar c) { default : break; } - bufline[bufpos] = line; bufcolumn[bufpos] = column; } #if NAMESPACE -${NAMESPACE_CLOSE} +${NAMESPACE_CLOSE} // end user namespace #fi diff --git a/src/main/resources/templates/cpp/DefaultCharStream.h.template b/src/main/resources/templates/cpp/DefaultCharStream.h.template index 022d013..e6c086e 100644 --- a/src/main/resources/templates/cpp/DefaultCharStream.h.template +++ b/src/main/resources/templates/cpp/DefaultCharStream.h.template @@ -1,3 +1,34 @@ +#if PRINT_LICENSE +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#fi \#ifndef JAVACC_DEFAULT_CHAR_STREAM_H \#define JAVACC_DEFAULT_CHAR_STREAM_H @@ -11,29 +42,102 @@ namespace ${NAMESPACE_OPEN} #fi -/** - * This class describes a character stream that maintains line and - * column number positions of the characters. It also has the capability - * to backup the stream to some extent. An implementation of this - * class is used in the TokenManager implementation generated by - * JavaCCParser. - * - * All the methods except backup can be implemented in any fashion. backup - * needs to be implemented correctly for the correct operation of the lexer. - * Rest of the methods are all used to get information like line number, - * column number and the string that constitutes a token and are not used - * by the lexer. Hence their implementation won't affect the generated lexer's - * operation. +/* + * The class (declarations) generated by Javacc/cpp (by CppCodeGenerator.java with + * DefaultCharStream.h.template) that implements the CharStream interface for a character stream + * that maintains line and column number positions of the characters. + * It also has the capability to backup the stream to some extent. + * An implementation of this interface is used in the TokenManager implementation generated by + * JavaCC. + * All the methods except backup() can be implemented in any fashion. + * backup() needs to be implemented correctly for the correct operation of the lexer. + * Rest of the methods are all used to get information like line number, column number + * and the String that constitutes a token and are not used by the lexer. + * Hence their implementation won't affect the generated lexer's operation. */ - -static constexpr int InitialBufferSize = 4096; - #if LIBRARY class ${PARSER_NAME_UPPER_CASE}_API DefaultCharStream : public CharStream { #else class DefaultCharStream : public CharStream { #fi + +public: + + /* + * Returns the next character that marks the beginning of the next token. + * All characters must remain in the buffer between two successive calls + * to this method to implement backup correctly. + */ + virtual JJChar beginToken(); + + /* + * Returns the next character from the selected input. + * The method of selecting the input is the responsibility of the class implementing + * this interface. Can throw any java.io.IOException. + */ + virtual inline JJChar readChar(); + + /* + * Backs up the input stream by amount steps. + * The lexer calls this method if it had already read some characters but could not use them + * to match a (longer) token. So, they will be used again as the prefix of the next + * token and it is the implementation's responsibility to do this right. + */ + virtual void backup(int amount); + + /* + * The lexer calls this function to indicate that it is done with the stream + * and hence implementations can free any resources held by this class. + * Again, the body of this function can be just empty and it will not affect + * the lexer's operation. + */ + virtual void deleteBuffers(); + + /* + * Returns a string made up of characters from the marked token beginning + * to the current buffer position. + * Implementations have the choice of returning anything that they want to. For example, + * for efficiency, one might decide to just return null, which is a valid implementation. + */ + virtual JJString getImage(); + + /* + * Returns an array of characters that make up the suffix of length 'len' + * for the currently matched token. + * This is used to build up the matched string for use in actions in the case of MORE. + * A simple and inefficient implementation of this is as follows : + * { + * String t = GetImage(); + * return t.substring(t.length() - len, t.length()).toCharArray(); + * } + */ + virtual JJString getSuffix(int len); + +#if KEEP_LINE_COLUMN +private: + + int getBufline(int pos); + int getBufcolumn(int pos) ; + public: + + virtual int getBeginLine() { return getBufline(tokenBegin); } + virtual int getBeginColumn() { return getBufcolumn(tokenBegin); } + virtual int getEndLine() { return getBufline(bufpos); } + virtual int getEndColumn() { return getBufcolumn(bufpos); } + //virtual int getLine() { return getBufline(bufpos); } + //virtual int getColumn() { return getBufcolumn(bufpos); } +#else + virtual int getBeginLine() { return -1; } + virtual int getBeginColumn() { return -1; } + virtual int getEndLine() { return -1; } + virtual int getEndColumn() { return -1; } + //virtual int getLine() { return -1; } + //virtual int getColumn() { return -1; } +#fi + + bool endOfInput(); + virtual ~DefaultCharStream(); DefaultCharStream(const JJChar *buf, int sz, int startline, int startcolumn, int buffersize); @@ -44,7 +148,7 @@ public: DefaultCharStream(ReaderStream *input_stream, int startline, int startcolumn, int buffersize); DefaultCharStream(ReaderStream *input_stream, int startline, int startcolumn); DefaultCharStream(ReaderStream *input_stream); - + virtual void ReInit(ReaderStream *input_stream, int startline, int startcolumn, int buffersize); virtual void ReInit(ReaderStream *input_stream, int startline, int startcolumn); virtual void ReInit(ReaderStream *input_stream); @@ -52,114 +156,53 @@ public: virtual void ReInit(const JJString& str, int startline, int startcolumn, int buffersize); virtual void ReInit(const JJString& str, int startline, int startcolumn); -/** - * Backs up the input stream by amount steps. Lexer calls this method if it - * had already read some characters, but could not use them to match a - * (longer) token. So, they will be used again as the prefix of the next - * token and it is the implementation's responsibility to do this right. - */ - virtual void backup(int amount); + int getTabSize() { return tabSize; } + void setTabSize(int i) { tabSize = i; } -/** - * Returns the next character that marks the beginning of the next token. - * All characters must remain in the buffer between two successive calls - * to this method to implement backup correctly. - */ - virtual JJChar beginToken(); - -/** - * Returns the next character from the selected input. The method - * of selecting the input is the responsibility of the class - * implementing this class. - */ - virtual JJChar readChar(); + virtual void adjustBeginLineColumn(int newLine, int newCol); - virtual void expandBuff(bool wrapAround); - virtual void fillBuff(); + //virtual bool getTrackLineColumn() { return trackLineColumn; } + //virtual void setTrackLineColumn(bool val) { trackLineColumn = val; } - /** - * Returns a string made up of characters from the marked token beginning - * to the current buffer position. Implementations can return - * anything that they want to. For example, for efficiency, one might decide - * to just return NULL, which is a valid implementation. - */ - virtual JJString getImage(); +protected: - /** - * Returns an array of characters that make up the suffix of length 'len' for - * the currently matched token. This is used to build up the matched string - * for use in actions in the case of MORE. A simple and inefficient - * implementation of this is as follows : - */ - virtual JJString getSuffix(int len); + ReaderStream* inputStream = nullptr; + bool deleteStream = false; - /** - * The lexer calls this function to indicate that it is done with the stream - * and hence implementations can free any resources held by this class. - */ - virtual void deleteBuffers(); + int bufsize = 0; + int available = 0; + int tokenBegin = 0; + int bufpos = 0; - bool endOfInput(); - void setTabSize(int i) { tabSize = i; } - int getTabSize() { return tabSize; } + JJChar* buffer = nullptr; + int maxNextCharInd = 0; + int inBuf = 0; + //bool trackLineColumn = true; + int* bufline = nullptr; + int* bufcolumn = nullptr; + int line = 0; + int column = 0; + bool prevCharIsCR = false; + bool prevCharIsLF = false; + int tabSize = 1; - virtual void adjustBeginLineColumn(int newLine, int newCol); -#if KEEP_LINE_COLUMN -private: - int getBufcolumn(int pos) ; - int getBufline(int pos); - -public: - virtual int getColumn() { return getBufcolumn(bufpos); } - virtual int getLine() { return getBufline(bufpos); } - virtual int getEndColumn() { return getBufcolumn(bufpos); } - virtual int getEndLine() { return getBufline(bufpos); } - virtual int getBeginColumn() { return getBufcolumn(tokenBegin); } - virtual int getBeginLine() { return getBufline(tokenBegin); } -#else -public: - virtual int getColumn() { return -1; } - virtual int getLine() { return -1; } - virtual int getEndColumn() { return -1; } - virtual int getEndLine() { return -1; } - virtual int getBeginColumn() { return -1; } - virtual int getBeginLine() { return -1; } -#fi - - virtual bool getTrackLineColumn() { return trackLineColumn; } - virtual void setTrackLineColumn(bool val) { trackLineColumn = val; } - + virtual void expandBuff(bool wrapAround); + virtual void fillBuff(); -protected: virtual void updateLineColumn(JJChar c); - int* bufline = nullptr; - int* bufcolumn = nullptr; - JJChar* buffer = nullptr; - int bufpos = 0; - int bufsize = 0; - int tokenBegin = 0; - int column = 0; - int line = 0; - bool prevCharIsCR = false; - bool prevCharIsLF = false; - int available = 0; - int maxNextCharInd = 0; - int inBuf = 0; - int tabSize = 8; - bool trackLineColumn = true; - ReaderStream* inputStream = nullptr; - bool deleteStream = false; - private: + void init(); -}; + +}; // end class + +static constexpr int InitialBufferSize = 4096; #if NAMESPACE -${NAMESPACE_CLOSE} +${NAMESPACE_CLOSE} // end namespace #fi - \#endif diff --git a/src/main/resources/templates/cpp/DefaultParserErrorHandler.cc.template b/src/main/resources/templates/cpp/DefaultParserErrorHandler.cc.template index b85d13a..ecc7b70 100644 --- a/src/main/resources/templates/cpp/DefaultParserErrorHandler.cc.template +++ b/src/main/resources/templates/cpp/DefaultParserErrorHandler.cc.template @@ -1,5 +1,36 @@ +#if PRINT_LICENSE +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#fi +// shouldn't BUILD_PARSER condition be in CppCodeGenerator.java? #if BUILD_PARSER - \#if (JAVACC_CHAR_TYPE_SIZEOF != 1) \#include \#include @@ -14,47 +45,53 @@ namespace ${NAMESPACE_OPEN} \#if (JAVACC_CHAR_TYPE_SIZEOF != 1) using convert_t = std::codecvt_utf8; + static std::wstring_convert strconverter; -static std::string to_string(const std::wstring& wstr) -{ - return strconverter.to_bytes(wstr); +static std::string to_string(const std::wstring& wstr) { + return strconverter.to_bytes(wstr); } -static std::wstring to_wstring(const std::string& str) -{ - return strconverter.from_bytes(str); +static std::wstring to_wstring(const std::string& str) { + return strconverter.from_bytes(str); } -\#endif -void DefaultParserErrorHandler::unexpectedToken(const JJString& expectedImage, const JJString& expectedLabel, const JJString& actualImage, const JJString& actualLabel, const Token* actualToken) { - error_count++; - JJLOG - << JJWIDE(Expecting) << JJSPACE << addUnicodeEscapes(expectedLabel) << JJWIDE(:) << JJQUOTE << addUnicodeEscapes(expectedImage) << JJQUOTE - << JJSPACE << JJWIDE(at) << JJSPACE << actualToken->beginLine() << JJWIDE(:) << actualToken->beginColumn() << JJSPACE - << JJWIDE(but got) << JJSPACE << JJQUOTE << addUnicodeEscapes(actualImage) << JJQUOTE << std::endl; +\#endif +void DefaultParserErrorHandler::unexpectedToken(const JJString& expectedImage, + const JJString& expectedLabel, + const JJString& actualImage, + const JJString& actualLabel, + const Token* actualToken) { + error_count++; + JJLOG << JJWIDE(Expecting) << JJSPACE << addUnicodeEscapes(expectedLabel) + << JJWIDE(:) << JJQUOTE << addUnicodeEscapes(expectedImage) << JJQUOTE + << JJSPACE << JJWIDE(at) << JJSPACE << actualToken->beginLine() + << JJWIDE(:) << actualToken->beginColumn() << JJSPACE + << JJWIDE(but got) << JJSPACE + << JJQUOTE << addUnicodeEscapes(actualImage) << JJQUOTE << std::endl; } - - -void DefaultParserErrorHandler::parseError(const Token* last, const Token* unexpected, const JJSimpleString& production) { - error_count++; + +void DefaultParserErrorHandler::parseError(const Token* last, + const Token* unexpected, + const JJSimpleString& production) { + error_count++; \#if (JAVACC_CHAR_TYPE_SIZEOF == 1) - const JJString& work = production; + const JJString& work = production; \#else - const JJString& work = to_wstring(production); + const JJString& work = to_wstring(production); \#endif - JJLOG - << JJWIDE(Encountered:) << JJSPACE << JJQUOTE << addUnicodeEscapes(unexpected->image()) << JJQUOTE << JJSPACE - << JJWIDE(at) << JJSPACE << unexpected->beginLine() << JJWIDE(:) << unexpected->beginColumn() << JJSPACE + JJLOG << JJWIDE(Encountered:) << JJSPACE + << JJQUOTE << addUnicodeEscapes(unexpected->image()) << JJQUOTE << JJSPACE + << JJWIDE(at) << JJSPACE << unexpected->beginLine() + << JJWIDE(:) << unexpected->beginColumn() << JJSPACE << JJWIDE(while parsing:) << JJSPACE << work << std::endl; } - + void DefaultParserErrorHandler::otherError(const JJString& message) { - JJLOG << JJWIDE(Error:) << JJSPACE << message << std::endl; + JJLOG << JJWIDE(Error:) << JJSPACE << message << std::endl; } - #if NAMESPACE -${NAMESPACE_CLOSE} +${NAMESPACE_CLOSE} // end namespace #fi #fi diff --git a/src/main/resources/templates/cpp/DefaultParserErrorHandler.h.template b/src/main/resources/templates/cpp/DefaultParserErrorHandler.h.template index b67ec9d..b7a3d4e 100644 --- a/src/main/resources/templates/cpp/DefaultParserErrorHandler.h.template +++ b/src/main/resources/templates/cpp/DefaultParserErrorHandler.h.template @@ -1,6 +1,38 @@ +#if PRINT_LICENSE +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#fi \#ifndef JAVACC_DEFAULT_PARSER_ERROR_HANDLER_H \#define JAVACC_DEFAULT_PARSER_ERROR_HANDLER_H +// shouldn't BUILD_PARSER condition be in CppCodeGenerator.java? #if BUILD_PARSER \#include "JavaCC.h" \#include "ParserErrorHandler.h" @@ -9,29 +41,41 @@ namespace ${NAMESPACE_OPEN} #fi +/* + * The class (declarations) generated by Javacc/cpp (by CppCodeGenerator.java with + * DefaultParserErrorHandler.h.template) that implements the ParserErrorHandler interface + * that describes the parser error handler. + * It seems that, for the moment, the user cannot tell JavaCC to generate a parser referencing a + * user custom implementation of this interface. + */ class DefaultParserErrorHandler : public ParserErrorHandler { + public: - DefaultParserErrorHandler() {} - virtual ~DefaultParserErrorHandler() {} + + DefaultParserErrorHandler() {} + virtual ~DefaultParserErrorHandler() {} // Called when the parser encounters a different token when expecting to consume a specific kind of token. - // expectedKind - token kind that the parser was trying to consume. - // expectedToken - the image of the token - tokenImages[expectedKind]. - // actual - the actual token that the parser got instead. - virtual void unexpectedToken(const JJString& expectedImage, const JJString& expectedLabel, const JJString& actualImage, const JJString& actualLabel, const Token* actualToken); + virtual void unexpectedToken(const JJString& expectedImage, + const JJString& expectedLabel, + const JJString& actualImage, + const JJString& actualLabel, + const Token* actualToken); // Called when the parser cannot continue parsing. - // last - the last token successfully parsed. - // unexpected - the token at which the error occurs. - // production - the production in which this error occurs. - virtual void parseError(const Token* last, const Token* unexpected, const JJSimpleString& production); + // last - the last token successfully parsed + // unexpected - the token at which the error occurs + // production - the production in which this error occurs + virtual void parseError(const Token* last, + const Token* unexpected, + const JJSimpleString& production); + virtual void otherError(const JJString& message); -}; - +}; // end class #if NAMESPACE -${NAMESPACE_CLOSE} +${NAMESPACE_CLOSE} // end namespace #fi #fi diff --git a/src/main/resources/templates/cpp/DefaultTokenManagerErrorHandler.cc.template b/src/main/resources/templates/cpp/DefaultTokenManagerErrorHandler.cc.template index 0201517..f14d45b 100644 --- a/src/main/resources/templates/cpp/DefaultTokenManagerErrorHandler.cc.template +++ b/src/main/resources/templates/cpp/DefaultTokenManagerErrorHandler.cc.template @@ -1,3 +1,35 @@ +#if PRINT_LICENSE +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#fi +// shouldn't BUILD_TOKEN_MANAGER condition be in TokenManagerCodeGenerator.java? #if BUILD_TOKEN_MANAGER \#if (JAVACC_CHAR_TYPE_SIZEOF != 1) \#include @@ -11,17 +43,28 @@ namespace ${NAMESPACE_OPEN} #fi -void DefaultTokenManagerErrorHandler::lexicalError(bool EOFSeen, int lexState, int errorLine, int errorColumn, JJString errorAfter, JJChar curChar) { - JJLOG - << JJWIDE(Lexical error at) << JJSPACE << errorLine << JJWIDE(:) << errorColumn << JJWIDE(.) - << JJWIDE( Encountered:) << JJSPACE << curChar <. + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#fi \#ifndef JAVACC_DEFAULT_TOKEN_MANAGER_ERROR_HANDLER_H \#define JAVACC_DEFAULT_TOKEN_MANAGER_ERROR_HANDLER_H +// shouldn't BUILD_TOKEN_MANAGER condition be in TokenManagerCodeGenerator.java? #if BUILD_TOKEN_MANAGER \#include "JavaCC.h" \#include "TokenManagerErrorHandler.h" @@ -10,7 +42,9 @@ namespace ${NAMESPACE_OPEN} #fi class DefaultTokenManagerErrorHandler : public TokenManagerErrorHandler { + public: + virtual ~DefaultTokenManagerErrorHandler() {} // Returns a detailed message for the Error when it is thrown by the @@ -23,13 +57,20 @@ public: // errorAfter : prefix that was seen before this error occurred // curchar : the offending character // - virtual void lexicalError(bool EOFSeen, int lexState, int errorLine, int errorColumn, JJString errorAfter, JJChar curChar); + virtual void lexicalError(bool EOFSeen, + int lexState, + int errorLine, + int errorColumn, + JJString errorAfter, + JJChar curChar); + virtual void lexicalError(const JJString& errorMessage); -}; + +}; // end class #if NAMESPACE -${NAMESPACE_CLOSE} +${NAMESPACE_CLOSE} // end namespace #fi #fi \#endif diff --git a/src/main/resources/templates/cpp/ImportExport.h.template b/src/main/resources/templates/cpp/ImportExport.h.template index ed4ed55..e821345 100644 --- a/src/main/resources/templates/cpp/ImportExport.h.template +++ b/src/main/resources/templates/cpp/ImportExport.h.template @@ -1,66 +1,102 @@ +#if PRINT_LICENSE +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#fi \#ifndef JAVACC_${PARSER_NAME_UPPER_CASE}_EXPORT_H \#define JAVACC_${PARSER_NAME_UPPER_CASE}_EXPORT_H +/* + * The set of macros generated by JavaCC/cpp (by CppCodeGenerator.java with ImportExport.h.template) + * to be used to compile to a library. + */ + // -// Ensure that ${PARSER_NAME_UPPER_CASE}_DLL is default unless ${PARSER_NAME_UPPER_CASE}_STATIC is defined +// Ensure that ${PARSER_NAME_UPPER_CASE}_DLL is default +// unless ${PARSER_NAME_UPPER_CASE}_STATIC is defined // \#if defined(_WIN32) && defined(_DLL) - \#if !defined(${PARSER_NAME_UPPER_CASE}_DLL) && !defined(${PARSER_NAME_UPPER_CASE}_STATIC) - \#define ${PARSER_NAME_UPPER_CASE}_DLL - \#endif + \#if !defined(${PARSER_NAME_UPPER_CASE}_DLL) && !defined(${PARSER_NAME_UPPER_CASE}_STATIC) + \#define ${PARSER_NAME_UPPER_CASE}_DLL + \#endif \#endif \#if defined(_MSC_VER) - \#if defined(${PARSER_NAME_UPPER_CASE}_DLL) - \#if defined(_DEBUG) - \#define ${PARSER_NAME_UPPER_CASE}_LIB_SUFFIX "d.lib" - \#else - \#define ${PARSER_NAME_UPPER_CASE}_LIB_SUFFIX ".lib" - \#endif - \#elif defined(_DLL) - \#if defined(_DEBUG) - \#define ${PARSER_NAME_UPPER_CASE}_LIB_SUFFIX "MDd.lib" - \#else - \#define ${PARSER_NAME_UPPER_CASE}_LIB_SUFFIX "MD.lib" - \#endif - \#else - \#if defined(_DEBUG) - \#define ${PARSER_NAME_UPPER_CASE}_LIB_SUFFIX "MTd.lib" - \#else - \#define ${PARSER_NAME_UPPER_CASE}_LIB_SUFFIX "MT.lib" - \#endif - \#endif + \#if defined(${PARSER_NAME_UPPER_CASE}_DLL) + \#if defined(_DEBUG) + \#define ${PARSER_NAME_UPPER_CASE}_LIB_SUFFIX "d.lib" + \#else + \#define ${PARSER_NAME_UPPER_CASE}_LIB_SUFFIX ".lib" + \#endif + \#elif defined(_DLL) + \#if defined(_DEBUG) + \#define ${PARSER_NAME_UPPER_CASE}_LIB_SUFFIX "MDd.lib" + \#else + \#define ${PARSER_NAME_UPPER_CASE}_LIB_SUFFIX "MD.lib" + \#endif + \#else + \#if defined(_DEBUG) + \#define ${PARSER_NAME_UPPER_CASE}_LIB_SUFFIX "MTd.lib" + \#else + \#define ${PARSER_NAME_UPPER_CASE}_LIB_SUFFIX "MT.lib" + \#endif + \#endif \#endif // -// The following block is the standard way of creating macros which make exporting -// from a DLL simpler. All files within this DLL are compiled with the ${PARSER_NAME_UPPER_CASE}_EXPORTS -// symbol defined on the command line. this symbol should not be defined on any project -// that uses this DLL. This way any other project whose source files include this file see -// ${PARSER_NAME_UPPER_CASE}_API functions as being imported from a DLL, wheras this DLL sees symbols -// defined with this macro as being exported. +// The following block is the standard way of creating macros which make exporting from a DLL simpler. +// All files within this DLL are compiled with the ${PARSER_NAME_UPPER_CASE}_EXPORTS symbol +// defined on the command line. +// This symbol should not be defined on any project that uses this DLL. +// This way any other project whose source files include this file see +// ${PARSER_NAME_UPPER_CASE}_API functions as being imported from a DLL, +// whereas this DLL sees symbols defined with this macro as being exported. // \#if defined(_WIN32) && defined(${PARSER_NAME_UPPER_CASE}_DLL) - \#if defined(${PARSER_NAME_UPPER_CASE}_EXPORTS) - \#define ${PARSER_NAME_UPPER_CASE}_API __declspec(dllexport) - \#else - \#define ${PARSER_NAME_UPPER_CASE}_API __declspec(dllimport) - \#endif + \#if defined(${PARSER_NAME_UPPER_CASE}_EXPORTS) + \#define ${PARSER_NAME_UPPER_CASE}_API __declspec(dllexport) + \#else + \#define ${PARSER_NAME_UPPER_CASE}_API __declspec(dllimport) + \#endif \#endif - \#if !defined(${PARSER_NAME_UPPER_CASE}_API) - \#define ${PARSER_NAME_UPPER_CASE}_API + \#define ${PARSER_NAME_UPPER_CASE}_API \#endif - // // Automatically link ${PARSER_NAME_UPPER_CASE} library. // \#if defined(_MSC_VER) - \#if !defined(${PARSER_NAME_UPPER_CASE}_NO_AUTOMATIC_LIBS) && !defined(${PARSER_NAME_UPPER_CASE}_EXPORTS) - \#pragma comment(lib, "${LIBRARY}" ${PARSER_NAME_UPPER_CASE}_LIB_SUFFIX) - \#endif - \#pragma warning(disable:4251) // class needs to have dll - interface + \#if !defined(${PARSER_NAME_UPPER_CASE}_NO_AUTOMATIC_LIBS) && !defined(${PARSER_NAME_UPPER_CASE}_EXPORTS) + \#pragma comment(lib, "${LIBRARY}" ${PARSER_NAME_UPPER_CASE}_LIB_SUFFIX) + \#endif + \#pragma warning(disable:4251) // class needs to have dll - interface \#endif \#endif diff --git a/src/main/resources/templates/cpp/JavaCC.h.template b/src/main/resources/templates/cpp/JavaCC.h.template index dd802b2..4527c81 100644 --- a/src/main/resources/templates/cpp/JavaCC.h.template +++ b/src/main/resources/templates/cpp/JavaCC.h.template @@ -1,3 +1,34 @@ +#if PRINT_LICENSE +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#fi \#ifndef JAVACC_JAVACC_H \#define JAVACC_JAVACC_H @@ -39,58 +70,62 @@ typedef JAVACC_CHAR_TYPE JJChar; typedef JAVACC_STRING_TYPE JJString; typedef JAVACC_SIMPLE_STRING JJSimpleString; -static const JJChar JJEMPTY[] = { 0 }; -static const JJChar JJSPACE[] = { ' ', 0 }; -static const JJChar JJCOMMA[] = { ',', 0 }; -static const JJChar JJQUOTE[] = { '\'', 0 }; +static const JJChar JJEMPTY[] = { 0 }; +static const JJChar JJSPACE[] = { ' ', 0 }; +static const JJChar JJCOMMA[] = { ',', 0 }; +static const JJChar JJQUOTE[] = { '\'', 0 }; +static const JJChar JJDBQUOTE[] = { '\"', 0 }; // Abstraction on stream classes to read a block of data into a buffer. class ReaderStream { + public: // Read block of data into a buffer and return the actual number read. virtual size_t read(JJChar* buffer, int offset, size_t len) { return 0; } virtual bool endOfInput() { return true; } virtual ~ReaderStream() {} + }; - template -struct JJEnter -{ - JJEnter(T f) : f{f} {f();} - ~JJEnter(){} - T f; +struct JJEnter { + JJEnter(T f) : f{f} {f();} + ~JJEnter(){} + T f; }; + template -struct JJExit -{ - JJExit(T f) : f{f} {} - ~JJExit(){f();} - T f; +struct JJExit { + JJExit(T f) : f{f} {} + ~JJExit(){f();} + T f; }; \#define OUT_OF_RANGE 0x0A template struct Array { - T array[size]; + + T array[size]; + public: - T &operator[](size_t index) { - if (index >= size) - throw OUT_OF_RANGE; - return array[index]; - } - const T &operator[](size_t index) const { - if (index >= size) - throw OUT_OF_RANGE; - return array[index]; - } - void* base() { - return this->array; - } - const void* base() const { - return this->array; - } + T &operator[](size_t index) { + if (index >= size) + throw OUT_OF_RANGE; + return array[index]; + } + const T &operator[](size_t index) const { + if (index >= size) + throw OUT_OF_RANGE; + return array[index]; + } + void* base() { + return this->array; + } + const void* base() const { + return this->array; + } + }; JJString addUnicodeEscapes(const JJString& str); diff --git a/src/main/resources/templates/cpp/ParseException.cc.template b/src/main/resources/templates/cpp/ParseException.cc.template index 0103bf0..7109d2f 100644 --- a/src/main/resources/templates/cpp/ParseException.cc.template +++ b/src/main/resources/templates/cpp/ParseException.cc.template @@ -1,117 +1,157 @@ +#if PRINT_LICENSE +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#fi #if NAMESPACE namespace ${NAMESPACE_OPEN} #fi - ParseException::ParseException() { - } +/* + * The class definitions generated by Javacc/cpp (by CppCodeGenerator.java with + * ParseException.cc.template) that are used when parse errors are encountered. + */ - ParseException::ParseException(const JJString& message) { - } +ParseException::ParseException() { +} - ParseException::ParseException(const Token* currentToken, const int** expectedTokenSequences, const JJString* tokenImage) - { - initialise(currentToken, expectedTokenSequences, tokenImage); - this->currentToken = currentToken; - this->expectedTokenSequences = expectedTokenSequences; - this->tokenImage = tokenImage; - } +ParseException::ParseException(const JJString& message) { +} + +ParseException::ParseException(const Token* currentToken, const int** expectedTokenSequences, const JJString* tokenImage) { + initialise(currentToken, expectedTokenSequences, tokenImage); + this->currentToken = currentToken; + this->expectedTokenSequences = expectedTokenSequences; + this->tokenImage = tokenImage; +} - JJString ParseException::initialise(const Token* currentToken, const int** expectedTokenSequences, const JJString* tokenImage) { -\#if 0 - //JJString eol = System.getProperty("line.separator", "\n"); - expected = new JJString(); - int maxSize = 0; - for (int i = 0; i < expectedTokenSequences.length; i++) { - if (maxSize < expectedTokenSequences[i].length) { - maxSize = expectedTokenSequences[i].length; - } - for (int j = 0; j < expectedTokenSequences[i].length; j++) { - expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' '); - } - if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) { - expected.append((JJChar*)"..."); - } - expected.append(eol).append(" "); +JJString ParseException::initialise(const Token* currentToken, const int** expectedTokenSequences, const JJString* tokenImage) { + +/* TODO + // JJString eol = System.getProperty("line.separator", "\n"); + expected = new JJString(); + int maxSize = 0; + for (int i = 0; i < expectedTokenSequences.length; i++) { + if (maxSize < expectedTokenSequences[i].length) { + maxSize = expectedTokenSequences[i].length; } - JJString retval = (JJChar*)"Encountered \""; - Token tok = currentToken.next; - for (int i = 0; i < maxSize; i++) { - if (i != 0) retval += (JJChar*)" "; - if (tok.kind == 0) { - retval += tokenImage[0]; - break; - } - retval += (JJChar*)" " + tokenImage[tok.kind]; - retval += (JJChar*)" \""; - retval += add_escapes(tok.image); - retval += (JJChar*)" \""; - tok = tok.next; + for (int j = 0; j < expectedTokenSequences[i].length; j++) { + expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' '); } - retval += (JJChar*)"\" at line " + currentToken.next.beginLine + (JJChar*)", column " + currentToken.next.beginColumn; - retval += (JJChar*)"." + eol; - if (expectedTokenSequences.length == 1) { - retval += (JJChar*)"Was expecting:" + eol + (JJChar*)" "; - } else { - retval += (JJChar*)"Was expecting one of:" + eol + (JJChar*)" "; + if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) { + expected.append((JJChar*)"..."); } - retval += expected.toString(); - return retval; -\#endif - return (JJChar*)"Parse exception"; + expected.append(eol).append(" "); } + JJString retval = (JJChar*)"Encountered \""; + Token tok = currentToken.next; + for (int i = 0; i < maxSize; i++) { + if (i != 0) retval += (JJChar*)" "; + if (tok.kind == 0) { + retval += tokenImage[0]; + break; + } + retval += (JJChar*)" " + tokenImage[tok.kind]; + retval += (JJChar*)" \""; + retval += add_escapes(tok.image); + retval += (JJChar*)" \""; + tok = tok.next; + } + retval += (JJChar*)"\" at line " + currentToken.next.beginLine + (JJChar*)", column " + currentToken.next.beginColumn; + retval += (JJChar*)"." + eol; + if (expectedTokenSequences.length == 1) { + retval += (JJChar*)"Was expecting:" + eol + (JJChar*)" "; + } else { + retval += (JJChar*)"Was expecting one of:" + eol + (JJChar*)" "; + } + retval += expected.toString(); + return retval; +*/ + + return (JJChar*)"Parse exception"; +} \#define eol "\n" - /** - * Used to convert raw characters to their escaped version - * when these raw version cannot be used as part of an ASCII - * string literal. - */ - JJString ParseException::addEscapes(const JJString& str) { -/* - JJString *retval = new JJString(); - JJChar ch; - for (int i = 0; i < str.length(); i++) { - switch (str.charAt(i)) - { - case '\b': - retval.append("\\b"); - continue; - case '\t': - retval.append("\\t"); - continue; - case '\n': - retval.append("\\n"); - continue; - case '\f': - retval.append("\\f"); - continue; - case '\r': - retval.append("\\r"); - continue; - case '\"': - retval.append("\\\""); - continue; - case '\'': - retval.append("\\\'"); - continue; - case '\\': - retval.append("\\\\"); - continue; - default: - if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { - JJString s = "0000" + Integer.toString(ch, 16); - retval.append("\\u" + s.substring(s.length() - 4, s.length())); - } else { - retval.append(ch); - } - continue; - } - } - return retval.toString(); -*/ return str; - } +/** + * Used to convert raw characters to their escaped version + * when these raw version cannot be used as part of an ASCII + * string literal. + */ +JJString ParseException::add_escapes(const JJString& str) { + +/* TODO + JJString *retval = new JJString(); + JJChar ch; + for (int i = 0; i < str.length(); i++) { + switch (str.charAt(i)) + { + case '\b': + retval.append("\\b"); + continue; + case '\t': + retval.append("\\t"); + continue; + case '\n': + retval.append("\\n"); + continue; + case '\f': + retval.append("\\f"); + continue; + case '\r': + retval.append("\\r"); + continue; + case '\"': + retval.append("\\\""); + continue; + case '\'': + retval.append("\\\'"); + continue; + case '\\': + retval.append("\\\\"); + continue; + default: + if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { + JJString s = "0000" + Integer.toString(ch, 16); + retval.append("\\u" + s.substring(s.length() - 4, s.length())); + } else { + retval.append(ch); + } + continue; + } + } + return retval.toString(); +*/ + + return str; +} #if NAMESPACE -${NAMESPACE_CLOSE} +${NAMESPACE_CLOSE} // end namespace #fi diff --git a/src/main/resources/templates/cpp/ParseException.h.template b/src/main/resources/templates/cpp/ParseException.h.template index 167aa3d..9e4c120 100644 --- a/src/main/resources/templates/cpp/ParseException.h.template +++ b/src/main/resources/templates/cpp/ParseException.h.template @@ -1,83 +1,108 @@ +#if PRINT_LICENSE +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#fi \#ifndef JAVACC_PARSER_EXCEPTION_H \#define JAVACC_PARSER_EXCEPTION_H \#include "JavaCC.h" \#include "Token.h" - #if NAMESPACE namespace ${NAMESPACE_OPEN} #fi -/** - * This exception is thrown when parse errors are encountered. - * You can explicitly create objects of this exception type by - * calling the method generateParseException in the generated - * parser. - * - * You can modify this class to customize your error reporting - * mechanisms so long as you retain the fields. + +/* + * The class (declarations) generated by Javacc/cpp (by CppCodeGenerator.java with + * ParseException.h.template) that is used when parse errors are encountered. + * You can explicitly create objects of this exception type by calling the method + * generateParseException() in the generated parser. + * You can modify this class to customize your error reporting mechanisms + * so long as you retain the public fields. */ class ParseException { -public: - /** - * The following constructors are for use by you for whatever - * purpose you can think of. Constructing the exception in this - * manner makes the exception behave in the normal way - i.e., as - * documented in the class "Throwable". The fields "errorToken", - * "expectedTokenSequences", and "tokenImage" do not contain - * relevant information. The JavaCC generated code does not use - * these constructors. - */ - ParseException(); - ParseException(const JJString& message); +public: - /** - * This constructor is used by the method "generateParseException" - * in the generated parser. Calling this constructor generates - * a new object of this type with the fields "currentToken", - * "expectedTokenSequences", and "tokenImage" set. + /* + * This constructor is used by the method "generateParseException" in the generated parser. + * Calling this constructor generates a new object of this type with the fields "currentToken", + * "expectedTokenSequences", and "tokenImage" set. */ ParseException(const Token* currentToken, const int** expectedTokenSequences, const JJString* tokenImage); + /* + * The following constructors are for use by you for whatever purpose you can think of. + * The fields "errorToken", "expectedTokenSequences", and "tokenImage" do not contain + * relevant information. + * The JavaCC generated code does not use these constructors. + */ + ParseException(); + ParseException(const JJString& message); - /** - * This is the last token that has been consumed successfully. If - * this object has been created due to a parse error, the token - * following this token will (therefore) be the first error token. + /* + * This is the last token that has been consumed successfully + * If this object has been created due to a parse error, + * the token following this token will (therefore) be the first error token. */ const Token* currentToken; - /** - * Each entry in this array is an array of integers. Each array - * of integers represents a sequence of tokens (by their ordinal - * values) that is expected at this point of the parse. + /* + * This is the last token that has been consumed successfully. + * If this object has been created due to a parse error, + * the token following this token will (therefore) be the first error token. */ const int** expectedTokenSequences; - /** - * This is a reference to the "tokenImage" array of the generated - * parser within which the parse error occurred. This array is - * defined in the generated ...Constants class. + /* + * This is a reference to the "tokenImage" array of the generated parser within which + * the parse error occurred. + * This array is defined in the generated ParserConstants.h file. */ const JJString* tokenImage; private: - /** - * It uses "currentToken" and "expectedTokenSequences" to generate a parse - * error message and returns it. If this object has been created - * due to a parse error, and you do not catch it (it gets thrown - * from the parser) the correct error message - * gets displayed. + + /* + * It uses "currentToken" and "expectedTokenSequences" to generate a parse error message + * and returns it. + * If this object has been created due to a parse error and you do not catch it (i.e. it gets + * thrown from the parser), the correct error message gets displayed. */ JJString initialise(const Token* currentToken, const int** expectedTokenSequences, const JJString* tokenImage); - /** - * Used to convert raw characters to their escaped version - * when these raw version cannot be used as part of an ASCII - * string literal. + /* + * Used to convert raw characters to their escaped version when these raw version + * cannot be used as part of an ASCII string literal. */ - JJString addEscapes(const JJString& str); + JJString add_escapes(const JJString& str); }; #if NAMESPACE diff --git a/src/main/resources/templates/cpp/ParserErrorHandler.h.template b/src/main/resources/templates/cpp/ParserErrorHandler.h.template index 03efece..696e0a7 100644 --- a/src/main/resources/templates/cpp/ParserErrorHandler.h.template +++ b/src/main/resources/templates/cpp/ParserErrorHandler.h.template @@ -1,38 +1,87 @@ +#if PRINT_LICENSE +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#fi \#ifndef JAVACC_PARSER_ERROR_HANDLER_H \#define JAVACC_PARSER_ERROR_HANDLER_H +// shouldn't BUILD_PARSER condition be in CppCodeGenerator.java? #if BUILD_PARSER \#include "JavaCC.h" \#include "Token.h" namespace JavaCC { +/* + * The interface (declarations) generated by JavaCC/cpp (by CppCodeGenerator.java with + * ParserErrorHandler.h.template) that describes the parser error handler. + * An implementation of this interface (DefaultParserErrorHandler.h & DefaultParserErrorHandler.cc) + * is generated by JavaCC/cpp (by CppCodeGenerator.java with DefaultParserErrorHandler.h.template & + * DefaultParserErrorHandler.cc.template). + * It seems that, for the moment, the user cannot tell JavaCC to generate a parser referencing a + * user custom implementation of this interface. + */ class ParserErrorHandler { + public: - ParserErrorHandler() : error_count(0) {} - virtual ~ParserErrorHandler() {} - + + ParserErrorHandler() : error_count(0) {} + virtual ~ParserErrorHandler() {} + // Called when the parser encounters a different token when expecting to consume a specific kind of token. - // expectedKind - token kind that the parser was trying to consume. - // expectedToken - the image of the token - tokenImages[expectedKind]. - // actual - the actual token that the parser got instead. - virtual void unexpectedToken(const JJString& expectedImage, const JJString& expectedLabel, const JJString& actualImage, const JJString& actualLabel, const Token* actualToken) = 0; - - + virtual void unexpectedToken(const JJString& expectedImage, + const JJString& expectedLabel, + const JJString& actualImage, + const JJString& actualLabel, + const Token* actualToken) = 0; + + // Called when the parser cannot continue parsing. - // last - the last token successfully parsed. - // unexpected - the token at which the error occurs. - // production - the production in which this error occurs. - virtual void parseError(const Token* last, const Token* unexpected, const JJSimpleString& production) = 0; + // last - the last token successfully parsed + // unexpected - the token at which the error occurs + // production - the production in which this error occurs + virtual void parseError(const Token* last, + const Token* unexpected, + const JJSimpleString& production) = 0; + virtual void otherError(const JJString& message) = 0; - int getErrorCount() const { return error_count; } + + int getErrorCount() const { return error_count; } protected: + int error_count; - -}; -} -using JavaCC::ParserErrorHandler; + +}; // end class + +} using JavaCC::ParserErrorHandler; // end namespace #fi \#endif diff --git a/src/main/resources/templates/cpp/TableDrivenTokenManager.h.template b/src/main/resources/templates/cpp/TableDrivenTokenManager.h.template deleted file mode 100644 index 945617a..0000000 --- a/src/main/resources/templates/cpp/TableDrivenTokenManager.h.template +++ /dev/null @@ -1,96 +0,0 @@ -\#ifndef JAVACC_${PARSER_NAME_UPPER_CASE}_TOKEN_MANAGER_H -\#define JAVACC_${PARSER_NAME_UPPER_CASE}_TOKEN_MANAGER_H - -#if LIBRARY -\#include "ImportExport.h" -#fi -\#include "JavaCC.h" -\#include "CharStream.h" -#if tokenInclude -\#include "${tokenInclude}" -#fi -\#include "ParserErrorHandler.h" -\#include "TokenManager.h" -\#include "${parserName}Constants.h" - - -#if TOKEN_MANAGER_USES_PARSER -\#include "${parserName}.h" -#fi - -#if NAMESPACE -namespace ${NAMESPACE_OPEN} -#fi - -#if LIBRARY -class ${PARSER_NAME_UPPER_CASE}_API ${parserName}TokenManager : public TokenManager -#else -class ${parserName}TokenManager : public TokenManager -#fi -{ -private: - int defaultLexState; - int curLexState = ${defaultLexState}; - int jjmatchedPos; - int jjmatchedKind; - - int moveIndex; -#if CPP_USE_ARRAY - Array<${nfaSize}, Array<${charsVectorSize}, unsigned long long>> jjChars;//[${nfaSize}][${charsVectorSize}]; -#else - unsigned long long jjChars[${nfaSize}][${charsVectorSize}]; -#fi - JJString jjimage; - JJString image; - int jjimageLen; - int lengthOfMatch; - JJChar curChar; - CharStream* input_stream; - bool delete_eh; - TokenManagerErrorHandler* errorHandler; - - int jjrounds[${stateSetSize}]; - int jjstateSet[2 * ${stateSetSize}]; - -public: - ${parserName}TokenManager(CharStream* stream, int lexState = 0); - virtual ~${parserName}TokenManager() {} - - Token* getNextToken(); -#if COMMON_TOKEN_ACTION - void CommonTokenAction(Token* token); -#fi -#if TOKEN_MANAGER_USES_PARSER - void setParser(void* parser); - -protected: - ${parserName}* parser; -#fi -protected: - bool moveToNextChar(); - - void ReInit(CharStream* stream, int lexState = 0); - void SwitchTo(int lexState); - - -private: - void tokenLexicalActions(Token* matchedToken); - void skipLexicalActions(const Token* matchedToken); - void moreLexicalActions(); - - int getStartAndSize(int index, int isCount); - int jjRunStringLiteralMatch(); - - int jjMoveNfa(int startState, int curPos); - Token* jjFillToken(); - -public: - void lexicalError(); - const TokenManagerErrorHandler* getErrorHandler() const; -}; - -#if NAMESPACE -${NAMESPACE_CLOSE} -#fi - -\#endif diff --git a/src/main/resources/templates/cpp/Token.cc.template b/src/main/resources/templates/cpp/Token.cc.template index b913759..6efb9c7 100644 --- a/src/main/resources/templates/cpp/Token.cc.template +++ b/src/main/resources/templates/cpp/Token.cc.template @@ -1,47 +1,75 @@ +#if PRINT_LICENSE +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#fi namespace JavaCC { -Token::Token() : _beginLine(0), _beginColumn(0), _endLine(0), _endColumn(0) -{ +/* + * The class definitions generated by JavaCC/cpp (by TokenCodeGenerator.java with + * Token.cc.template) that describe a token. + */ + +Token::Token() : _beginLine(0), _beginColumn(0), _endLine(0), _endColumn(0) { this->_kind = 0; this->_next = nullptr; this->_specialToken = nullptr; } -Token::Token(int kind) : _beginLine(0), _beginColumn(0), _endLine(0), _endColumn(0) -{ +Token::Token(int kind) : _beginLine(0), _beginColumn(0), _endLine(0), _endColumn(0) { this->_kind = kind; this->_next = nullptr; this->_specialToken = nullptr; } -Token::Token(int kind, const JJString& image) : _beginLine(0), _beginColumn(0), _endLine(0), _endColumn(0) -{ +Token::Token(int kind, const JJString& image) : _beginLine(0), _beginColumn(0), _endLine(0), _endColumn(0) { this->_kind = kind; this->_image = image; this->_next = nullptr; this->_specialToken = nullptr; } -Token* Token::newToken(int kind, const JJString& image) -{ - switch(kind) - { +Token* Token::newToken(int kind, const JJString& image) { + switch(kind) { default : return new Token(kind, image); } } -Token* Token::newToken(int kind) -{ +Token* Token::newToken(int kind) { return newToken(kind, JJString()); } -Token::~Token() -{ +Token::~Token() { if (_specialToken) delete _specialToken; this->_kind = 0; this->_next = nullptr; this->_specialToken = nullptr; } - -} \ No newline at end of file +} // end namespace \ No newline at end of file diff --git a/src/main/resources/templates/cpp/Token.h.template b/src/main/resources/templates/cpp/Token.h.template index b9f18f4..63d3855 100644 --- a/src/main/resources/templates/cpp/Token.h.template +++ b/src/main/resources/templates/cpp/Token.h.template @@ -1,3 +1,34 @@ +#if PRINT_LICENSE +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#fi \#ifndef JAVACC_TOKEN_H \#define JAVACC_TOKEN_H @@ -8,60 +39,58 @@ namespace JavaCC { -/** - * Describes the input token stream. +/* + * The class (declarations) generated by JavaCC/cpp (by TokenCodeGenerator.java with + * Token.h.template) that describe a token. */ - #if LIBRARY -class ${PARSER_NAME_UPPER_CASE}_API Token +class ${PARSER_NAME_UPPER_CASE}_API Token { #else -class Token +class Token { #fi -{ + public: - Token(); - Token(int kind); - Token(int kind, const JJString& image); + + Token(); + Token(int kind); + Token(int kind, const JJString& image); virtual ~Token(); - /** - * An integer that describes the kind of this token. This numbering - * system is determined by JavaCCParser, and a table of these numbers is - * stored in the file ...Constants.java. + /* + * An integer that describes the kind of this token, determined by JavaCC. + * An array of these numbers is stored in the file ParserConstants.h. */ - int& kind(); + int& kind(); - int& beginLine(); // The line number of the first character of this Token. - int& beginColumn(); // The column number of the first character of this Token. - int& endLine(); // The line number of the last character of this Token. - int& endColumn(); // The column number of the last character of this Token. + int& beginLine(); // The line number of the first character of this Token. + int& beginColumn(); // The column number of the first character of this Token. + int& endLine(); // The line number of the last character of this Token. + int& endColumn(); // The column number of the last character of this Token. - JJString& image(); // The string image of the token. - - /** - * A reference to the next regular (non-special) token from the input - * stream. If this is the last token from the input stream, or if the - * token manager has not read tokens beyond this one, this field is - * set to NULL. This is true only if this token is also a regular - * token. Otherwise, see below for a description of the contents of - * this field. + JJString& image(); // The string image of the token. + + /* + * A reference to the next regular (non-special) token from the input stream. + * If this is the last token from the input stream, or if the token manager has not + * read tokens beyond this one, this field is set to null. + * This is true only if this token is also a regular token. + * Otherwise, see below for a description of the contents of this field. */ - Token*& next(); - /** - * This field is used to access special tokens that occur prior to this - * token, but after the immediately preceding regular (non-special) token. - * If there are no such special tokens, this field is set to NULL. - * When there are more than one such special token, this field refers - * to the last of these special tokens, which in turn refers to the next - * previous special token through its specialToken field, and so on - * until the first special token (whose specialToke_ field is NULL). - * The next fields of special tokens refer to other special tokens that - * immediately follow it (without an intervening regular token). If there - * is no such token, this field is NULL. + Token*& next(); + + /* + * This field is used to access special tokens that occur prior to this token, + * but after the immediately preceding regular (non-special) token. + * If there are no such special tokens, this field is set to null. + * When there are more than one such special token, this field refers to the last of these + * special tokens, which in turn refers to the next previous special token through its + * specialToken field, and so on until the first special token (whose specialToken field is null). + * The next fields of special tokens refer to other special tokens that immediately follow it + * (without an intervening regular token). If there is no such token, this field is null. */ - Token*& specialToken(); + Token*& specialToken(); - /** + /* * Returns a new Token, by default. However, if you want, you * can create and return subclass objects based on the value of ofKind. * Simply add the cases to the switch for all those special cases. @@ -73,68 +102,67 @@ public: * to the following switch statement. Then you can cast matchedToken * variable to the appropriate type and use sit in your lexical actions. */ - static Token* newToken(int ofKind, const JJString& image); - static Token* newToken(int ofKind); + static Token* newToken(int ofKind, const JJString& image); + static Token* newToken(int ofKind); - /** + /* * An optional attribute value of the Token. - * Tokens which are not used as syntactic sugar will often contain - * meaningful values that will be used later on by the compiler or - * interpreter. This attribute value is often different from the image. - * Any subclass of Token that actually wants to return a non-NULL value can - * override this method as appropriate. + * Tokens which are not used as syntactic sugar will often contain meaningful values + * that will be used later on by the compiler or interpreter. + * This attribute value is often different from the image. + * Any subclass of Token that actually wants to return a non-null value can override + * this method as appropriate. */ - void*& value(); - - const int& kind() const; - const int& beginLine() const; - const int& beginColumn() const; - const int& endLine() const; - const int& endColumn() const; - const JJString& image() const; - const Token* next() const; - const Token* specialToken() const; - const JJString& toString(); - const void* value() const; + void*& value(); + + const int& kind() const; + const int& beginLine() const; + const int& beginColumn() const; + const int& endLine() const; + const int& endColumn() const; + const JJString& image() const; + const Token* next() const; + const Token* specialToken() const; + const JJString& toString(); + const void* value() const; private: - int _kind; - int _beginLine; - int _beginColumn; - int _endLine; - int _endColumn; - JJString _image; - Token* _next; - Token* _specialToken; - void* _value; - -}; - -inline int& Token::kind() { return _kind; } -inline int& Token::beginLine() { return _beginLine; } -inline int& Token::beginColumn() { return _beginColumn; } -inline int& Token::endLine() { return _endLine; } -inline int& Token::endColumn() { return _endColumn; } -inline JJString& Token::image() { return _image; } -inline Token*& Token::next() { return _next; } -inline Token*& Token::specialToken() { return _specialToken; } - -inline const int& Token::kind() const { return _kind; } -inline const int& Token::beginLine() const { return _beginLine; } -inline const int& Token::beginColumn() const { return _beginColumn; } -inline const int& Token::endLine() const { return _endLine; } -inline const int& Token::endColumn() const { return _endColumn; } -inline const JJString& Token::image() const { return _image; } -inline const Token* Token::next() const { return _next; } -inline const Token* Token::specialToken() const { return _specialToken; } - -inline const JJString& Token::toString() { return _image; } - -inline void*& Token::value() { return _value; } -inline const void* Token::value() const { return _value; } - -} - -using JavaCC::Token; + + int _kind; + int _beginLine; + int _beginColumn; + int _endLine; + int _endColumn; + JJString _image; + Token* _next; + Token* _specialToken; + void* _value; + +}; // end class + +inline int& Token::kind() { return _kind; } +inline int& Token::beginLine() { return _beginLine; } +inline int& Token::beginColumn() { return _beginColumn; } +inline int& Token::endLine() { return _endLine; } +inline int& Token::endColumn() { return _endColumn; } +inline JJString& Token::image() { return _image; } +inline Token*& Token::next() { return _next; } +inline Token*& Token::specialToken() { return _specialToken; } + +inline const int& Token::kind() const { return _kind; } +inline const int& Token::beginLine() const { return _beginLine; } +inline const int& Token::beginColumn() const { return _beginColumn; } +inline const int& Token::endLine() const { return _endLine; } +inline const int& Token::endColumn() const { return _endColumn; } +inline const JJString& Token::image() const { return _image; } +inline const Token* Token::next() const { return _next; } +inline const Token* Token::specialToken() const { return _specialToken; } + +inline const JJString& Token::toString() { return _image; } + +inline void*& Token::value() { return _value; } +inline const void* Token::value() const { return _value; } + +} using JavaCC::Token; // end namespace \#endif diff --git a/src/main/resources/templates/cpp/TokenManager.h.template b/src/main/resources/templates/cpp/TokenManager.h.template index 60d5601..878e272 100644 --- a/src/main/resources/templates/cpp/TokenManager.h.template +++ b/src/main/resources/templates/cpp/TokenManager.h.template @@ -1,3 +1,34 @@ +#if PRINT_LICENSE +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#fi \#ifndef JAVACC_TOKEN_MANAGER_H \#define JAVACC_TOKEN_MANAGER_H @@ -11,61 +42,77 @@ namespace JavaCC { -/** - * An implementation for this interface is generated by JavaCCParser. - * The user is free to use any implementation of their choice. +/* + * The interface (declarations) generated by JavaCC/cpp (by CppCodeGenerator.java with + * TokenManager.h.template) that describes the TokenManager. + * An implementation of this interface (ParserTokenManager.h & ParserTokenManager.cc) + * is generated by JavaCC/cpp (by TokenManagerGenerator.java with TokenManagerDriver.h.template & + * TokenManagerDriver.cc.template) if the user does not set the USER_TOKEN_MANAGER option. + * If the user sets this option, he has to implement this interface. */ - #if LIBRARY class ${PARSER_NAME_UPPER_CASE}_API TokenManager { #else class TokenManager { #fi + public: TokenManager() { #if DEBUG_TOKEN_MANAGER - trace = true; + trace = true; #else - trace = false; + trace = false; #fi } - virtual ~TokenManager() {} - - // This gets the next token from the input stream. A token of kind 0 () should be returned on EOF. - virtual Token* getNextToken() = 0; - virtual void lexicalError() = 0; + virtual ~TokenManager() {} + /* + * This gets the next token from the input stream. + * A token of kind 0 () should be returned on EOF. + */ + virtual Token* getNextToken() = 0; + virtual void lexicalError() = 0; #if TOKEN_MANAGER_USES_PARSER - virtual void setParser(void* parser) = 0; + virtual void setParser(void* parser) = 0; #fi -/* - void setErrorHandler(TokenManagerErrorHandler* eh) { +/* + // removed + void setErrorHandler(TokenManagerErrorHandler* eh) { if (delete_eh) delete errorHandler, errorHandler = nullptr; delete_eh = false; // We don't delete stuff passed in. errorHandler = eh; } - const TokenManagerErrorHandler* getErrorHandler() const { return errorHandler; } -*/ + // moved to TableDrivenTokenManager.h.template / TableDrivenTokenManager.cc.template + const TokenManagerErrorHandler* getErrorHandler() const { + return errorHandler; + } +*/ + protected: /* - bool delete_eh = false; - TokenManagerErrorHandler* errorHandler = nullptr; + // moved to TableDrivenTokenManager.h.template + bool delete_eh = false; + // moved to TableDrivenTokenManager.h.template + TokenManagerErrorHandler* errorHandler = nullptr; */ - bool trace; + bool trace; + public: - void enable_tracing() { + void enable_tracing() { #if DEBUG_TOKEN_MANAGER - trace = true; + trace = true; #fi } - void disable_tracing(){ + void disable_tracing() { #if DEBUG_TOKEN_MANAGER trace = false; #fi } - bool trace_enabled() const { return trace; } -}; + bool trace_enabled() const { + return trace; + } + +}; // end class TokenManager -} -using JavaCC::TokenManager; +} using JavaCC::TokenManager; \#endif diff --git a/src/main/resources/templates/cpp/TableDrivenTokenManager.cc.template b/src/main/resources/templates/cpp/TokenManagerDriver.cc.template similarity index 62% rename from src/main/resources/templates/cpp/TableDrivenTokenManager.cc.template rename to src/main/resources/templates/cpp/TokenManagerDriver.cc.template index c6e8946..d5570d7 100644 --- a/src/main/resources/templates/cpp/TableDrivenTokenManager.cc.template +++ b/src/main/resources/templates/cpp/TokenManagerDriver.cc.template @@ -1,65 +1,100 @@ -${decls} +#if PRINT_LICENSE +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#fi +/* + * The class definitions generated by JavaCC/cpp (from TokenManagerDriver.cc.template & + * TokenManagerGenerator.java) that tokenize input for the parser. + */ + +bool ${parserName}TokenManager::moveToNextChar() { + if(input_stream->endOfInput()) + return false; + curChar = input_stream->readChar(); +#if IGNORE_CASE + curChar = towlower(curChar); +#fi + return true; +} -/** Constructor. */ -${parserName}TokenManager::${parserName}TokenManager(CharStream* stream, int lexState) -{ - ReInit(stream, lexState); +/* Constructor. */ +${parserName}TokenManager::${parserName}TokenManager(CharStream* stream, int lexState) { + ReInit(stream, lexState); } -/** Reinitialise parser. */ -void ${parserName}TokenManager::ReInit(CharStream* stream, int lexState) -{ - defaultLexState = ${defaultLexState}; - curLexState = ${defaultLexState}; - moveIndex = 1; - errorHandler = nullptr; - delete_eh = false; +// Beginning of user token manager declarations +${decls} +// End of user token manager declarations + +/* Reinitialise the parser. */ +void ${parserName}TokenManager::ReInit(CharStream* stream, int lexState) { + defaultLexState = ${defaultLexState}; + curLexState = ${defaultLexState}; + moveIndex = 1; + errorHandler = nullptr; + delete_eh = false; #if CPP_USE_ARRAY - std::memset(jjChars.base(), 0, sizeof(jjChars)); + std::memset(jjChars.base(), 0, sizeof(jjChars)); #else - std::memset(jjChars, 0, sizeof(jjChars)); + std::memset(jjChars, 0, sizeof(jjChars)); #fi - for (int i = 0; i < ${nfaSize}; i++) { - int ind = 0; - // We originally generate something like RLE for the static arrays and - // we actually expand them here. - for (int j = 0; j < jjCharData[i][0]; j += 2) { - for (int k = 0; k < jjCharData[i][j + 1]; k++) { - jjChars[i][ind++] = jjCharData[i][j + 2]; - } + for (int i = 0; i < ${nfaSize}; i++) { + int ind = 0; + // We originally generate something like RLE for the static arrays + // and we actually expand them here. + for (int j = 0; j < jjCharData[i][0]; j += 2) { + for (int k = 0; k < jjCharData[i][j + 1]; k++) { + jjChars[i][ind++] = jjCharData[i][j + 2]; } } - - jjmatchedPos = 0; - curLexState = defaultLexState; - input_stream = stream; - SwitchTo(lexState); - errorHandler = new DefaultTokenManagerErrorHandler(); -} - -/** Switch to specified lex state. */ -void ${parserName}TokenManager::SwitchTo(int lexState) -{ - if (lexState > ${lastLexState} || lexState < ${firstLexState}) { - JJString message; - message += JJWIDE(Error: Ignoring invalid lexical state : ); - message += lexState; message += JJWIDE(. State unchanged.); - throw new TokenManagerError(message, INVALID_LEXICAL_STATE); - } else - curLexState = lexState; + } + + jjmatchedPos = 0; + curLexState = defaultLexState; + input_stream = stream; + SwitchTo(lexState); + errorHandler = new DefaultTokenManagerErrorHandler(); } -bool ${parserName}TokenManager::moveToNextChar() { - if(input_stream->endOfInput()) - return false; - - curChar = input_stream->readChar(); -#if IGNORE_CASE - curChar = towlower(curChar); -#fi - return true; +/* Switch to specified lex state. */ +void ${parserName}TokenManager::SwitchTo(int lexState) { + if (lexState > ${lastLexState} || lexState < ${firstLexState}) { + JJString message; + message += JJWIDE(Error: Ignoring invalid lexical state : ); + message += lexState; + message += JJWIDE(. State unchanged.); + throw new TokenManagerError(message, INVALID_LEXICAL_STATE); + } else + curLexState = lexState; } #if !NO_DFA @@ -74,15 +109,21 @@ int ${parserName}TokenManager::jjRunStringLiteralMatch() { int ignoreCase = (int) stringLiterals[index++]; #if DEBUG_TOKEN_MANAGER if (trace_enabled()) { - JJERR << JJWIDE(Looking for string literal match of kind: ) << stringLiterals[index + len] - << JJSPACE << JJWIDE(token image:) << JJSPACE - << JJQUOTE << addUnicodeEscapes(tokenImages[stringLiterals[index + len]]) << JJQUOTE << std::endl; + JJERR << JJWIDE(Looking for string literal match of kind:) << JJSPACE + << stringLiterals[index + len] + << JJWIDE(, token image:) << JJSPACE + << JJDBQUOTE + << addUnicodeEscapes(tokenImages[stringLiterals[index + len]]) + << JJDBQUOTE + << std::endl; } #fi do { #if DEBUG_TOKEN_MANAGER if (trace_enabled()) { - JJERR << JJSPACE << JJSPACE << JJWIDE(Current character:) << JJSPACE << JJQUOTE << ((char)curChar) << JJQUOTE << std::endl; + JJERR << JJWIDE(Cur char:) << JJSPACE << JJQUOTE + << ((char)curChar) << JJQUOTE + << std::endl; } #fi if (curChar != stringLiterals[index + curPos] && @@ -100,10 +141,15 @@ int ${parserName}TokenManager::jjRunStringLiteralMatch() { startState = (int) stringLiterals[index + len + (ignoreCase * len) + 1]; #if DEBUG_TOKEN_MANAGER if (trace_enabled()) { - JJERR << JJSPACE << JJSPACE - << JJWIDE(Currently matched the first:) << JJSPACE << jjmatchedPos << JJSPACE - << JJWIDE(chars as kind:) << JJSPACE << stringLiterals[index + len] << JJCOMMA - << JJWIDE(with image:) << JJSPACE << addUnicodeEscapes(tokenImages[jjmatchedKind]) << std::endl; + JJERR << JJWIDE(Currently matched the first:) << JJSPACE + << jjmatchedPos + << JJSPACE << JJWIDE(chars as kind:) << JJSPACE + << stringLiterals[index + len] + << JJWIDE(, with image:) << JJSPACE + << JJDBQUOTE + << addUnicodeEscapes(tokenImages[jjmatchedKind]) + << JJDBQUOTE + << std::endl; } #fi if (!moveToNextChar()) { @@ -120,11 +166,14 @@ int ${parserName}TokenManager::jjRunStringLiteralMatch() { } } } - } else { #if DEBUG_TOKEN_MANAGER + } else { if (trace_enabled()) { - JJERR << JJWIDE(No string literal start with char:) << JJSPACE << JJQUOTE << ((char)curChar) << JJQUOTE << std::endl; - } + JJERR << JJWIDE(No string literal start with char:) << JJSPACE << JJQUOTE + << ((char)curChar) + << JJQUOTE + << std::endl; + } #fi } return jjMoveNfa(startState, curPos); @@ -184,7 +233,9 @@ int ${parserName}TokenManager::jjMoveNfa(int startState, int curPos) { do { #if DEBUG_TOKEN_MANAGER if (trace_enabled()) { - JJERR << JJSPACE << JJSPACE << JJWIDE(Current character:) << JJSPACE << JJQUOTE << (char)curChar << JJQUOTE << std::endl; + JJERR << JJWIDE(Cur char:) << JJSPACE << JJQUOTE + << (char)curChar << JJQUOTE + << std::endl; } #fi int newCnt = 0; @@ -201,16 +252,20 @@ int ${parserName}TokenManager::jjMoveNfa(int startState, int curPos) { int state = stateSet[--cnt]; #if DEBUG_TOKEN_MANAGER if (trace_enabled()) { - JJERR << JJWIDE(Looking to move from state: ) << JJSPACE << state << JJSPACE << JJWIDE(for:) << JJSPACE - << (jjmatchKinds[state] != INT_MAX - ? addUnicodeEscapes(tokenImages[jjmatchKinds[state]]) : JJWIDE( )) - << std::endl; - JJERR << "state=" << state << " vectorindex=" << vectorIndex << " bitpattern=" << bitpattern - << " jjChars[state][vectorIndex]=" << jjChars[state][vectorIndex] << std::endl; + JJERR << JJWIDE(Looking to move from state: ) << JJSPACE + << state + << JJWIDE(, for token:) << JJSPACE + << (jjmatchKinds[state] != INT_MAX + ? addUnicodeEscapes(tokenImages[jjmatchKinds[state]]) + : JJWIDE()) + << std::endl; + //JJERR << "state=" << state << " vectorindex=" << vectorIndex << " bitpattern=" << bitpattern + // << " jjChars[state][vectorIndex]=" << jjChars[state][vectorIndex] + // << std::endl; } #fi - bool canMoveThisNFAState = (jjChars[state][vectorIndex] & bitpattern) != 0L; - if (canMoveThisNFAState) { + bool canMoveThisNFAState = (jjChars[state][vectorIndex] & bitpattern) != 0L; + if (canMoveThisNFAState) { // Current input character can move this NFA state. So add all the // next states of the current states for use with the next input char. for (int idx = 0; idx < jjnextStateSet[state][0]; idx++) { @@ -228,9 +283,14 @@ int ${parserName}TokenManager::jjMoveNfa(int startState, int curPos) { kind = newKind; #if DEBUG_TOKEN_MANAGER if (trace_enabled()) { - JJERR << JJWIDE(Found a match of kind: ) << kind << JJWIDE(; kind: ) << JJSPACE - << addUnicodeEscapes(tokenLabels[kind]) << JJSPACE << JJWIDE(using the first:) << JJSPACE - << curPos << JJSPACE << JJWIDE(characters.) << std::endl; + JJERR << JJWIDE(Found a match of kind:) << JJSPACE + << kind + << JJSPACE << JJWIDE([) + << addUnicodeEscapes(tokenLabels[kind]) + << JJWIDE(] using the first:) << JJSPACE + << curPos + << JJSPACE << JJWIDE(characters) + << std::endl; } #fi } @@ -260,7 +320,7 @@ int ${parserName}TokenManager::jjMoveNfa(int startState, int curPos) { // current input. So we are done. #if DEBUG_TOKEN_MANAGER if (trace_enabled()) { - JJERR << JJWIDE(Done with NFA at pos: ) << JJSPACE << curPos << std::endl; + JJERR << JJWIDE(Done with NFA at pos:) << JJSPACE << curPos << std::endl; } #fi return curPos; @@ -270,7 +330,7 @@ int ${parserName}TokenManager::jjMoveNfa(int startState, int curPos) { // EOF reached! #if DEBUG_TOKEN_MANAGER if (trace_enabled()) { - JJERR << JJWIDE(Reached EOF here at pos: ) << JJSPACE << curPos << std::endl; + JJERR << JJWIDE(Reached EOF here at pos:) << JJSPACE << curPos << std::endl; } #fi return curPos; @@ -327,24 +387,21 @@ Token * ${parserName}TokenManager::jjFillToken() { endColumn = input_stream->getEndColumn(); #fi } - #if TOKEN_FACTORY - t = ${TOKEN_FACTORY}::newToken(jjmatchedKind, curTokenImage); + t = ${TOKEN_FACTORY}::newToken(jjmatchedKind, curTokenImage); #else - t = ${tokenClass}::newToken(jjmatchedKind, curTokenImage); + t = ${tokenClass}::newToken(jjmatchedKind, curTokenImage); #fi - #if KEEP_LINE_COLUMN - t->beginLine() = beginLine; - t->endLine() = endLine; - t->beginColumn() = beginColumn; - t->endColumn() = endColumn; + t->beginLine() = beginLine; + t->endLine() = endLine; + t->beginColumn() = beginColumn; + t->endColumn() = endColumn; #fi - - return t; + return t; } -/** Get the next Token. */ +/* Get the next Token. */ Token * ${parserName}TokenManager::getNextToken() { Token * specialToken = nullptr; Token * matchedToken; @@ -352,12 +409,16 @@ Token * ${parserName}TokenManager::getNextToken() { EOFLoop: for (;;) { + // First see if we have any input at all. if(input_stream->endOfInput()) { #if DEBUG_TOKEN_MANAGER if (trace_enabled()) { - JJERR << JJWIDE(<) << addUnicodeEscapes(lexStateNames[curLexState]) << JJWIDE(> ) << JJSPACE - << JJWIDE(Reached EOF at ) << JJSPACE << input_stream->getBeginLine() - << JJWIDE(:) << input_stream->getBeginColumn() << std::endl; + JJERR << JJWIDE(<) << addUnicodeEscapes(lexStateNames[curLexState]) << JJWIDE(>) << JJSPACE; + JJERR << JJWIDE(Reached EOF at) << JJSPACE + << input_stream->getBeginLine() + << JJWIDE(:) + << input_stream->getBeginColumn() + << std::endl; } #fi // No input. So return EOF token. @@ -368,7 +429,6 @@ Token * ${parserName}TokenManager::getNextToken() { return matchedToken; } - // First see if we have any input at all. curChar = input_stream->beginToken(); #if IGNORE_CASE curChar = towlower(curChar); @@ -376,20 +436,24 @@ Token * ${parserName}TokenManager::getNextToken() { #if DEBUG_TOKEN_MANAGER if (trace_enabled()) { - JJERR << JJWIDE(<) << addUnicodeEscapes(lexStateNames[curLexState]) << JJWIDE(>) << std::endl - << JJSPACE << JJSPACE << JJWIDE( Current character:) << JJSPACE << JJQUOTE << (char)curChar << JJQUOTE << JJSPACE - << JJWIDE( at ) << JJSPACE << input_stream->getBeginLine() - << JJWIDE(:) << input_stream->getBeginColumn() << std::endl; + JJERR << JJWIDE(<) << addUnicodeEscapes(lexStateNames[curLexState]) << JJWIDE(>) << JJSPACE; + JJERR << JJWIDE( Current input char:) << JJSPACE << JJQUOTE + << (char)curChar + << JJQUOTE << JJSPACE << JJWIDE(at) << JJSPACE + << input_stream->getBeginLine() + << JJWIDE(:) + << input_stream->getBeginColumn() + << std::endl; } #fi - // Set matched kind to a MAX VALUE to implement largest, first occuring rule + // Set matched kind to a MAX VALUE to implement largest, first occurring rule // i.e., smallest kind value matched should be used. image = jjimage; // image->setLength(0); jjimageLen = 0; - for (;;) { + for (;;) { // inner loop jjmatchedKind = INT_MAX; jjmatchedPos = 0; #if !NO_DFA @@ -401,8 +465,10 @@ Token * ${parserName}TokenManager::getNextToken() { jjmatchedKind = canMatchAnyChar[curLexState]; #if DEBUG_TOKEN_MANAGER if (trace_enabled()) { - JJERR << JJWIDE(Matched current char:) << JJSPACE << JJQUOTE << (char)curChar << JJQUOTE << JJSPACE - << JJWIDE(as a wildcard kind:) << JJSPACE << jjmatchedKind + JJERR << JJWIDE(Matched current char:) << JJSPACE << JJQUOTE + << (char)curChar + << JJQUOTE << JJSPACE << JJWIDE(as a wildcard kind:) << JJSPACE + << jjmatchedKind << std::endl; } #fi @@ -410,7 +476,6 @@ Token * ${parserName}TokenManager::getNextToken() { if (jjmatchedKind != INT_MAX) { // We have a match! - // Put back any characters looked ahead. input_stream->backup(lastReadPosition - jjmatchedPos); if (isToken(jjmatchedKind)) { @@ -427,19 +492,19 @@ Token * ${parserName}TokenManager::getNextToken() { #if DEBUG_TOKEN_MANAGER if (trace_enabled()) { JJERR << JJWIDE(Returning token:) << JJSPACE << JJQUOTE - << addUnicodeEscapes(matchedToken->image()) << JJQUOTE << JJSPACE + << addUnicodeEscapes(matchedToken->image()) + << JJQUOTE << std::endl; } #fi return matchedToken; - } else - if (isSkip(jjmatchedKind) || isSpecial(jjmatchedKind)) { + } else if (isSkip(jjmatchedKind) || isSpecial(jjmatchedKind)) { + // Matched kind is a SKIP or SPECIAL_TOKEN. #if DEBUG_TOKEN_MANAGER if (trace_enabled()) { - JJERR << JJWIDE(Found a SKIP match.) << std::endl; + JJERR << JJWIDE(Found a SKIP match) << std::endl; } #fi - // Matched kind is a SKIP or SPECIAL_TOKEN. if (isSpecial(jjmatchedKind)) { matchedToken = jjFillToken(); if (specialToken == nullptr) { @@ -457,12 +522,12 @@ Token * ${parserName}TokenManager::getNextToken() { } goto EOFLoop; } + // Here it's a MORE. #if DEBUG_TOKEN_MANAGER if (trace_enabled()) { - JJERR << JJWIDE(Found a MORE match.) << std::endl; + JJERR << JJWIDE(Found a MORE match) << std::endl; } #fi - // Here it's a MORE. moreLexicalActions(); if (jjnewLexState[jjmatchedKind] != -1) { curLexState = jjnewLexState[jjmatchedKind]; @@ -476,40 +541,40 @@ Token * ${parserName}TokenManager::getNextToken() { #fi } while(curChar >= 0); } + + /* reportError inlined */ int error_line = input_stream->getEndLine(); int error_column = input_stream->getEndColumn(); JJString error_after = JJEMPTY; bool EOFSeen = false; - if(input_stream->endOfInput()) { EOFSeen = true; error_after = lastReadPosition <= 1 ? JJEMPTY : input_stream->getImage(); if (curChar == '\n' || curChar == '\r') { - error_line++; - error_column = 0; + error_line++; + error_column = 0; + } else { + error_column++; } - else - error_column++; } if (!EOFSeen) { error_after = lastReadPosition <= 1 ? JJEMPTY : input_stream->getImage(); } errorHandler->lexicalError(EOFSeen, curLexState, error_line, error_column, error_after, curChar); goto EOFLoop; - } - } + } // inner loop + } // EOFLoop } #if TOKEN_MANAGER_USES_PARSER void ${parserName}TokenManager::setParser(void* parser) { - this->parser = static_cast<${parserName}*>(parser); + this->parser = static_cast<${parserName}*>(parser); } #fi void ${parserName}TokenManager::lexicalError() { - std::clog << "Lexical error encountered." << std::endl; + std::clog << "Lexical error encountered." << std::endl; } + const TokenManagerErrorHandler* ${parserName}TokenManager::getErrorHandler() const { return errorHandler; } - - diff --git a/src/main/resources/templates/cpp/TokenManagerDriver.h.template b/src/main/resources/templates/cpp/TokenManagerDriver.h.template new file mode 100644 index 0000000..da5e3ec --- /dev/null +++ b/src/main/resources/templates/cpp/TokenManagerDriver.h.template @@ -0,0 +1,125 @@ +#if PRINT_LICENSE +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#fi +\#ifndef JAVACC_${PARSER_NAME_UPPER_CASE}_TOKEN_MANAGER_H +\#define JAVACC_${PARSER_NAME_UPPER_CASE}_TOKEN_MANAGER_H + +#if LIBRARY +\#include "ImportExport.h" +#fi +\#include "JavaCC.h" +\#include "CharStream.h" +#if tokenInclude +\#include "${tokenInclude}" +#fi +\#include "ParserErrorHandler.h" +\#include "TokenManager.h" +\#include "${parserName}Constants.h" +#if TOKEN_MANAGER_USES_PARSER +\#include "${parserName}.h" +#fi + +#if NAMESPACE +namespace ${NAMESPACE_OPEN} +#fi + +/* + * The class (declarations) generated by JavaCC/cpp (from TokenManagerDriver.h.template & + * TokenManagerGenerator.java) that tokenizes input for the parser. + */ +#if LIBRARY +class ${PARSER_NAME_UPPER_CASE}_API ${parserName}TokenManager : public TokenManager { +#else +class ${parserName}TokenManager : public TokenManager { +#fi + +private: + int defaultLexState; + int curLexState = ${defaultLexState}; + int jjmatchedPos; + int jjmatchedKind; + int moveIndex; +#if CPP_USE_ARRAY + Array<${nfaSize}, Array<${charsVectorSize}, unsigned long long>> jjChars; +#else + unsigned long long jjChars[${nfaSize}][${charsVectorSize}]; +#fi + JJString jjimage; + JJString image; + int jjimageLen; + int lengthOfMatch; + JJChar curChar; + CharStream* input_stream; + TokenManagerErrorHandler* errorHandler; + bool delete_eh; + int jjrounds[${stateSetSize}]; + int jjstateSet[2 * ${stateSetSize}]; + +public: + ${parserName}TokenManager(CharStream* stream, int lexState = 0); + virtual ~${parserName}TokenManager() {} + Token* getNextToken(); +#if COMMON_TOKEN_ACTION + void CommonTokenAction(Token* token); +#fi +#if TOKEN_MANAGER_USES_PARSER + void setParser(void* parser); + +protected: + ${parserName}* parser; +#else + +protected: +#fi + bool moveToNextChar(); + void ReInit(CharStream* stream, int lexState = 0); + void SwitchTo(int lexState); + +private: + void tokenLexicalActions(Token* matchedToken); + void skipLexicalActions(const Token* matchedToken); + void moreLexicalActions(); + int getStartAndSize(int index, int isCount); + int jjRunStringLiteralMatch(); + int jjMoveNfa(int startState, int curPos); + Token* jjFillToken(); + +public: + void lexicalError(); + const TokenManagerErrorHandler* getErrorHandler() const; + +}; // end class ${parserName}TokenManager + +#if NAMESPACE +${NAMESPACE_CLOSE} // end namespace +#fi + +\#endif diff --git a/src/main/resources/templates/cpp/TokenManagerError.cc.template b/src/main/resources/templates/cpp/TokenManagerError.cc.template index 2c48e6d..93c4174 100644 --- a/src/main/resources/templates/cpp/TokenManagerError.cc.template +++ b/src/main/resources/templates/cpp/TokenManagerError.cc.template @@ -1,35 +1,70 @@ +#if PRINT_LICENSE +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#fi #if NAMESPACE namespace ${NAMESPACE_OPEN} #fi - +/* + * The class definitions generated by JavaCC/cpp (by CppCodeGenerator.java with + * TokenManagerError.cc.template) used when TokenManager errors are encountered. + */ + JJString TokenManagerError::lexicalError(bool EOFSeen, int lexState, int errorLine, int errorColumn, const JJString& errorAfter, JJChar curChar) { JJString s; \#if (JAVACC_CHAR_TYPE_SIZEOF == 1) - s += "Lexical error at line "; - s += std::to_string(errorLine); - s += ":"; - s += std::to_string(errorColumn); - s += ". Encountered: "; - s += curChar; - s += "("; - s += std::to_string((int)curChar); - s += ") after: "; - s += errorAfter; + s += "Lexical error at line "; + s += std::to_string(errorLine); + s += ", column "; + s += std::to_string(errorColumn); + s += ". Encountered: "; + s += curChar; + s += " ("; + s += std::to_string((int)curChar); + s += ") after: "; + s += errorAfter; \#else - s += L"Lexical error at line "; - s += std::to_wstring(errorLine); - s += L":"; - s += std::to_wstring(errorColumn); - s += L". Encountered: "; - s += curChar; - s += L"("; - s += std::to_wstring((int)curChar); - s += L") after: "; - s += errorAfter; + s += L"Lexical error at line "; + s += std::to_wstring(errorLine); + s += L", column "; + s += std::to_wstring(errorColumn); + s += L". Encountered: "; + s += curChar; + s += L" ("; + s += std::to_wstring((int)curChar); + s += L") after: "; + s += errorAfter; \#endif - return s; - } + return s; +} JJString TokenManagerError::getMessage() { return message; @@ -38,17 +73,21 @@ JJString TokenManagerError::getMessage() { TokenManagerError::TokenManagerError() { errorCode = -1; } + TokenManagerError::TokenManagerError(const JJString & message, int reason) { errorCode = reason; } + TokenManagerError::TokenManagerError(bool EOFSeen, int lexState, int errorLine, int errorColumn, const JJString& errorAfter, JJChar curChar, int reason) { message = lexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar); errorCode = reason; } + TokenManagerError::~TokenManagerError() { } + #if NAMESPACE -${NAMESPACE_CLOSE} +${NAMESPACE_CLOSE} // end namespace #fi // i < 16 - guaranteed @@ -59,7 +98,7 @@ static char hexChar(int i) { return 'a' + (i - 10); } -/** +/* * Replaces unprintable characters by their escaped (or unicode escaped) * equivalents in the given string */ @@ -86,8 +125,7 @@ JJString addUnicodeEscapes(const JJString& str) { JJString retval; for (size_t i = 0; i < str.size(); i++) { JJChar ch = str[i]; - switch (ch) - { + switch (ch) { case '\b': retval.append(JJB); continue; diff --git a/src/main/resources/templates/cpp/TokenManagerError.h.template b/src/main/resources/templates/cpp/TokenManagerError.h.template index ccef900..34eb259 100644 --- a/src/main/resources/templates/cpp/TokenManagerError.h.template +++ b/src/main/resources/templates/cpp/TokenManagerError.h.template @@ -1,3 +1,34 @@ +#if PRINT_LICENSE +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#fi \#ifndef JAVACC_TOKEN_MANAGER_ERROR_H \#define JAVACC_TOKEN_MANAGER_ERROR_H @@ -8,40 +39,43 @@ namespace ${NAMESPACE_OPEN} #fi enum LexerErrors { - LEXICAL_ERROR = 0, // Lexical error occurred. - STATIC_LEXER_ERROR = 1, // An attempt was made to create a second instance of a token manager. - INVALID_LEXICAL_STATE = 2, // Tried to change to an invalid lexical state. - LOOP_DETECTED = 3, // Detected (and bailed out of) an infinite loop in the token manager. + LEXICAL_ERROR = 0, // Lexical error occurred. + STATIC_LEXER_ERROR = 1, // An attempt was made to create a second instance of a token manager. + INVALID_LEXICAL_STATE = 2, // Tried to change to an invalid lexical state. + LOOP_DETECTED = 3, // Detected (and bailed out of) an infinite loop in the token manager. }; +/* + * The class (declarations) generated by JavaCC/cpp (by CppCodeGenerator.java with + * TokenManagerError.h.template) used when TokenManager errors are encountered. + */ class TokenManagerError { + public: + TokenManagerError(); TokenManagerError(const JJString& message, int reason); TokenManagerError(bool EOFSeen, int lexState, int errorLine, int errorColumn, const JJString& errorAfter, JJChar curChar, int reason) ; virtual ~TokenManagerError(); - /** - * Indicates the reason why the exception is thrown. It will have - * one of the above 4 values. - */ + /* Indicates the reason why the exception is thrown. It will have one of the above 4 values. */ int errorCode; - /** - * Returns a detailed message for the Error when it is thrown by the - * token manager to indicate a lexical error. - * Parameters : - * EOFSeen : indicates if EOF caused the lexical error - * curLexState : lexical state in which this error occurred - * errorLine : line number when the error occurred - * errorColumn : column number when the error occurred - * errorAfter : prefix that was seen before this error occurred - * curchar : the offending character + /* + * Returns a detailed message for the Error when it is thrown by the token manager + * to indicate a lexical error.
* Note: You can customize the lexical error message by modifying this method. + * + * @param eofSeen - true if EOF caused the lexical error + * @param curLexState - lexical state in which this error occurred + * @param errorLine - line number when the error occurred + * @param errorColumn - column number when the error occurred + * @param errorAfter - prefix that was seen before this error occurred + * @param curchar - the offending character */ virtual JJString lexicalError(bool EOFSeen, int lexState, int errorLine, int errorColumn, const JJString& errorAfter, JJChar curChar); - /** + /* * You can also modify the body of this method to customize your error messages. * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not * of end-users concern, so you can return something like : @@ -50,16 +84,16 @@ public: * * from this method for such cases in the release version of your parser. */ -public: JJString getMessage() ; private: + JJString message; -}; +}; // end class #if NAMESPACE -${NAMESPACE_CLOSE} +${NAMESPACE_CLOSE} // end namespace #fi \#endif diff --git a/src/main/resources/templates/cpp/TokenManagerErrorHandler.h.template b/src/main/resources/templates/cpp/TokenManagerErrorHandler.h.template index bc07dab..e0cd589 100644 --- a/src/main/resources/templates/cpp/TokenManagerErrorHandler.h.template +++ b/src/main/resources/templates/cpp/TokenManagerErrorHandler.h.template @@ -1,18 +1,60 @@ +#if PRINT_LICENSE +/* + * Copyright (c) 2020-2025, Sreeni Viswanadha . + * Copyright (c) 2024-2025, Marc Mazas . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#fi \#ifndef JAVACC_TOKEN_MANAGER_ERROR_HANDLER_H \#define JAVACC_TOKEN_MANAGER_ERROR_HANDLER_H +// shouldn't BUILD_TOKEN_MANAGER condition be in TokenManagerCodeGenerator.java? #if BUILD_TOKEN_MANAGER \#include "JavaCC.h" \#include "Token.h" namespace JavaCC { +/* + * The interface (declarations) generated by JavaCC/cpp (by TokenManagerCodeGenerator.java with + * TokenManagerErrorHandler.h.template) that describes the token manager error handler. + * An implementation of this interface (DefaultTokenManagerErrorHandler.h & + * DefaultTokenManagerErrorHandler.cc) is generated by JavaCC/cpp (by CppCodeGenerator.java with + * DefaultTokenManagerErrorHandler.h.template & DefaultTokenManagerErrorHandler.cc.template). + * It seems that, for the moment, the user cannot tell JavaCC to generate a token manager + * referencing a user custom implementation of this interface. + */ class TokenManagerErrorHandler { + public: - TokenManagerErrorHandler() : error_count(0) {} + + TokenManagerErrorHandler() : error_count(0) {} virtual ~TokenManagerErrorHandler() {} - -public: + // Returns a detailed message for the Error when it is thrown by the // token manager to indicate a lexical error. // Parameters : @@ -23,16 +65,24 @@ public: // errorAfter : prefix that was seen before this error occurred // curchar : the offending character // - virtual void lexicalError(bool EOFSeen, int lexState, int errorLine, int errorColumn, JJString errorAfter, JJChar curChar) = 0; + virtual void lexicalError(bool EOFSeen, + int lexState, + int errorLine, + int errorColumn, + JJString errorAfter, + JJChar curChar) = 0; + virtual void lexicalError(const JJString& errorMessage) = 0; - int getErrorCount() const { return error_count; } + + int getErrorCount() const { return error_count; } protected: + int error_count; -}; -} -using JavaCC::TokenManagerErrorHandler; +}; // end class + +} using JavaCC::TokenManagerErrorHandler; // end namespace #fi \#endif