Может ли синтаксический анализатор вернуть исходный текст без лишних пробелов?
Да, вам нужно определить правило лексера, которое фиксирует эти пробелы, а затем skip()
их:
Space
: (' ' | '\t') {skip();}
;
, что приведет к игнорированию пробелов и символов табуляции.
PS. Я предполагаю, что вы используете Java в качестве целевого языка. skip()
может отличаться в других целях (например, Skip()
для C #). Вы также можете включить в это правило символы \r
и \n
.
EDIT
Допустим, ваш язык состоит только из пары объявлений переменных. Предполагая, что вы знакомы с основами ANTLR, следующая грамматика должна быть проста для понимания:
grammar T;
parse
: stat* EOF
;
stat
: Type Identifier '=' Int ';'
;
Type
: 'int'
| 'double'
| 'boolean'
;
Identifier
: ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*
;
Int
: '0'..'9'+
;
Space
: (' ' | '\t' | '\n' | 'r')+ {skip();}
;
И вы анализируете источник:
int x = 5 ; double y =5;boolean z = 0 ;
который вы хотели бы изменить на:
int x=5;
double y=5;
boolean z=0;
Вот способ встроить код в вашу грамматику и позволить правилам синтаксического анализа возвращать пользовательские объекты (в данном случае Strings):
grammar T;
parse returns [String str]
@init{StringBuilder buffer = new StringBuilder();}
@after{$str = buffer.toString();}
: (stat {buffer.append($stat.str).append('\n');})* EOF
;
stat returns [String str]
: Type Identifier '=' Int ';'
{$str = $Type.text + " " + $Identifier.text + "=" + $Int.text + ";";}
;
Type
: 'int'
| 'double'
| 'boolean'
;
Identifier
: ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*
;
Int
: '0'..'9'+
;
Space
: (' ' | '\t' | '\n' | 'r')+ {skip();}
;
Проверьте это следующим классом:
import org.antlr.runtime.*;
public class Main {
public static void main(String[] args) throws Exception {
String source = "int x = 5 ; double y =5;boolean z = 0 ;";
ANTLRStringStream in = new ANTLRStringStream(source);
TLexer lexer = new TLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
TParser parser = new TParser(tokens);
System.out.println("Result:\n"+parser.parse());
}
}
, который производит:
Result:
int x=5;
double y=5;
boolean z=0;