Skip to content

Instantly share code, notes, and snippets.

@yydai
Created February 5, 2017 03:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yydai/2daa663adbe51b09a24f93a3881858bb to your computer and use it in GitHub Desktop.
Save yydai/2daa663adbe51b09a24f93a3881858bb to your computer and use it in GitHub Desktop.
Chapter3 of antlr4----convert initialized Java short arrays to strings(like {1,2,3} to "\u0001\u0002\u0003")
/** Grammars always start with a grammar header. This grammar is called
* ArrayInit and must match the filename: ArrayInit.g4
*/
grammar ArrayInit;
/** A rule called init that matches comma-separated values between {...}. */
init : '{' value (',' value)* '}' ; // must match at least one value
/** A value can be either a nested array/struct or a simple integer (INT) */
value : init
| INT
;
// parser rules start with lowercase letters, lexer rules with uppercase
INT : [0-9]+ ; // Define token INT as one or more digits
WS : [ \t\r\n]+ -> skip ; // Define whitespace rule, toss it out
/**
* Created by yingdai on 2017/1/26.
* In English, the translation is a series of “X goes to Y” rules.
* 1. Translate { to ".
* 2. Translate } to ".
* 3. Translate integers to four-digit hexadecimal strings prefixed with \u.
*/
public class ShortToUnicodeString extends ArrayInitBaseListener{
public void enterInit(ArrayInitParser.InitContext ctx) {
System.out.print('"'); }
/** Translate } to " */
@Override
public void exitInit(ArrayInitParser.InitContext ctx) {
System.out.print('"'); }
/** Translate integers to 4-digit hexadecimal strings prefixed with \\u */
@Override
public void enterValue(ArrayInitParser.ValueContext ctx) {
// Assumes no nested array initializers
int value = Integer.valueOf(ctx.INT().getText());
System.out.printf("\\u%04x", value);
}
}
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
public class Test {
public static void main(String[] args) throws Exception {
// create a CharStream that reads from standard input
ANTLRInputStream input = new ANTLRInputStream(System.in); // create a lexer that feeds off of input CharStream
ArrayInitLexer lexer = new ArrayInitLexer(input); // create a buffer of tokens pulled from the lexer
CommonTokenStream tokens = new CommonTokenStream(lexer); // create a parser that feeds off the tokens buffer
ArrayInitParser parser = new ArrayInitParser(tokens);
ParseTree tree = parser.init(); // begin parsing at init rule
System.out.println(tree.toStringTree(parser)); // print LISP-style tree }
}
}
/*
➾ $ javac ArrayInit*.java Test.java
➾ $ java Test
➾ {1,{2,3},4} ➾EOF
❮ (init { (value 1) , (value (init { (value 2) , (value 3) })) , (value 4) })
*/
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
public class Translate {
public static void main(String[] args) throws Exception{
ANTLRInputStream input = new ANTLRInputStream(System.in);
ArrayInitLexer lexer = new ArrayInitLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
ArrayInitParser parser = new ArrayInitParser(tokens);
ParseTree tree = parser.init();
ParseTreeWalker walker = new ParseTreeWalker();
walker.walk(new ShortToUnicodeString(), tree);
System.out.println();
}
}
/* commands:
parse tree dialog box:
➾ $ grun ArrayInit init -gui
➾ $ {1,{2,3},4}
➾ $ EOF
================
➾ $ antlr4 ArrayInit.g4 # Generate parser and lexer using antlr4 alias
➾ $ javac ArrayInit*.java Translate.java
➾ $ java Translate
➾ {99, 3, 451} ➾EOF
❮ "\u0063\u0003\u01c3"
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment