Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHP target generates invalid output when $ is used as part of the literal in lexer rule #2709

Closed
adamwojs opened this issue Jan 2, 2020 · 1 comment · Fixed by #2945
Closed
Milestone

Comments

@adamwojs
Copy link
Contributor

adamwojs commented Jan 2, 2020

Steps to reproduce

Generate lexer using PHP target from the following grammar

lexer grammar TestLexer;

DOLAR_ACTION: '$ACTION';

using ANTLR build from the current master branch

Actual behavior

ANTLR produces invalid PHP code (it's not allowed to use variables as part of the constant expression)

final class TestLexer extends Lexer
{
        # ...

	/**
	 * @var array<string|null>
	 */
	private const LITERAL_NAMES = [
	    null, "'$ACTION'"  
	];

        # ...
 }
PHP Fatal error:  Constant expression contains invalid operations in /home/awojs/Projekty/grammars-v4/tsql/target/TestLexer.php on line 48

Expected behavior

$ character in PHP Target is escaped

final class TestLexer extends Lexer
{
    # ...

	/**
	 * @var array<string|null>
	 */
	private const LITERAL_NAMES = [
	    null, "'\$ACTION'"
	];

    # ...
 }

Patch proposal

This seems to solve a problem

diff --git a/tool/src/org/antlr/v4/codegen/target/PHPTarget.java b/tool/src/org/antlr/v4/codegen/target/PHPTarget.java
index 2617565fb..6a9ba31d9 100644
--- a/tool/src/org/antlr/v4/codegen/target/PHPTarget.java
+++ b/tool/src/org/antlr/v4/codegen/target/PHPTarget.java
@@ -102,4 +102,11 @@ public class PHPTarget extends Target {
        protected void appendUnicodeEscapedCodePoint(int codePoint, StringBuilder sb) {
                UnicodeEscapes.appendPythonStyleEscapedCodePoint(codePoint, sb);
        }
+
+       @Override
+       public String getTargetStringLiteralFromANTLRStringLiteral(CodeGenerator generator, String literal, boolean addQuotes) {
+               String targetStringLiteral = super.getTargetStringLiteralFromANTLRStringLiteral(generator, literal, addQuotes);
+               targetStringLiteral = targetStringLiteral.replace("$", "\\$");
+               return targetStringLiteral;
+       }
 }

but maybe problem is more generic and getTargetStringLiteralFromANTLRStringLiteral should take into account all characters from targetCharValueEscape ?

@marcospassos
Copy link
Contributor

Hey @adamwojs, sorry for the delayed reply.

I think escaping in getTargetStringLiteralFromANTLRStringLiteral should be enough. Could you please open a PR including tests?

adamwojs added a commit to adamwojs/antlr4 that referenced this issue Oct 20, 2020
adamwojs added a commit to adamwojs/antlr4 that referenced this issue Oct 20, 2020
@parrt parrt added this to the 4.9 milestone Nov 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants