Я столкнулся с проблемой с моим парсером javascript.Мой парсер, сгенерированный на Java из следующей грамматики, хорошо работает с UTF-8.Вот моя следующая грамматика:
LabeledWims.g4
grammar LabeledWims;
NUM_INT : [0-9]+;
NUM_REAL : [0-9]+(('.' [0-9] + (EXPONENT)?)? | EXPONENT);
fragment EXPONENT : ('e') ('+' | '-')? [0-9] +;
PLUS : '+';
MINUS : '-';
STAR : '*';
SLASH : '/';
POWER : '^';
DOT : '.';
OB : '{';
CB : '}';
OP : '(';
CP : ')';
YES : 'yes';
NO : 'no';
DOTS : '..';
EQUAL : '=';
BSLASH : '\\';
CRLF : '\r'? '\n' | '\r';
WS : (' ' | '\t' | '\r' | '\n') -> skip;
//NEWLINE : '\n';
/*==============================================================*/
/*======================== Keywords ============================*/
/*==============================================================*/
RANDINT : 'randint';
KEYWORD
: RANDINT
| 'shuffle'
| 'rows'
; // TO BE COMPLETED...
TYPE : 'type'; //TYPE OF ANSWER DECLARATION
ANSWERTYPE
: 'numeric' | 'numexp' | 'units' | 'range'| 'vector' | 'matrix' //NUMERICAL VALUES
| 'correspond' //ASSOCIATION OF OBJECTS
| 'case' | 'nocase' | 'atext' //WORD
| 'menu' | 'radio' | 'click' | 'checkbox' | 'flashcard' | 'mark' //MULTIPLE CHOICE 1
| 'dragfill' | 'clickfill' //MULTIPLE CHOICE 1
| 'function' | 'algexp' | 'litexp' //MATH EXPRESSION // MATH FORMULA
;
ID : [a-zA-Z] ([a-zA-Z] | [0-9] | '-' | '_' )*;
// Doc https://github.com/antlr/antlr4/blob/master/doc/lexer-rules.md#lexer-rule-elements
// INCLUDE THESE TOKENS makes unicode char include in string rule
EMOJI : [\p{Emoji}] ;
JAPANESE : [\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Han}] ;
NOT_CYRILLIC : [\P{Script=Cyrillic}] ;
/*==============================================================*/
/*=================== WIMS Commands ============================*/
/*==============================================================*/
TITLE : BSLASH 'title';
LANGUAGE : BSLASH 'language';
AUTHOR : BSLASH 'author';
EMAIL : BSLASH 'email';
COMPUTEANSWER : BSLASH 'computeanswer';
PRECISION : BSLASH 'precision';
RANGE : BSLASH 'range';
STATEMENT : BSLASH 'statement';
HINT : BSLASH 'hint';
HELP : BSLASH 'help';
/*=================== Assignement Commands =====================*/
INTEGER : BSLASH 'integer';
RATIONAL : BSLASH 'rational';
REAL : BSLASH 'real';
COMPLEX : BSLASH 'complex';
TEXT : BSLASH 'text';
MATRIX : BSLASH 'matrix';
FUNCTION : BSLASH 'function';
//ASSIGNEMENT : INTEGER | RATIONAL | REAL | COMPLEX | TEXT | MATRIX | FUNCTION;
/*=================== Answer Commands ==========================*/
ANSWER : BSLASH 'answer';
CONDITION : BSLASH 'condition';
FEEDBACK : BSLASH 'feedback';
SOLUTION : BSLASH 'solution';
/*===========After all keywords, let s authorize the rest in unicode ========*/
sentence
: (string | callvariable | KEYWORD OP )+?
;
//string : (STRING)+;
string
: (~(BSLASH| CB))+ ;
/*==============================================================*/
/*==================== Variable Assignements ===================*/
/*==============================================================*/
integer
: INTEGER OB assignement CB #printInt
;
rational
: RATIONAL OB assignement CB
;
real
: REAL OB assignement CB
;
complex
: COMPLEX OB assignement CB
;
text
: TEXT OB assignement CB
;
matrix
: MATRIX OB assignement CB
;
founction
: FUNCTION OB assignement CB
;
assignement
: ID EQUAL expression #assign
;
/*==============================================================*/
/*====================== EXPRESSIONS ===========================*/
/*==============================================================*/
expression
: expression op=(PLUS | MINUS) expression #addSub
| expression op=(STAR | SLASH) expression #mulDiv
| expression POWER expression #power //operator is right associative normally add <assoc=right> but generate warning
| (PLUS | MINUS) expression #pluMin
| OP expression CP #parens
| RANDINT OP expression DOTS expression CP #keyRandint
| callvariable #id
| NUM_INT #numInt
| NUM_REAL #numReal
;
callvariable
: BSLASH ID
;
/*==============================================================*/
/*=================== WIMS EXERCICE ============================*/
/*==============================================================*/
//PRE EXERCISE PART
title
: TITLE OB string CB
;
language
: LANGUAGE OB string CB
;
author
: AUTHOR OB string CB
;
email
: EMAIL OB string CB
;
computeanswer
: COMPUTEANSWER OB ( YES| NO) CB
;
precision
: PRECISION OB NUM_INT CB
;
rangedeclaration
: RANGE OB expression DOTS expression CB
;
//DURING EXERCISE PART
statement
: STATEMENT OB sentence CB #statementExercise
;
hint
: HINT OB sentence CB
;
help
: HELP OB sentence CB
;
//POST EXERCISE PART
answer
: ANSWER OB sentence CB
OB callvariable CB
answertype
;
answertype
: OB TYPE EQUAL ANSWERTYPE CB
;
condition
: OB sentence CB
;
feedback
: FEEDBACK OB sentence CB
;
solution
: SOLUTION OB sentence CB
;
wims :
title
('\n')+language
('\n')+author
('\n')+email
('\n')+computeanswer
('\n')+precision
(('\n')+rangedeclaration)*
(('\n')+integer)*
('\n')+statement
('\n')+answer
;
Пример простого исходного кода, который я хочу проанализировать:
\title{Un pré bis}
\language{fr}
\author{Mr. Toto}
\email{toto@univ.com}
\computeanswer{no}
\precision{10000}
\integer{L = 10*randint(1..10)}
\integer{l = 10*randint(1..10) }
\integer{per = 2*(\L+\l)}
\statement{Donner le périmètre d'un pré rectangulaire de longueur \L m et de largeur \l m.}
\answer{périmetre (en m)}{\per}{type=numeric}
Я сгенерировал мой анализатор Java с помощью:
antlr4 -no-listener -visitor LabeledWims.g4
Затем я вызываю в основном классе Java анализатор с:
CharStream input = CharStreams.fromFileName(inputFile);
LabeledWimsLexer lexer = new LabeledWimsLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
LabeledWimsParser parser = new LabeledWimsParser(tokens);
ParseTree tree = parser.wims(); // begin parsing at init rule
System.out.println(tree.toStringTree(parser)+"\n"); // print LISP-style tree
EvalVisitor eval = new EvalVisitor();
eval.visit(tree);
Как видите, я использую класс CharStream, чтобы разрешить символы UTF-8 в моем исходном коде. Он генерирует следующее правильно сформированное дерево LISP:
(wims (title \title { (string Un pr é bis) }) \n (language...
(каждыйUTF-8 char генерирует токен, но на данный момент это не имеет значения)
Тогда я бы хотел сделать то же самое в Javascript.Я сгенерировал Javascript Parser благодаря graddle с аргументами '-Dlanguage = JavaScript', 'LabeledWims.g4', '- o', 'static / generate-parser'
и вызвал анализатор в сценарии JSс помощью:
var lexer = new TodoLexer.LabeledWimsLexer(chars);
var tokens = new antlr4.CommonTokenStream(lexer);
console.log("Parsed: "+ tokens);
var parser = new TodoParser.LabeledWimsParser(tokens);
parser.buildParseTrees = true;
var tree = parser.wims();
var extractor = new MyWimsListener();
antlr4.tree.ParseTreeWalker.DEFAULT.walk(extractor, tree);
Но там сгенерированное дерево LISP избегает использования символа UTF-8 следующим образом:
(wims (title \title { (string Un pr bis) }) \n (language...
Как вы можете видеть, 'é' исчезает из дерева.Я пытался из браузера и текстовой области, а также скрипт node.js в терминале, результаты одинаковы.Я не могу определить источник этой проблемы.Буду благодарен за вашу помощь.
Крис