I'm writing simple language in ANTLR, and I'd like to write shell where I can put line of code, hit ENTER and have it executed, enter another line, and have it executed.
I have already written grammar which execute all alines of input at one.
Example input:
int a,b,c;
string d;
string e;
d=\"dziala\";
a=4+7;
b=a+33;
c=(b/11)*2;
grammar Kalkulator;
options {
language = Java;
output=AST;
ASTLabelType=CommonTree;
}
tokens {
NEG;
}
@header {
package lab4;
}
@lexer::header {
package lab4;
}
line
:
(assignment | declaration)* EOF
;
declaration
: type^ IDENT (','! IDENT)* ';'!
;
type
: 'int' | 'string'
;
assignment
: IDENT '='^ expression ';'!
;
term
: IDENT
| INTEGER
| STRING_LITERAL
| '('! expression ')'!
;
unary
: (( negation^ | '+'! ))* term
;
negation
: '-' -> NEG
;
mult
: unary ( ('*'^ | '/'^) unary )*
;
exp2
:mult ( ('-'^ | '+'^) mult)*
;
expression
: exp2 ('&'^ exp2)*
;
fragment LETTER : ('a'..'z'|'A'..'Z');
fragment DIGIT : '0'..'9';
INTEGER : DIGIT+;
IDENT : LETTER (LETTER | DIGIT)* ;
WS : (' ' | '\t' | '\n' | '\r' | '\f')+ {$channel=HIDDEN;};
STRING_LITERAL : '\"' .* '\"';
and:
tree grammar Evaluator;
options {
language = Java;
tokenVocab = Kalkulator;
ASTLabelType = CommonTree;
}
@header {
package lab4;
import java.util.Map;
import java.util.HashMap;
}
@members {
private Map<String, Object> zmienne = new HashMap<String, Object>();
}
line returns [Object result]
: (declaration | assignment { result = $assignment.result; })* EOF
;
declaration
: ^(type
(
IDENT
{
if("string".equals($type.result)){
zmienne.put($IDENT.text,""); //add definition
}
else{
zmienne.put($IDENT.text,0); //add definition
}
System.out.println($type.result + " " + $IDENT.text);//write output
}
)*
)
;
assignment returns [Object result]
: ^('=' IDENT e=expression)
{
if(zmienne.containsKey($IDENT.text))
{zmienne.put($IDENT.text, e);
result = e;
System.out.println(e);
}
else{
System.out.println("Blad: Niezadeklarowana zmienna");
}
}
;
type returns [Object result]
: 'int' {result="int";}| 'string' {result="string";}
;
expression returns [Object result]
: ^('+' op1=expression op2=expression) { result = (Integer)op1 + (Integer)op2; }
| ^('-' op1=expression op2=expression) { result = (Integer)op1 - (Integer)op2; }
| ^('*' op1=expression op2=expression) { result = (Integer)op1 * (Integer)op2; }
| ^('/' op1=expression op2=expression) { result = (Integer)op1 / (Integer)op2; }
| ^('%' op1=expression op2=expression) { result = (Integer)op1 \% (Integer)op2; }
| ^('&' op1=expression op2=expression) { result = (String)op1 + (String)op2; }
| ^(NEG e=expression) { result = -(Integer)e; }
| IDENT { result = zmienne.get($IDENT.text); }
| INTEGER { result = Integer.parseInt($INTEGER.text); }
| STRING_LITERAL { String t=$STRING_LITERAL.text; result = t.substring(1,t.length()-1); }
;
Can I make it process line-by-line or is that easier to make it all again?