Escribir un compilador en Java (1) -análisis léxico y gramatical

Instalación de ANTLR
$ cd / usr / local / lib
$ wget https://www.antlr.org/download/antlr-4.7.1-complete.jar
$ export CLASSPATH = ".: / Usr / local / lib / antlr-4.7 .1-complete.jar: $ CLASSPATH "
$ alias antlr4 = 'java -jar /usr/local/lib/antlr-4.7.1-complete.jar'
$ alias grun = 'java org.antlr.v4.gui.TestRig '
análisis léxico y las definiciones léxicas Antlr
análisis léxico es hablar la secuencia de caracteres palabra en una secuencia de procesos. Una palabra es la unidad más pequeña que constituye el código fuente y consta de uno o más caracteres consecutivos. Por ejemplo, si realizamos un análisis léxico en el código int año = 2018, el código fuente se convertirá en una secuencia de 5 palabras: int, \ s (espacio), año, = y 2018.

La definición léxica de antlr es relativamente simple y la mayoría de los métodos léxicos se pueden expresar usando expresiones regulares simples. Veamos un ejemplo simple de DemoLexer.g4:

Grammer Demo the lexer;
PLUS: '+';
MINUS: '-';
the MULTIPLE: '*';
the DIV: '/';
LPAREN: '(';
RPAREN: ')';
NUMBER: [0-9] +;
primero La línea 1 declara que este es un archivo de definición léxica.Las líneas 2-7 definen 4 palabras clave de operador y dos paréntesis izquierdo y derecho.La línea 8 es la definición de un entero positivo.

Análisis gramatical y definición de gramática antlr El
análisis gramatical es el proceso de analizar la entrada compuesta por secuencias de palabras y determinar su estructura gramatical de acuerdo con una gramática formal específica. Por ejemplo, las secuencias de 5 palabras de int, \ s (espacio), año, = y 2018 se ingresan en el analizador sintáctico en orden, y el analizador puede reconocer que esta es una declaración de declaración e inicialización de variable.

La definición gramatical de antlr es similar a la definición léxica y enumera todas las combinaciones posibles de palabras. Tomemos como ejemplo una definición simple de cuatro gramática aritmética.

DemoParser.g4

analizador gramatical DemoParser;
options {tokenVocab = DemoLexer;}
expr:
'(' expr ')'
| NUMBER (MULTIPLE | DIV) NUMBER
| NUMBER (PLUS | MINUS) NUMBER
; La
primera línea declara que este es un archivo de definición gramatical, la segunda Establezca la opción léxica en la línea para indicar qué léxico usar.Las líneas 3-7 son la definición gramatical de la expresión de la operación. Aquí hay una breve introducción, expr es el nombre que le dimos a la gramática Esta gramática tiene tres casos: expresiones entre paréntesis, expresiones de multiplicación y división y expresiones de suma y resta. Cabe señalar que el orden de definición de las expresiones de multiplicación y división y las expresiones de suma y resta no se pueden intercambiar arbitrariamente, de lo contrario afectará la precedencia de los operadores y dará como resultado un árbol de análisis incorrecto. Las expresiones de alta prioridad deben definirse primero.

Genere analizador léxico y analizador gramatical. Lo
anterior es solo la definición de léxico y gramática antlr, que no se puede usar directamente en java, porque no es un código fuente legal de java, necesitamos convertirlo en código java, este trabajo de conversión aún lo realiza antlr para nosotros llevar a cabo. Ejecute el siguiente comando en la terminal:

Antlr4 DemoLexer.g4 -package demo.antlr antlr4
DemoParser.g4 -package demo.antlr -visitor Después de ejecutar el
comando, los siguientes archivos se generarán automáticamente:

DemoLexer.java
DemoLexer.tokens
DemoParser.java
DemoParser.tokens
DemoParserBaseListener.java
DemoParserBaseVisitor.java
DemoParserListener.java
DemoParserVisitor.java
Estos archivos java son el analizador léxico y el analizador de sintaxis que podemos llamar directamente en el programa.

Uso del analizador léxico y el analizador gramatical Una vez que el
analizador léxico y el analizador gramatical generados se copian en el directorio fuente, se pueden usar directamente. Echemos un vistazo a los métodos de llamada más utilizados:

String source = "1 + 2 + 3"; // La expresión que necesitamos analizar
CharStream charStream = new ANTLRInputStream (fuente);
DemoLexer lexer = new DemoLexer (charStrem); // Analizador léxico
CommonTokenStream tokenStream = new CommonTokenStream (lexer) ;
DemoParser parser = new DemoParser (tokenStream); // Parser
ExprContext exprContext = parser.expr (); // Comience a analizar con la regla expr como regla de inicio y obtenga el analizador gramatical.
A través de los pasos anteriores, la cadena de expresión finalmente Convertido en un árbol de análisis sintáctico, con un árbol de análisis sintáctico, resulta muy sencillo evaluar expresiones. Primero, primero definimos un dispositivo MainDemoParserVisitor.java de visita de árbol de análisis (transversal):

public MainDemoParserVisitor extiende DemoParserBaseVisitor { @override public Integer visitExpr (ExprContext ctx) { if (ctx.MULTIPLE ()! = null) {// 乘法return Integer.parseInt (ctx.NUMBER (0)) * Integer.parseInt (ctx.NUMBER) (1)); } else if (ctx.DIV ()! = null) {// 除法return Integer.parseInt (ctx.NUMBER (0)) / Integer.parseInt (ctx.NUMBER (1)); } else if (ctx.PLUS ()! = null) {// 加法return Integer.parseInt (ctx.NUMBER (0)) + Integer.parseInt (ctx.NUMBER (1)); } else if (ctx.MINUS ()! = null) {// 减法return Integer.parseInt (ctx.NUMBER (0)) - Integer.parseInt (ctx.NUMBER (1)); } else {// 对 括号 内 表达式 求 值return visitExpr (ctx.expr ()); } }













}
Utilice el descriptor de acceso para recorrer y evaluar el árbol de análisis:

MainDemoParserVisitor visitor = new MainDemoParserVisitor (); // Crear un visitante
Integer result = (Integer) vistor.visit (exprContext); // Comenzar a recorrer el árbol de análisis sintáctico para evaluar la expresión
System.out.println (resultado);
Evaluación de Amazon www .yisuping.com

Supongo que te gusta

Origin blog.csdn.net/weixin_45032957/article/details/108399280
Recomendado
Clasificación