2013-12-11 2 views
1

Сценарий заключается в том, что я хочу создать язык BASIC (высокого уровня), используя ANTRL4.Antlr4 Grammar/Rules - проблема с решением переменной BASIC для печати

Ниже приведен тестовый ввод - создание переменной C $ и назначение целочисленного значения. Назначение значений работает. Операция печати работает, за исключением тех случаев, когда конкатенация переменной к ней: -

 ************ TEST CASE **************** 

$ C = 15;

print "dangerdanger!"; # печатные работы

print "Количество GB left =" + $ C;

Parse Tree Inspector

Использование дерева разбора инспектор, я могу видеть задания работают нормально, но когда он попадает к идентификации переменной в строке, кажется, есть несогласованная вход «+», ожидающей STMTEND.

Я задавался вопросом, может ли кто-нибудь помочь мне здесь и посмотреть, какую настройку мне нужно внести в мои правила и грамматику, чтобы решить эту проблему.

Большое спасибо заранее.

Kevin PS. В качестве побочного вопроса я предпочел бы C $, чем $ C, но первые дни ...

********RULES************ 


VARNAME : '$'('A'..'Z')* 
     ; 

CONCAT : '+' 
     ; 
STMTEND : SEMICOLON NEWLINE* | NEWLINE+ 
     ; 
STRING : SQUOTED_STRING (CONCAT SQUOTED_STRING | CONCAT VARNAME)* 
    | DQUOTED_STRING (CONCAT DQUOTED_STRING | CONCAT VARNAME)* 
     ; 
fragment SQUOTED_STRING : '\'' (~['])* '\'' 
    ; 

fragment DQUOTED_STRING 
    : '"' (ESC_SEQ| ~('\\'|'"'))* '"' 
    ; 

fragment ESC_SEQ 
    : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') 
    | UNICODE_ESC 
    | OCTAL_ESC 
    ; 

fragment OCTAL_ESC 
    : '\\' ('0'..'3') ('0'..'7') ('0'..'7') 
    | '\\' ('0'..'7') ('0'..'7') 
    | '\\' ('0'..'7') 
    ; 

fragment HEX_DIGIT : '0x' ('0'..'9' | 'a'..'f' | 'A'..'F')+ 
    ; 

fragment UNICODE_ESC : '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT 
    ; 

SEMICOLON : ';' 
    ; 

NEWLINE : '\r'?'\n' 


************GRAMMAR************ 

print_command 
    : PRINT STRING STMTEND #printCommandLabel 
    ; 

assignment 
    : VARNAME EQUALS INTEGER STMTEND #assignInteger 
    | VARNAME EQUALS STRING STMTEND #assignString 
    ; 

ответ

1

Вы не должны пытаться создавать Concat-выражения внутри лексере: это ответственность парсера. Что-то вроде этого должно это сделать:

print_command 
: PRINT STRING STMTEND #printCommandLabel 
; 

assignment 
: VARNAME EQUALS expression STMTEND 
; 

expression 
: expression CONCAT expression 
| INTEGER 
| STRING 
| VARNAME 
; 

CONCAT 
: '+' 
; 

VARNAME 
: '$'('A'..'Z')* 
; 

STMTEND 
: SEMICOLON NEWLINE* 
| NEWLINE+ 
; 

STRING 
: SQUOTED_STRING 
| DQUOTED_STRING 
; 

fragment SQUOTED_STRING 
: '\'' (~['])* '\'' 
; 

fragment DQUOTED_STRING 
: '"' (ESC_SEQ| ~('\\'|'"'))* '"' 
; 

fragment ESC_SEQ 
: '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') 
| UNICODE_ESC 
| OCTAL_ESC 
; 

fragment OCTAL_ESC 
: '\\' ('0'..'3') ('0'..'7') ('0'..'7') 
| '\\' ('0'..'7') ('0'..'7') 
| '\\' ('0'..'7') 
; 

fragment HEX_DIGIT : '0x' ('0'..'9' | 'a'..'f' | 'A'..'F')+; 

fragment UNICODE_ESC : '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT; 

fragment SEMICOLON : ';'; 

fragment NEWLINE : '\r'?'\n'; 
+0

Блестящий! Спасибо вам большое за это. – KevinY