mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-22 13:29:18 +00:00
Parsing, 3 Address Code, Type Inference
This commit is contained in:
parent
7a24cc0b62
commit
a06fe6e989
@ -1,11 +1,29 @@
|
||||
// KickC grammar
|
||||
grammar KickC;
|
||||
|
||||
file :
|
||||
stmtSeq EOF
|
||||
;
|
||||
|
||||
stmtSeq
|
||||
: stmt+
|
||||
;
|
||||
|
||||
stmt
|
||||
: '{' stmtSeq '}' #stmtBlock
|
||||
| (TYPE)? NAME ('=' expr)? ';' #stmtAssignment
|
||||
| expr ';' #stmtExpr
|
||||
| 'if' '(' expr ')' stmt ( 'else' stmt )? #stmtIfElse
|
||||
| 'while' '(' expr ')' stmt #stmtWhile
|
||||
;
|
||||
|
||||
|
||||
expr
|
||||
: '(' expr ')' #exprPar
|
||||
| ('+' | '-' | 'not' | '!') expr #exprUnary
|
||||
| expr ('*' | '/' ) expr #exprBinary
|
||||
| expr ( '+' | '-') expr #exprBinary
|
||||
| expr ( '=' | '==' | '!=' | '<>' | '<' | '<=' | '=<' | '>=' | '=>' | '>' ) expr #exprBinary
|
||||
| expr ( '==' | '!=' | '<>' | '<' | '<=' | '=<' | '>=' | '=>' | '>' ) expr #exprBinary
|
||||
| expr ( 'and' | '&&' ) expr #exprBinary
|
||||
| expr ( 'or' | '||' ) expr #exprBinary
|
||||
| NAME #exprId
|
||||
@ -13,6 +31,8 @@ expr
|
||||
| STRING #exprString
|
||||
| BOOLEAN #exprBool
|
||||
;
|
||||
|
||||
TYPE: 'byte' | 'word' | 'string' | 'boolean';
|
||||
STRING : '"' ('\\"' | ~'"')* '"';
|
||||
BOOLEAN : 'true' | 'false';
|
||||
NUMBER : NUMFLOAT | NUMINT ;
|
||||
|
@ -20,38 +20,51 @@ T__18=19
|
||||
T__19=20
|
||||
T__20=21
|
||||
T__21=22
|
||||
STRING=23
|
||||
BOOLEAN=24
|
||||
NUMBER=25
|
||||
NUMFLOAT=26
|
||||
BINFLOAT=27
|
||||
DECFLOAT=28
|
||||
HEXFLOAT=29
|
||||
NUMINT=30
|
||||
BININTEGER=31
|
||||
DECINTEGER=32
|
||||
HEXINTEGER=33
|
||||
NAME=34
|
||||
WS=35
|
||||
'('=1
|
||||
')'=2
|
||||
'+'=3
|
||||
'-'=4
|
||||
'not'=5
|
||||
'!'=6
|
||||
'*'=7
|
||||
'/'=8
|
||||
'='=9
|
||||
'=='=10
|
||||
'!='=11
|
||||
'<>'=12
|
||||
'<'=13
|
||||
'<='=14
|
||||
'=<'=15
|
||||
'>='=16
|
||||
'=>'=17
|
||||
'>'=18
|
||||
'and'=19
|
||||
'&&'=20
|
||||
'or'=21
|
||||
'||'=22
|
||||
T__22=23
|
||||
T__23=24
|
||||
T__24=25
|
||||
T__25=26
|
||||
T__26=27
|
||||
T__27=28
|
||||
TYPE=29
|
||||
STRING=30
|
||||
BOOLEAN=31
|
||||
NUMBER=32
|
||||
NUMFLOAT=33
|
||||
BINFLOAT=34
|
||||
DECFLOAT=35
|
||||
HEXFLOAT=36
|
||||
NUMINT=37
|
||||
BININTEGER=38
|
||||
DECINTEGER=39
|
||||
HEXINTEGER=40
|
||||
NAME=41
|
||||
WS=42
|
||||
'{'=1
|
||||
'}'=2
|
||||
'='=3
|
||||
';'=4
|
||||
'if'=5
|
||||
'('=6
|
||||
')'=7
|
||||
'else'=8
|
||||
'while'=9
|
||||
'+'=10
|
||||
'-'=11
|
||||
'not'=12
|
||||
'!'=13
|
||||
'*'=14
|
||||
'/'=15
|
||||
'=='=16
|
||||
'!='=17
|
||||
'<>'=18
|
||||
'<'=19
|
||||
'<='=20
|
||||
'=<'=21
|
||||
'>='=22
|
||||
'=>'=23
|
||||
'>'=24
|
||||
'and'=25
|
||||
'&&'=26
|
||||
'or'=27
|
||||
'||'=28
|
||||
|
@ -11,6 +11,90 @@ import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
* of the available methods.
|
||||
*/
|
||||
public class KickCBaseListener implements KickCListener {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterFile(KickCParser.FileContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitFile(KickCParser.FileContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterStmtSeq(KickCParser.StmtSeqContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitStmtSeq(KickCParser.StmtSeqContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterStmtBlock(KickCParser.StmtBlockContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitStmtBlock(KickCParser.StmtBlockContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterStmtAssignment(KickCParser.StmtAssignmentContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitStmtAssignment(KickCParser.StmtAssignmentContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterStmtExpr(KickCParser.StmtExprContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitStmtExpr(KickCParser.StmtExprContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterStmtIfElse(KickCParser.StmtIfElseContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitStmtIfElse(KickCParser.StmtIfElseContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterStmtWhile(KickCParser.StmtWhileContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitStmtWhile(KickCParser.StmtWhileContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
|
@ -11,6 +11,55 @@ import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
|
||||
* operations with no return type.
|
||||
*/
|
||||
public class KickCBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements KickCVisitor<T> {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitFile(KickCParser.FileContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitStmtSeq(KickCParser.StmtSeqContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitStmtBlock(KickCParser.StmtBlockContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitStmtAssignment(KickCParser.StmtAssignmentContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitStmtExpr(KickCParser.StmtExprContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitStmtIfElse(KickCParser.StmtIfElseContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitStmtWhile(KickCParser.StmtWhileContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
|
@ -19,9 +19,10 @@ public class KickCLexer extends Lexer {
|
||||
public static final int
|
||||
T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9,
|
||||
T__9=10, T__10=11, T__11=12, T__12=13, T__13=14, T__14=15, T__15=16, T__16=17,
|
||||
T__17=18, T__18=19, T__19=20, T__20=21, T__21=22, STRING=23, BOOLEAN=24,
|
||||
NUMBER=25, NUMFLOAT=26, BINFLOAT=27, DECFLOAT=28, HEXFLOAT=29, NUMINT=30,
|
||||
BININTEGER=31, DECINTEGER=32, HEXINTEGER=33, NAME=34, WS=35;
|
||||
T__17=18, T__18=19, T__19=20, T__20=21, T__21=22, T__22=23, T__23=24,
|
||||
T__24=25, T__25=26, T__26=27, T__27=28, TYPE=29, STRING=30, BOOLEAN=31,
|
||||
NUMBER=32, NUMFLOAT=33, BINFLOAT=34, DECFLOAT=35, HEXFLOAT=36, NUMINT=37,
|
||||
BININTEGER=38, DECINTEGER=39, HEXINTEGER=40, NAME=41, WS=42;
|
||||
public static String[] channelNames = {
|
||||
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
|
||||
};
|
||||
@ -33,22 +34,24 @@ public class KickCLexer extends Lexer {
|
||||
public static final String[] ruleNames = {
|
||||
"T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8",
|
||||
"T__9", "T__10", "T__11", "T__12", "T__13", "T__14", "T__15", "T__16",
|
||||
"T__17", "T__18", "T__19", "T__20", "T__21", "STRING", "BOOLEAN", "NUMBER",
|
||||
"NUMFLOAT", "BINFLOAT", "DECFLOAT", "HEXFLOAT", "NUMINT", "BININTEGER",
|
||||
"DECINTEGER", "HEXINTEGER", "BINDIGIT", "DECDIGIT", "HEXDIGIT", "NAME",
|
||||
"NAME_START", "NAME_CHAR", "WS"
|
||||
"T__17", "T__18", "T__19", "T__20", "T__21", "T__22", "T__23", "T__24",
|
||||
"T__25", "T__26", "T__27", "TYPE", "STRING", "BOOLEAN", "NUMBER", "NUMFLOAT",
|
||||
"BINFLOAT", "DECFLOAT", "HEXFLOAT", "NUMINT", "BININTEGER", "DECINTEGER",
|
||||
"HEXINTEGER", "BINDIGIT", "DECDIGIT", "HEXDIGIT", "NAME", "NAME_START",
|
||||
"NAME_CHAR", "WS"
|
||||
};
|
||||
|
||||
private static final String[] _LITERAL_NAMES = {
|
||||
null, "'('", "')'", "'+'", "'-'", "'not'", "'!'", "'*'", "'/'", "'='",
|
||||
"'=='", "'!='", "'<>'", "'<'", "'<='", "'=<'", "'>='", "'=>'", "'>'",
|
||||
"'and'", "'&&'", "'or'", "'||'"
|
||||
null, "'{'", "'}'", "'='", "';'", "'if'", "'('", "')'", "'else'", "'while'",
|
||||
"'+'", "'-'", "'not'", "'!'", "'*'", "'/'", "'=='", "'!='", "'<>'", "'<'",
|
||||
"'<='", "'=<'", "'>='", "'=>'", "'>'", "'and'", "'&&'", "'or'", "'||'"
|
||||
};
|
||||
private static final String[] _SYMBOLIC_NAMES = {
|
||||
null, null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null, null, "STRING",
|
||||
"BOOLEAN", "NUMBER", "NUMFLOAT", "BINFLOAT", "DECFLOAT", "HEXFLOAT", "NUMINT",
|
||||
"BININTEGER", "DECINTEGER", "HEXINTEGER", "NAME", "WS"
|
||||
null, null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, "TYPE", "STRING", "BOOLEAN", "NUMBER", "NUMFLOAT",
|
||||
"BINFLOAT", "DECFLOAT", "HEXFLOAT", "NUMINT", "BININTEGER", "DECINTEGER",
|
||||
"HEXINTEGER", "NAME", "WS"
|
||||
};
|
||||
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
|
||||
|
||||
@ -108,103 +111,122 @@ public class KickCLexer extends Lexer {
|
||||
public ATN getATN() { return _ATN; }
|
||||
|
||||
public static final String _serializedATN =
|
||||
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2%\u011b\b\1\4\2\t"+
|
||||
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2,\u0154\b\1\4\2\t"+
|
||||
"\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+
|
||||
"\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
|
||||
"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
|
||||
"\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+
|
||||
"\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\3\2\3\2\3\3\3"+
|
||||
"\3\3\4\3\4\3\5\3\5\3\6\3\6\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n\3\13"+
|
||||
"\3\13\3\13\3\f\3\f\3\f\3\r\3\r\3\r\3\16\3\16\3\17\3\17\3\17\3\20\3\20"+
|
||||
"\3\20\3\21\3\21\3\21\3\22\3\22\3\22\3\23\3\23\3\24\3\24\3\24\3\24\3\25"+
|
||||
"\3\25\3\25\3\26\3\26\3\26\3\27\3\27\3\27\3\30\3\30\3\30\3\30\7\30\u0092"+
|
||||
"\n\30\f\30\16\30\u0095\13\30\3\30\3\30\3\31\3\31\3\31\3\31\3\31\3\31\3"+
|
||||
"\31\3\31\3\31\5\31\u00a2\n\31\3\32\3\32\5\32\u00a6\n\32\3\33\3\33\3\33"+
|
||||
"\5\33\u00ab\n\33\3\34\3\34\3\34\3\34\3\34\5\34\u00b2\n\34\3\34\7\34\u00b5"+
|
||||
"\n\34\f\34\16\34\u00b8\13\34\3\34\3\34\6\34\u00bc\n\34\r\34\16\34\u00bd"+
|
||||
"\3\35\7\35\u00c1\n\35\f\35\16\35\u00c4\13\35\3\35\3\35\6\35\u00c8\n\35"+
|
||||
"\r\35\16\35\u00c9\3\36\3\36\3\36\3\36\3\36\5\36\u00d1\n\36\3\36\7\36\u00d4"+
|
||||
"\n\36\f\36\16\36\u00d7\13\36\3\36\3\36\6\36\u00db\n\36\r\36\16\36\u00dc"+
|
||||
"\3\37\3\37\3\37\5\37\u00e2\n\37\3 \3 \3 \6 \u00e7\n \r \16 \u00e8\3 \3"+
|
||||
" \6 \u00ed\n \r \16 \u00ee\5 \u00f1\n \3!\6!\u00f4\n!\r!\16!\u00f5\3\""+
|
||||
"\3\"\3\"\3\"\3\"\5\"\u00fd\n\"\3\"\6\"\u0100\n\"\r\"\16\"\u0101\3#\3#"+
|
||||
"\3$\3$\3%\3%\3&\3&\7&\u010c\n&\f&\16&\u010f\13&\3\'\3\'\3(\3(\3)\6)\u0116"+
|
||||
"\n)\r)\16)\u0117\3)\3)\2\2*\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25"+
|
||||
"\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4"+
|
||||
",\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3"+
|
||||
"\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3\n\3\13"+
|
||||
"\3\13\3\f\3\f\3\r\3\r\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20\3\21\3\21"+
|
||||
"\3\21\3\22\3\22\3\22\3\23\3\23\3\23\3\24\3\24\3\25\3\25\3\25\3\26\3\26"+
|
||||
"\3\26\3\27\3\27\3\27\3\30\3\30\3\30\3\31\3\31\3\32\3\32\3\32\3\32\3\33"+
|
||||
"\3\33\3\33\3\34\3\34\3\34\3\35\3\35\3\35\3\36\3\36\3\36\3\36\3\36\3\36"+
|
||||
"\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36"+
|
||||
"\3\36\5\36\u00c5\n\36\3\37\3\37\3\37\3\37\7\37\u00cb\n\37\f\37\16\37\u00ce"+
|
||||
"\13\37\3\37\3\37\3 \3 \3 \3 \3 \3 \3 \3 \3 \5 \u00db\n \3!\3!\5!\u00df"+
|
||||
"\n!\3\"\3\"\3\"\5\"\u00e4\n\"\3#\3#\3#\3#\3#\5#\u00eb\n#\3#\7#\u00ee\n"+
|
||||
"#\f#\16#\u00f1\13#\3#\3#\6#\u00f5\n#\r#\16#\u00f6\3$\7$\u00fa\n$\f$\16"+
|
||||
"$\u00fd\13$\3$\3$\6$\u0101\n$\r$\16$\u0102\3%\3%\3%\3%\3%\5%\u010a\n%"+
|
||||
"\3%\7%\u010d\n%\f%\16%\u0110\13%\3%\3%\6%\u0114\n%\r%\16%\u0115\3&\3&"+
|
||||
"\3&\5&\u011b\n&\3\'\3\'\3\'\6\'\u0120\n\'\r\'\16\'\u0121\3\'\3\'\6\'\u0126"+
|
||||
"\n\'\r\'\16\'\u0127\5\'\u012a\n\'\3(\6(\u012d\n(\r(\16(\u012e\3)\3)\3"+
|
||||
")\3)\3)\5)\u0136\n)\3)\6)\u0139\n)\r)\16)\u013a\3*\3*\3+\3+\3,\3,\3-\3"+
|
||||
"-\7-\u0145\n-\f-\16-\u0148\13-\3.\3.\3/\3/\3\60\6\60\u014f\n\60\r\60\16"+
|
||||
"\60\u0150\3\60\3\60\2\2\61\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25"+
|
||||
"\f\27\r\31\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32"+
|
||||
"\63\33\65\34\67\359\36;\37= ?!A\"C#E\2G\2I\2K$M\2O\2Q%\3\2\n\3\2$$\4\2"+
|
||||
"DDdd\3\2\62\63\3\2\62;\5\2\62;CHch\5\2C\\aac|\6\2\62;C\\aac|\5\2\13\f"+
|
||||
"\17\17\"\"\2\u0130\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13"+
|
||||
"\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2"+
|
||||
"\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2"+
|
||||
"!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3"+
|
||||
"\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2"+
|
||||
"\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2K"+
|
||||
"\3\2\2\2\2Q\3\2\2\2\3S\3\2\2\2\5U\3\2\2\2\7W\3\2\2\2\tY\3\2\2\2\13[\3"+
|
||||
"\2\2\2\r_\3\2\2\2\17a\3\2\2\2\21c\3\2\2\2\23e\3\2\2\2\25g\3\2\2\2\27j"+
|
||||
"\3\2\2\2\31m\3\2\2\2\33p\3\2\2\2\35r\3\2\2\2\37u\3\2\2\2!x\3\2\2\2#{\3"+
|
||||
"\2\2\2%~\3\2\2\2\'\u0080\3\2\2\2)\u0084\3\2\2\2+\u0087\3\2\2\2-\u008a"+
|
||||
"\3\2\2\2/\u008d\3\2\2\2\61\u00a1\3\2\2\2\63\u00a5\3\2\2\2\65\u00aa\3\2"+
|
||||
"\2\2\67\u00b1\3\2\2\29\u00c2\3\2\2\2;\u00d0\3\2\2\2=\u00e1\3\2\2\2?\u00f0"+
|
||||
"\3\2\2\2A\u00f3\3\2\2\2C\u00fc\3\2\2\2E\u0103\3\2\2\2G\u0105\3\2\2\2I"+
|
||||
"\u0107\3\2\2\2K\u0109\3\2\2\2M\u0110\3\2\2\2O\u0112\3\2\2\2Q\u0115\3\2"+
|
||||
"\2\2ST\7*\2\2T\4\3\2\2\2UV\7+\2\2V\6\3\2\2\2WX\7-\2\2X\b\3\2\2\2YZ\7/"+
|
||||
"\2\2Z\n\3\2\2\2[\\\7p\2\2\\]\7q\2\2]^\7v\2\2^\f\3\2\2\2_`\7#\2\2`\16\3"+
|
||||
"\2\2\2ab\7,\2\2b\20\3\2\2\2cd\7\61\2\2d\22\3\2\2\2ef\7?\2\2f\24\3\2\2"+
|
||||
"\2gh\7?\2\2hi\7?\2\2i\26\3\2\2\2jk\7#\2\2kl\7?\2\2l\30\3\2\2\2mn\7>\2"+
|
||||
"\2no\7@\2\2o\32\3\2\2\2pq\7>\2\2q\34\3\2\2\2rs\7>\2\2st\7?\2\2t\36\3\2"+
|
||||
"\2\2uv\7?\2\2vw\7>\2\2w \3\2\2\2xy\7@\2\2yz\7?\2\2z\"\3\2\2\2{|\7?\2\2"+
|
||||
"|}\7@\2\2}$\3\2\2\2~\177\7@\2\2\177&\3\2\2\2\u0080\u0081\7c\2\2\u0081"+
|
||||
"\u0082\7p\2\2\u0082\u0083\7f\2\2\u0083(\3\2\2\2\u0084\u0085\7(\2\2\u0085"+
|
||||
"\u0086\7(\2\2\u0086*\3\2\2\2\u0087\u0088\7q\2\2\u0088\u0089\7t\2\2\u0089"+
|
||||
",\3\2\2\2\u008a\u008b\7~\2\2\u008b\u008c\7~\2\2\u008c.\3\2\2\2\u008d\u0093"+
|
||||
"\7$\2\2\u008e\u008f\7^\2\2\u008f\u0092\7$\2\2\u0090\u0092\n\2\2\2\u0091"+
|
||||
"\u008e\3\2\2\2\u0091\u0090\3\2\2\2\u0092\u0095\3\2\2\2\u0093\u0091\3\2"+
|
||||
"\2\2\u0093\u0094\3\2\2\2\u0094\u0096\3\2\2\2\u0095\u0093\3\2\2\2\u0096"+
|
||||
"\u0097\7$\2\2\u0097\60\3\2\2\2\u0098\u0099\7v\2\2\u0099\u009a\7t\2\2\u009a"+
|
||||
"\u009b\7w\2\2\u009b\u00a2\7g\2\2\u009c\u009d\7h\2\2\u009d\u009e\7c\2\2"+
|
||||
"\u009e\u009f\7n\2\2\u009f\u00a0\7u\2\2\u00a0\u00a2\7g\2\2\u00a1\u0098"+
|
||||
"\3\2\2\2\u00a1\u009c\3\2\2\2\u00a2\62\3\2\2\2\u00a3\u00a6\5\65\33\2\u00a4"+
|
||||
"\u00a6\5=\37\2\u00a5\u00a3\3\2\2\2\u00a5\u00a4\3\2\2\2\u00a6\64\3\2\2"+
|
||||
"\2\u00a7\u00ab\5\67\34\2\u00a8\u00ab\59\35\2\u00a9\u00ab\5;\36\2\u00aa"+
|
||||
"\u00a7\3\2\2\2\u00aa\u00a8\3\2\2\2\u00aa\u00a9\3\2\2\2\u00ab\66\3\2\2"+
|
||||
"\2\u00ac\u00b2\7\'\2\2\u00ad\u00ae\7\62\2\2\u00ae\u00b2\7d\2\2\u00af\u00b0"+
|
||||
"\7\62\2\2\u00b0\u00b2\7D\2\2\u00b1\u00ac\3\2\2\2\u00b1\u00ad\3\2\2\2\u00b1"+
|
||||
"\u00af\3\2\2\2\u00b2\u00b6\3\2\2\2\u00b3\u00b5\5E#\2\u00b4\u00b3\3\2\2"+
|
||||
"\2\u00b5\u00b8\3\2\2\2\u00b6\u00b4\3\2\2\2\u00b6\u00b7\3\2\2\2\u00b7\u00b9"+
|
||||
"\3\2\2\2\u00b8\u00b6\3\2\2\2\u00b9\u00bb\7\60\2\2\u00ba\u00bc\5E#\2\u00bb"+
|
||||
"\u00ba\3\2\2\2\u00bc\u00bd\3\2\2\2\u00bd\u00bb\3\2\2\2\u00bd\u00be\3\2"+
|
||||
"\2\2\u00be8\3\2\2\2\u00bf\u00c1\5G$\2\u00c0\u00bf\3\2\2\2\u00c1\u00c4"+
|
||||
"\3\2\2\2\u00c2\u00c0\3\2\2\2\u00c2\u00c3\3\2\2\2\u00c3\u00c5\3\2\2\2\u00c4"+
|
||||
"\u00c2\3\2\2\2\u00c5\u00c7\7\60\2\2\u00c6\u00c8\5G$\2\u00c7\u00c6\3\2"+
|
||||
"\2\2\u00c8\u00c9\3\2\2\2\u00c9\u00c7\3\2\2\2\u00c9\u00ca\3\2\2\2\u00ca"+
|
||||
":\3\2\2\2\u00cb\u00d1\7&\2\2\u00cc\u00cd\7\62\2\2\u00cd\u00d1\7z\2\2\u00ce"+
|
||||
"\u00cf\7\62\2\2\u00cf\u00d1\7Z\2\2\u00d0\u00cb\3\2\2\2\u00d0\u00cc\3\2"+
|
||||
"\2\2\u00d0\u00ce\3\2\2\2\u00d1\u00d5\3\2\2\2\u00d2\u00d4\5I%\2\u00d3\u00d2"+
|
||||
"\3\2\2\2\u00d4\u00d7\3\2\2\2\u00d5\u00d3\3\2\2\2\u00d5\u00d6\3\2\2\2\u00d6"+
|
||||
"\u00d8\3\2\2\2\u00d7\u00d5\3\2\2\2\u00d8\u00da\7\60\2\2\u00d9\u00db\5"+
|
||||
"I%\2\u00da\u00d9\3\2\2\2\u00db\u00dc\3\2\2\2\u00dc\u00da\3\2\2\2\u00dc"+
|
||||
"\u00dd\3\2\2\2\u00dd<\3\2\2\2\u00de\u00e2\5A!\2\u00df\u00e2\5C\"\2\u00e0"+
|
||||
"\u00e2\5? \2\u00e1\u00de\3\2\2\2\u00e1\u00df\3\2\2\2\u00e1\u00e0\3\2\2"+
|
||||
"\2\u00e2>\3\2\2\2\u00e3\u00e4\7\62\2\2\u00e4\u00e6\t\3\2\2\u00e5\u00e7"+
|
||||
"\5E#\2\u00e6\u00e5\3\2\2\2\u00e7\u00e8\3\2\2\2\u00e8\u00e6\3\2\2\2\u00e8"+
|
||||
"\u00e9\3\2\2\2\u00e9\u00f1\3\2\2\2\u00ea\u00ec\7\'\2\2\u00eb\u00ed\5E"+
|
||||
"#\2\u00ec\u00eb\3\2\2\2\u00ed\u00ee\3\2\2\2\u00ee\u00ec\3\2\2\2\u00ee"+
|
||||
"\u00ef\3\2\2\2\u00ef\u00f1\3\2\2\2\u00f0\u00e3\3\2\2\2\u00f0\u00ea\3\2"+
|
||||
"\2\2\u00f1@\3\2\2\2\u00f2\u00f4\5G$\2\u00f3\u00f2\3\2\2\2\u00f4\u00f5"+
|
||||
"\3\2\2\2\u00f5\u00f3\3\2\2\2\u00f5\u00f6\3\2\2\2\u00f6B\3\2\2\2\u00f7"+
|
||||
"\u00fd\7&\2\2\u00f8\u00f9\7\62\2\2\u00f9\u00fd\7z\2\2\u00fa\u00fb\7\62"+
|
||||
"\2\2\u00fb\u00fd\7Z\2\2\u00fc\u00f7\3\2\2\2\u00fc\u00f8\3\2\2\2\u00fc"+
|
||||
"\u00fa\3\2\2\2\u00fd\u00ff\3\2\2\2\u00fe\u0100\5I%\2\u00ff\u00fe\3\2\2"+
|
||||
"\2\u0100\u0101\3\2\2\2\u0101\u00ff\3\2\2\2\u0101\u0102\3\2\2\2\u0102D"+
|
||||
"\3\2\2\2\u0103\u0104\t\4\2\2\u0104F\3\2\2\2\u0105\u0106\t\5\2\2\u0106"+
|
||||
"H\3\2\2\2\u0107\u0108\t\6\2\2\u0108J\3\2\2\2\u0109\u010d\5M\'\2\u010a"+
|
||||
"\u010c\5O(\2\u010b\u010a\3\2\2\2\u010c\u010f\3\2\2\2\u010d\u010b\3\2\2"+
|
||||
"\2\u010d\u010e\3\2\2\2\u010eL\3\2\2\2\u010f\u010d\3\2\2\2\u0110\u0111"+
|
||||
"\t\7\2\2\u0111N\3\2\2\2\u0112\u0113\t\b\2\2\u0113P\3\2\2\2\u0114\u0116"+
|
||||
"\t\t\2\2\u0115\u0114\3\2\2\2\u0116\u0117\3\2\2\2\u0117\u0115\3\2\2\2\u0117"+
|
||||
"\u0118\3\2\2\2\u0118\u0119\3\2\2\2\u0119\u011a\b)\2\2\u011aR\3\2\2\2\31"+
|
||||
"\2\u0091\u0093\u00a1\u00a5\u00aa\u00b1\u00b6\u00bd\u00c2\u00c9\u00d0\u00d5"+
|
||||
"\u00dc\u00e1\u00e8\u00ee\u00f0\u00f5\u00fc\u0101\u010d\u0117\3\b\2\2";
|
||||
"\63\33\65\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S\2U\2W\2Y+[\2]\2_,"+
|
||||
"\3\2\n\3\2$$\4\2DDdd\3\2\62\63\3\2\62;\5\2\62;CHch\5\2C\\aac|\6\2\62;"+
|
||||
"C\\aac|\5\2\13\f\17\17\"\"\2\u016c\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2"+
|
||||
"\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3"+
|
||||
"\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2"+
|
||||
"\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2"+
|
||||
"\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2"+
|
||||
"\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2"+
|
||||
"\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2"+
|
||||
"O\3\2\2\2\2Q\3\2\2\2\2Y\3\2\2\2\2_\3\2\2\2\3a\3\2\2\2\5c\3\2\2\2\7e\3"+
|
||||
"\2\2\2\tg\3\2\2\2\13i\3\2\2\2\rl\3\2\2\2\17n\3\2\2\2\21p\3\2\2\2\23u\3"+
|
||||
"\2\2\2\25{\3\2\2\2\27}\3\2\2\2\31\177\3\2\2\2\33\u0083\3\2\2\2\35\u0085"+
|
||||
"\3\2\2\2\37\u0087\3\2\2\2!\u0089\3\2\2\2#\u008c\3\2\2\2%\u008f\3\2\2\2"+
|
||||
"\'\u0092\3\2\2\2)\u0094\3\2\2\2+\u0097\3\2\2\2-\u009a\3\2\2\2/\u009d\3"+
|
||||
"\2\2\2\61\u00a0\3\2\2\2\63\u00a2\3\2\2\2\65\u00a6\3\2\2\2\67\u00a9\3\2"+
|
||||
"\2\29\u00ac\3\2\2\2;\u00c4\3\2\2\2=\u00c6\3\2\2\2?\u00da\3\2\2\2A\u00de"+
|
||||
"\3\2\2\2C\u00e3\3\2\2\2E\u00ea\3\2\2\2G\u00fb\3\2\2\2I\u0109\3\2\2\2K"+
|
||||
"\u011a\3\2\2\2M\u0129\3\2\2\2O\u012c\3\2\2\2Q\u0135\3\2\2\2S\u013c\3\2"+
|
||||
"\2\2U\u013e\3\2\2\2W\u0140\3\2\2\2Y\u0142\3\2\2\2[\u0149\3\2\2\2]\u014b"+
|
||||
"\3\2\2\2_\u014e\3\2\2\2ab\7}\2\2b\4\3\2\2\2cd\7\177\2\2d\6\3\2\2\2ef\7"+
|
||||
"?\2\2f\b\3\2\2\2gh\7=\2\2h\n\3\2\2\2ij\7k\2\2jk\7h\2\2k\f\3\2\2\2lm\7"+
|
||||
"*\2\2m\16\3\2\2\2no\7+\2\2o\20\3\2\2\2pq\7g\2\2qr\7n\2\2rs\7u\2\2st\7"+
|
||||
"g\2\2t\22\3\2\2\2uv\7y\2\2vw\7j\2\2wx\7k\2\2xy\7n\2\2yz\7g\2\2z\24\3\2"+
|
||||
"\2\2{|\7-\2\2|\26\3\2\2\2}~\7/\2\2~\30\3\2\2\2\177\u0080\7p\2\2\u0080"+
|
||||
"\u0081\7q\2\2\u0081\u0082\7v\2\2\u0082\32\3\2\2\2\u0083\u0084\7#\2\2\u0084"+
|
||||
"\34\3\2\2\2\u0085\u0086\7,\2\2\u0086\36\3\2\2\2\u0087\u0088\7\61\2\2\u0088"+
|
||||
" \3\2\2\2\u0089\u008a\7?\2\2\u008a\u008b\7?\2\2\u008b\"\3\2\2\2\u008c"+
|
||||
"\u008d\7#\2\2\u008d\u008e\7?\2\2\u008e$\3\2\2\2\u008f\u0090\7>\2\2\u0090"+
|
||||
"\u0091\7@\2\2\u0091&\3\2\2\2\u0092\u0093\7>\2\2\u0093(\3\2\2\2\u0094\u0095"+
|
||||
"\7>\2\2\u0095\u0096\7?\2\2\u0096*\3\2\2\2\u0097\u0098\7?\2\2\u0098\u0099"+
|
||||
"\7>\2\2\u0099,\3\2\2\2\u009a\u009b\7@\2\2\u009b\u009c\7?\2\2\u009c.\3"+
|
||||
"\2\2\2\u009d\u009e\7?\2\2\u009e\u009f\7@\2\2\u009f\60\3\2\2\2\u00a0\u00a1"+
|
||||
"\7@\2\2\u00a1\62\3\2\2\2\u00a2\u00a3\7c\2\2\u00a3\u00a4\7p\2\2\u00a4\u00a5"+
|
||||
"\7f\2\2\u00a5\64\3\2\2\2\u00a6\u00a7\7(\2\2\u00a7\u00a8\7(\2\2\u00a8\66"+
|
||||
"\3\2\2\2\u00a9\u00aa\7q\2\2\u00aa\u00ab\7t\2\2\u00ab8\3\2\2\2\u00ac\u00ad"+
|
||||
"\7~\2\2\u00ad\u00ae\7~\2\2\u00ae:\3\2\2\2\u00af\u00b0\7d\2\2\u00b0\u00b1"+
|
||||
"\7{\2\2\u00b1\u00b2\7v\2\2\u00b2\u00c5\7g\2\2\u00b3\u00b4\7y\2\2\u00b4"+
|
||||
"\u00b5\7q\2\2\u00b5\u00b6\7t\2\2\u00b6\u00c5\7f\2\2\u00b7\u00b8\7u\2\2"+
|
||||
"\u00b8\u00b9\7v\2\2\u00b9\u00ba\7t\2\2\u00ba\u00bb\7k\2\2\u00bb\u00bc"+
|
||||
"\7p\2\2\u00bc\u00c5\7i\2\2\u00bd\u00be\7d\2\2\u00be\u00bf\7q\2\2\u00bf"+
|
||||
"\u00c0\7q\2\2\u00c0\u00c1\7n\2\2\u00c1\u00c2\7g\2\2\u00c2\u00c3\7c\2\2"+
|
||||
"\u00c3\u00c5\7p\2\2\u00c4\u00af\3\2\2\2\u00c4\u00b3\3\2\2\2\u00c4\u00b7"+
|
||||
"\3\2\2\2\u00c4\u00bd\3\2\2\2\u00c5<\3\2\2\2\u00c6\u00cc\7$\2\2\u00c7\u00c8"+
|
||||
"\7^\2\2\u00c8\u00cb\7$\2\2\u00c9\u00cb\n\2\2\2\u00ca\u00c7\3\2\2\2\u00ca"+
|
||||
"\u00c9\3\2\2\2\u00cb\u00ce\3\2\2\2\u00cc\u00ca\3\2\2\2\u00cc\u00cd\3\2"+
|
||||
"\2\2\u00cd\u00cf\3\2\2\2\u00ce\u00cc\3\2\2\2\u00cf\u00d0\7$\2\2\u00d0"+
|
||||
">\3\2\2\2\u00d1\u00d2\7v\2\2\u00d2\u00d3\7t\2\2\u00d3\u00d4\7w\2\2\u00d4"+
|
||||
"\u00db\7g\2\2\u00d5\u00d6\7h\2\2\u00d6\u00d7\7c\2\2\u00d7\u00d8\7n\2\2"+
|
||||
"\u00d8\u00d9\7u\2\2\u00d9\u00db\7g\2\2\u00da\u00d1\3\2\2\2\u00da\u00d5"+
|
||||
"\3\2\2\2\u00db@\3\2\2\2\u00dc\u00df\5C\"\2\u00dd\u00df\5K&\2\u00de\u00dc"+
|
||||
"\3\2\2\2\u00de\u00dd\3\2\2\2\u00dfB\3\2\2\2\u00e0\u00e4\5E#\2\u00e1\u00e4"+
|
||||
"\5G$\2\u00e2\u00e4\5I%\2\u00e3\u00e0\3\2\2\2\u00e3\u00e1\3\2\2\2\u00e3"+
|
||||
"\u00e2\3\2\2\2\u00e4D\3\2\2\2\u00e5\u00eb\7\'\2\2\u00e6\u00e7\7\62\2\2"+
|
||||
"\u00e7\u00eb\7d\2\2\u00e8\u00e9\7\62\2\2\u00e9\u00eb\7D\2\2\u00ea\u00e5"+
|
||||
"\3\2\2\2\u00ea\u00e6\3\2\2\2\u00ea\u00e8\3\2\2\2\u00eb\u00ef\3\2\2\2\u00ec"+
|
||||
"\u00ee\5S*\2\u00ed\u00ec\3\2\2\2\u00ee\u00f1\3\2\2\2\u00ef\u00ed\3\2\2"+
|
||||
"\2\u00ef\u00f0\3\2\2\2\u00f0\u00f2\3\2\2\2\u00f1\u00ef\3\2\2\2\u00f2\u00f4"+
|
||||
"\7\60\2\2\u00f3\u00f5\5S*\2\u00f4\u00f3\3\2\2\2\u00f5\u00f6\3\2\2\2\u00f6"+
|
||||
"\u00f4\3\2\2\2\u00f6\u00f7\3\2\2\2\u00f7F\3\2\2\2\u00f8\u00fa\5U+\2\u00f9"+
|
||||
"\u00f8\3\2\2\2\u00fa\u00fd\3\2\2\2\u00fb\u00f9\3\2\2\2\u00fb\u00fc\3\2"+
|
||||
"\2\2\u00fc\u00fe\3\2\2\2\u00fd\u00fb\3\2\2\2\u00fe\u0100\7\60\2\2\u00ff"+
|
||||
"\u0101\5U+\2\u0100\u00ff\3\2\2\2\u0101\u0102\3\2\2\2\u0102\u0100\3\2\2"+
|
||||
"\2\u0102\u0103\3\2\2\2\u0103H\3\2\2\2\u0104\u010a\7&\2\2\u0105\u0106\7"+
|
||||
"\62\2\2\u0106\u010a\7z\2\2\u0107\u0108\7\62\2\2\u0108\u010a\7Z\2\2\u0109"+
|
||||
"\u0104\3\2\2\2\u0109\u0105\3\2\2\2\u0109\u0107\3\2\2\2\u010a\u010e\3\2"+
|
||||
"\2\2\u010b\u010d\5W,\2\u010c\u010b\3\2\2\2\u010d\u0110\3\2\2\2\u010e\u010c"+
|
||||
"\3\2\2\2\u010e\u010f\3\2\2\2\u010f\u0111\3\2\2\2\u0110\u010e\3\2\2\2\u0111"+
|
||||
"\u0113\7\60\2\2\u0112\u0114\5W,\2\u0113\u0112\3\2\2\2\u0114\u0115\3\2"+
|
||||
"\2\2\u0115\u0113\3\2\2\2\u0115\u0116\3\2\2\2\u0116J\3\2\2\2\u0117\u011b"+
|
||||
"\5O(\2\u0118\u011b\5Q)\2\u0119\u011b\5M\'\2\u011a\u0117\3\2\2\2\u011a"+
|
||||
"\u0118\3\2\2\2\u011a\u0119\3\2\2\2\u011bL\3\2\2\2\u011c\u011d\7\62\2\2"+
|
||||
"\u011d\u011f\t\3\2\2\u011e\u0120\5S*\2\u011f\u011e\3\2\2\2\u0120\u0121"+
|
||||
"\3\2\2\2\u0121\u011f\3\2\2\2\u0121\u0122\3\2\2\2\u0122\u012a\3\2\2\2\u0123"+
|
||||
"\u0125\7\'\2\2\u0124\u0126\5S*\2\u0125\u0124\3\2\2\2\u0126\u0127\3\2\2"+
|
||||
"\2\u0127\u0125\3\2\2\2\u0127\u0128\3\2\2\2\u0128\u012a\3\2\2\2\u0129\u011c"+
|
||||
"\3\2\2\2\u0129\u0123\3\2\2\2\u012aN\3\2\2\2\u012b\u012d\5U+\2\u012c\u012b"+
|
||||
"\3\2\2\2\u012d\u012e\3\2\2\2\u012e\u012c\3\2\2\2\u012e\u012f\3\2\2\2\u012f"+
|
||||
"P\3\2\2\2\u0130\u0136\7&\2\2\u0131\u0132\7\62\2\2\u0132\u0136\7z\2\2\u0133"+
|
||||
"\u0134\7\62\2\2\u0134\u0136\7Z\2\2\u0135\u0130\3\2\2\2\u0135\u0131\3\2"+
|
||||
"\2\2\u0135\u0133\3\2\2\2\u0136\u0138\3\2\2\2\u0137\u0139\5W,\2\u0138\u0137"+
|
||||
"\3\2\2\2\u0139\u013a\3\2\2\2\u013a\u0138\3\2\2\2\u013a\u013b\3\2\2\2\u013b"+
|
||||
"R\3\2\2\2\u013c\u013d\t\4\2\2\u013dT\3\2\2\2\u013e\u013f\t\5\2\2\u013f"+
|
||||
"V\3\2\2\2\u0140\u0141\t\6\2\2\u0141X\3\2\2\2\u0142\u0146\5[.\2\u0143\u0145"+
|
||||
"\5]/\2\u0144\u0143\3\2\2\2\u0145\u0148\3\2\2\2\u0146\u0144\3\2\2\2\u0146"+
|
||||
"\u0147\3\2\2\2\u0147Z\3\2\2\2\u0148\u0146\3\2\2\2\u0149\u014a\t\7\2\2"+
|
||||
"\u014a\\\3\2\2\2\u014b\u014c\t\b\2\2\u014c^\3\2\2\2\u014d\u014f\t\t\2"+
|
||||
"\2\u014e\u014d\3\2\2\2\u014f\u0150\3\2\2\2\u0150\u014e\3\2\2\2\u0150\u0151"+
|
||||
"\3\2\2\2\u0151\u0152\3\2\2\2\u0152\u0153\b\60\2\2\u0153`\3\2\2\2\32\2"+
|
||||
"\u00c4\u00ca\u00cc\u00da\u00de\u00e3\u00ea\u00ef\u00f6\u00fb\u0102\u0109"+
|
||||
"\u010e\u0115\u011a\u0121\u0127\u0129\u012e\u0135\u013a\u0146\u0150\3\b"+
|
||||
"\2\2";
|
||||
public static final ATN _ATN =
|
||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||
static {
|
||||
|
@ -20,38 +20,51 @@ T__18=19
|
||||
T__19=20
|
||||
T__20=21
|
||||
T__21=22
|
||||
STRING=23
|
||||
BOOLEAN=24
|
||||
NUMBER=25
|
||||
NUMFLOAT=26
|
||||
BINFLOAT=27
|
||||
DECFLOAT=28
|
||||
HEXFLOAT=29
|
||||
NUMINT=30
|
||||
BININTEGER=31
|
||||
DECINTEGER=32
|
||||
HEXINTEGER=33
|
||||
NAME=34
|
||||
WS=35
|
||||
'('=1
|
||||
')'=2
|
||||
'+'=3
|
||||
'-'=4
|
||||
'not'=5
|
||||
'!'=6
|
||||
'*'=7
|
||||
'/'=8
|
||||
'='=9
|
||||
'=='=10
|
||||
'!='=11
|
||||
'<>'=12
|
||||
'<'=13
|
||||
'<='=14
|
||||
'=<'=15
|
||||
'>='=16
|
||||
'=>'=17
|
||||
'>'=18
|
||||
'and'=19
|
||||
'&&'=20
|
||||
'or'=21
|
||||
'||'=22
|
||||
T__22=23
|
||||
T__23=24
|
||||
T__24=25
|
||||
T__25=26
|
||||
T__26=27
|
||||
T__27=28
|
||||
TYPE=29
|
||||
STRING=30
|
||||
BOOLEAN=31
|
||||
NUMBER=32
|
||||
NUMFLOAT=33
|
||||
BINFLOAT=34
|
||||
DECFLOAT=35
|
||||
HEXFLOAT=36
|
||||
NUMINT=37
|
||||
BININTEGER=38
|
||||
DECINTEGER=39
|
||||
HEXINTEGER=40
|
||||
NAME=41
|
||||
WS=42
|
||||
'{'=1
|
||||
'}'=2
|
||||
'='=3
|
||||
';'=4
|
||||
'if'=5
|
||||
'('=6
|
||||
')'=7
|
||||
'else'=8
|
||||
'while'=9
|
||||
'+'=10
|
||||
'-'=11
|
||||
'not'=12
|
||||
'!'=13
|
||||
'*'=14
|
||||
'/'=15
|
||||
'=='=16
|
||||
'!='=17
|
||||
'<>'=18
|
||||
'<'=19
|
||||
'<='=20
|
||||
'=<'=21
|
||||
'>='=22
|
||||
'=>'=23
|
||||
'>'=24
|
||||
'and'=25
|
||||
'&&'=26
|
||||
'or'=27
|
||||
'||'=28
|
||||
|
@ -7,6 +7,86 @@ import org.antlr.v4.runtime.tree.ParseTreeListener;
|
||||
* {@link KickCParser}.
|
||||
*/
|
||||
public interface KickCListener extends ParseTreeListener {
|
||||
/**
|
||||
* Enter a parse tree produced by {@link KickCParser#file}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterFile(KickCParser.FileContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link KickCParser#file}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitFile(KickCParser.FileContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link KickCParser#stmtSeq}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterStmtSeq(KickCParser.StmtSeqContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link KickCParser#stmtSeq}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitStmtSeq(KickCParser.StmtSeqContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code stmtBlock}
|
||||
* labeled alternative in {@link KickCParser#stmt}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterStmtBlock(KickCParser.StmtBlockContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code stmtBlock}
|
||||
* labeled alternative in {@link KickCParser#stmt}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitStmtBlock(KickCParser.StmtBlockContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code stmtAssignment}
|
||||
* labeled alternative in {@link KickCParser#stmt}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterStmtAssignment(KickCParser.StmtAssignmentContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code stmtAssignment}
|
||||
* labeled alternative in {@link KickCParser#stmt}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitStmtAssignment(KickCParser.StmtAssignmentContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code stmtExpr}
|
||||
* labeled alternative in {@link KickCParser#stmt}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterStmtExpr(KickCParser.StmtExprContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code stmtExpr}
|
||||
* labeled alternative in {@link KickCParser#stmt}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitStmtExpr(KickCParser.StmtExprContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code stmtIfElse}
|
||||
* labeled alternative in {@link KickCParser#stmt}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterStmtIfElse(KickCParser.StmtIfElseContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code stmtIfElse}
|
||||
* labeled alternative in {@link KickCParser#stmt}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitStmtIfElse(KickCParser.StmtIfElseContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code stmtWhile}
|
||||
* labeled alternative in {@link KickCParser#stmt}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterStmtWhile(KickCParser.StmtWhileContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code stmtWhile}
|
||||
* labeled alternative in {@link KickCParser#stmt}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitStmtWhile(KickCParser.StmtWhileContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code exprBinary}
|
||||
* labeled alternative in {@link KickCParser#expr}.
|
||||
|
@ -19,25 +19,27 @@ public class KickCParser extends Parser {
|
||||
public static final int
|
||||
T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9,
|
||||
T__9=10, T__10=11, T__11=12, T__12=13, T__13=14, T__14=15, T__15=16, T__16=17,
|
||||
T__17=18, T__18=19, T__19=20, T__20=21, T__21=22, STRING=23, BOOLEAN=24,
|
||||
NUMBER=25, NUMFLOAT=26, BINFLOAT=27, DECFLOAT=28, HEXFLOAT=29, NUMINT=30,
|
||||
BININTEGER=31, DECINTEGER=32, HEXINTEGER=33, NAME=34, WS=35;
|
||||
T__17=18, T__18=19, T__19=20, T__20=21, T__21=22, T__22=23, T__23=24,
|
||||
T__24=25, T__25=26, T__26=27, T__27=28, TYPE=29, STRING=30, BOOLEAN=31,
|
||||
NUMBER=32, NUMFLOAT=33, BINFLOAT=34, DECFLOAT=35, HEXFLOAT=36, NUMINT=37,
|
||||
BININTEGER=38, DECINTEGER=39, HEXINTEGER=40, NAME=41, WS=42;
|
||||
public static final int
|
||||
RULE_expr = 0;
|
||||
RULE_file = 0, RULE_stmtSeq = 1, RULE_stmt = 2, RULE_expr = 3;
|
||||
public static final String[] ruleNames = {
|
||||
"expr"
|
||||
"file", "stmtSeq", "stmt", "expr"
|
||||
};
|
||||
|
||||
private static final String[] _LITERAL_NAMES = {
|
||||
null, "'('", "')'", "'+'", "'-'", "'not'", "'!'", "'*'", "'/'", "'='",
|
||||
"'=='", "'!='", "'<>'", "'<'", "'<='", "'=<'", "'>='", "'=>'", "'>'",
|
||||
"'and'", "'&&'", "'or'", "'||'"
|
||||
null, "'{'", "'}'", "'='", "';'", "'if'", "'('", "')'", "'else'", "'while'",
|
||||
"'+'", "'-'", "'not'", "'!'", "'*'", "'/'", "'=='", "'!='", "'<>'", "'<'",
|
||||
"'<='", "'=<'", "'>='", "'=>'", "'>'", "'and'", "'&&'", "'or'", "'||'"
|
||||
};
|
||||
private static final String[] _SYMBOLIC_NAMES = {
|
||||
null, null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null, null, "STRING",
|
||||
"BOOLEAN", "NUMBER", "NUMFLOAT", "BINFLOAT", "DECFLOAT", "HEXFLOAT", "NUMINT",
|
||||
"BININTEGER", "DECINTEGER", "HEXINTEGER", "NAME", "WS"
|
||||
null, null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, "TYPE", "STRING", "BOOLEAN", "NUMBER", "NUMFLOAT",
|
||||
"BINFLOAT", "DECFLOAT", "HEXFLOAT", "NUMINT", "BININTEGER", "DECINTEGER",
|
||||
"HEXINTEGER", "NAME", "WS"
|
||||
};
|
||||
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
|
||||
|
||||
@ -88,6 +90,350 @@ public class KickCParser extends Parser {
|
||||
super(input);
|
||||
_interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
|
||||
}
|
||||
public static class FileContext extends ParserRuleContext {
|
||||
public StmtSeqContext stmtSeq() {
|
||||
return getRuleContext(StmtSeqContext.class,0);
|
||||
}
|
||||
public TerminalNode EOF() { return getToken(KickCParser.EOF, 0); }
|
||||
public FileContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_file; }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof KickCListener ) ((KickCListener)listener).enterFile(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof KickCListener ) ((KickCListener)listener).exitFile(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof KickCVisitor ) return ((KickCVisitor<? extends T>)visitor).visitFile(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final FileContext file() throws RecognitionException {
|
||||
FileContext _localctx = new FileContext(_ctx, getState());
|
||||
enterRule(_localctx, 0, RULE_file);
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(8);
|
||||
stmtSeq();
|
||||
setState(9);
|
||||
match(EOF);
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static class StmtSeqContext extends ParserRuleContext {
|
||||
public List<StmtContext> stmt() {
|
||||
return getRuleContexts(StmtContext.class);
|
||||
}
|
||||
public StmtContext stmt(int i) {
|
||||
return getRuleContext(StmtContext.class,i);
|
||||
}
|
||||
public StmtSeqContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_stmtSeq; }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof KickCListener ) ((KickCListener)listener).enterStmtSeq(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof KickCListener ) ((KickCListener)listener).exitStmtSeq(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof KickCVisitor ) return ((KickCVisitor<? extends T>)visitor).visitStmtSeq(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final StmtSeqContext stmtSeq() throws RecognitionException {
|
||||
StmtSeqContext _localctx = new StmtSeqContext(_ctx, getState());
|
||||
enterRule(_localctx, 2, RULE_stmtSeq);
|
||||
int _la;
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(12);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
do {
|
||||
{
|
||||
{
|
||||
setState(11);
|
||||
stmt();
|
||||
}
|
||||
}
|
||||
setState(14);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
} while ( (((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << T__4) | (1L << T__5) | (1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << TYPE) | (1L << STRING) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0) );
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static class StmtContext extends ParserRuleContext {
|
||||
public StmtContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_stmt; }
|
||||
|
||||
public StmtContext() { }
|
||||
public void copyFrom(StmtContext ctx) {
|
||||
super.copyFrom(ctx);
|
||||
}
|
||||
}
|
||||
public static class StmtBlockContext extends StmtContext {
|
||||
public StmtSeqContext stmtSeq() {
|
||||
return getRuleContext(StmtSeqContext.class,0);
|
||||
}
|
||||
public StmtBlockContext(StmtContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof KickCListener ) ((KickCListener)listener).enterStmtBlock(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof KickCListener ) ((KickCListener)listener).exitStmtBlock(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof KickCVisitor ) return ((KickCVisitor<? extends T>)visitor).visitStmtBlock(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
public static class StmtExprContext extends StmtContext {
|
||||
public ExprContext expr() {
|
||||
return getRuleContext(ExprContext.class,0);
|
||||
}
|
||||
public StmtExprContext(StmtContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof KickCListener ) ((KickCListener)listener).enterStmtExpr(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof KickCListener ) ((KickCListener)listener).exitStmtExpr(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof KickCVisitor ) return ((KickCVisitor<? extends T>)visitor).visitStmtExpr(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
public static class StmtWhileContext extends StmtContext {
|
||||
public ExprContext expr() {
|
||||
return getRuleContext(ExprContext.class,0);
|
||||
}
|
||||
public StmtContext stmt() {
|
||||
return getRuleContext(StmtContext.class,0);
|
||||
}
|
||||
public StmtWhileContext(StmtContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof KickCListener ) ((KickCListener)listener).enterStmtWhile(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof KickCListener ) ((KickCListener)listener).exitStmtWhile(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof KickCVisitor ) return ((KickCVisitor<? extends T>)visitor).visitStmtWhile(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
public static class StmtAssignmentContext extends StmtContext {
|
||||
public TerminalNode NAME() { return getToken(KickCParser.NAME, 0); }
|
||||
public TerminalNode TYPE() { return getToken(KickCParser.TYPE, 0); }
|
||||
public ExprContext expr() {
|
||||
return getRuleContext(ExprContext.class,0);
|
||||
}
|
||||
public StmtAssignmentContext(StmtContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof KickCListener ) ((KickCListener)listener).enterStmtAssignment(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof KickCListener ) ((KickCListener)listener).exitStmtAssignment(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof KickCVisitor ) return ((KickCVisitor<? extends T>)visitor).visitStmtAssignment(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
public static class StmtIfElseContext extends StmtContext {
|
||||
public ExprContext expr() {
|
||||
return getRuleContext(ExprContext.class,0);
|
||||
}
|
||||
public List<StmtContext> stmt() {
|
||||
return getRuleContexts(StmtContext.class);
|
||||
}
|
||||
public StmtContext stmt(int i) {
|
||||
return getRuleContext(StmtContext.class,i);
|
||||
}
|
||||
public StmtIfElseContext(StmtContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof KickCListener ) ((KickCListener)listener).enterStmtIfElse(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof KickCListener ) ((KickCListener)listener).exitStmtIfElse(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof KickCVisitor ) return ((KickCVisitor<? extends T>)visitor).visitStmtIfElse(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final StmtContext stmt() throws RecognitionException {
|
||||
StmtContext _localctx = new StmtContext(_ctx, getState());
|
||||
enterRule(_localctx, 4, RULE_stmt);
|
||||
int _la;
|
||||
try {
|
||||
setState(47);
|
||||
_errHandler.sync(this);
|
||||
switch ( getInterpreter().adaptivePredict(_input,4,_ctx) ) {
|
||||
case 1:
|
||||
_localctx = new StmtBlockContext(_localctx);
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(16);
|
||||
match(T__0);
|
||||
setState(17);
|
||||
stmtSeq();
|
||||
setState(18);
|
||||
match(T__1);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
_localctx = new StmtAssignmentContext(_localctx);
|
||||
enterOuterAlt(_localctx, 2);
|
||||
{
|
||||
setState(21);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
if (_la==TYPE) {
|
||||
{
|
||||
setState(20);
|
||||
match(TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
setState(23);
|
||||
match(NAME);
|
||||
setState(26);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
if (_la==T__2) {
|
||||
{
|
||||
setState(24);
|
||||
match(T__2);
|
||||
setState(25);
|
||||
expr(0);
|
||||
}
|
||||
}
|
||||
|
||||
setState(28);
|
||||
match(T__3);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
_localctx = new StmtExprContext(_localctx);
|
||||
enterOuterAlt(_localctx, 3);
|
||||
{
|
||||
setState(29);
|
||||
expr(0);
|
||||
setState(30);
|
||||
match(T__3);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
_localctx = new StmtIfElseContext(_localctx);
|
||||
enterOuterAlt(_localctx, 4);
|
||||
{
|
||||
setState(32);
|
||||
match(T__4);
|
||||
setState(33);
|
||||
match(T__5);
|
||||
setState(34);
|
||||
expr(0);
|
||||
setState(35);
|
||||
match(T__6);
|
||||
setState(36);
|
||||
stmt();
|
||||
setState(39);
|
||||
_errHandler.sync(this);
|
||||
switch ( getInterpreter().adaptivePredict(_input,3,_ctx) ) {
|
||||
case 1:
|
||||
{
|
||||
setState(37);
|
||||
match(T__7);
|
||||
setState(38);
|
||||
stmt();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
_localctx = new StmtWhileContext(_localctx);
|
||||
enterOuterAlt(_localctx, 5);
|
||||
{
|
||||
setState(41);
|
||||
match(T__8);
|
||||
setState(42);
|
||||
match(T__5);
|
||||
setState(43);
|
||||
expr(0);
|
||||
setState(44);
|
||||
match(T__6);
|
||||
setState(45);
|
||||
stmt();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static class ExprContext extends ParserRuleContext {
|
||||
public ExprContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
@ -237,41 +583,41 @@ public class KickCParser extends Parser {
|
||||
int _parentState = getState();
|
||||
ExprContext _localctx = new ExprContext(_ctx, _parentState);
|
||||
ExprContext _prevctx = _localctx;
|
||||
int _startState = 0;
|
||||
enterRecursionRule(_localctx, 0, RULE_expr, _p);
|
||||
int _startState = 6;
|
||||
enterRecursionRule(_localctx, 6, RULE_expr, _p);
|
||||
int _la;
|
||||
try {
|
||||
int _alt;
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(13);
|
||||
setState(60);
|
||||
_errHandler.sync(this);
|
||||
switch (_input.LA(1)) {
|
||||
case T__0:
|
||||
case T__5:
|
||||
{
|
||||
_localctx = new ExprParContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
|
||||
setState(3);
|
||||
match(T__0);
|
||||
setState(4);
|
||||
setState(50);
|
||||
match(T__5);
|
||||
setState(51);
|
||||
expr(0);
|
||||
setState(5);
|
||||
match(T__1);
|
||||
setState(52);
|
||||
match(T__6);
|
||||
}
|
||||
break;
|
||||
case T__2:
|
||||
case T__3:
|
||||
case T__4:
|
||||
case T__5:
|
||||
case T__9:
|
||||
case T__10:
|
||||
case T__11:
|
||||
case T__12:
|
||||
{
|
||||
_localctx = new ExprUnaryContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(7);
|
||||
setState(54);
|
||||
_la = _input.LA(1);
|
||||
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__2) | (1L << T__3) | (1L << T__4) | (1L << T__5))) != 0)) ) {
|
||||
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12))) != 0)) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
}
|
||||
else {
|
||||
@ -279,7 +625,7 @@ public class KickCParser extends Parser {
|
||||
_errHandler.reportMatch(this);
|
||||
consume();
|
||||
}
|
||||
setState(8);
|
||||
setState(55);
|
||||
expr(10);
|
||||
}
|
||||
break;
|
||||
@ -288,7 +634,7 @@ public class KickCParser extends Parser {
|
||||
_localctx = new ExprIdContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(9);
|
||||
setState(56);
|
||||
match(NAME);
|
||||
}
|
||||
break;
|
||||
@ -297,7 +643,7 @@ public class KickCParser extends Parser {
|
||||
_localctx = new ExprNumberContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(10);
|
||||
setState(57);
|
||||
match(NUMBER);
|
||||
}
|
||||
break;
|
||||
@ -306,7 +652,7 @@ public class KickCParser extends Parser {
|
||||
_localctx = new ExprStringContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(11);
|
||||
setState(58);
|
||||
match(STRING);
|
||||
}
|
||||
break;
|
||||
@ -315,7 +661,7 @@ public class KickCParser extends Parser {
|
||||
_localctx = new ExprBoolContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(12);
|
||||
setState(59);
|
||||
match(BOOLEAN);
|
||||
}
|
||||
break;
|
||||
@ -323,26 +669,26 @@ public class KickCParser extends Parser {
|
||||
throw new NoViableAltException(this);
|
||||
}
|
||||
_ctx.stop = _input.LT(-1);
|
||||
setState(32);
|
||||
setState(79);
|
||||
_errHandler.sync(this);
|
||||
_alt = getInterpreter().adaptivePredict(_input,2,_ctx);
|
||||
_alt = getInterpreter().adaptivePredict(_input,7,_ctx);
|
||||
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
|
||||
if ( _alt==1 ) {
|
||||
if ( _parseListeners!=null ) triggerExitRuleEvent();
|
||||
_prevctx = _localctx;
|
||||
{
|
||||
setState(30);
|
||||
setState(77);
|
||||
_errHandler.sync(this);
|
||||
switch ( getInterpreter().adaptivePredict(_input,1,_ctx) ) {
|
||||
switch ( getInterpreter().adaptivePredict(_input,6,_ctx) ) {
|
||||
case 1:
|
||||
{
|
||||
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_expr);
|
||||
setState(15);
|
||||
setState(62);
|
||||
if (!(precpred(_ctx, 9))) throw new FailedPredicateException(this, "precpred(_ctx, 9)");
|
||||
setState(16);
|
||||
setState(63);
|
||||
_la = _input.LA(1);
|
||||
if ( !(_la==T__6 || _la==T__7) ) {
|
||||
if ( !(_la==T__13 || _la==T__14) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
}
|
||||
else {
|
||||
@ -350,7 +696,7 @@ public class KickCParser extends Parser {
|
||||
_errHandler.reportMatch(this);
|
||||
consume();
|
||||
}
|
||||
setState(17);
|
||||
setState(64);
|
||||
expr(10);
|
||||
}
|
||||
break;
|
||||
@ -358,11 +704,11 @@ public class KickCParser extends Parser {
|
||||
{
|
||||
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_expr);
|
||||
setState(18);
|
||||
setState(65);
|
||||
if (!(precpred(_ctx, 8))) throw new FailedPredicateException(this, "precpred(_ctx, 8)");
|
||||
setState(19);
|
||||
setState(66);
|
||||
_la = _input.LA(1);
|
||||
if ( !(_la==T__2 || _la==T__3) ) {
|
||||
if ( !(_la==T__9 || _la==T__10) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
}
|
||||
else {
|
||||
@ -370,7 +716,7 @@ public class KickCParser extends Parser {
|
||||
_errHandler.reportMatch(this);
|
||||
consume();
|
||||
}
|
||||
setState(20);
|
||||
setState(67);
|
||||
expr(9);
|
||||
}
|
||||
break;
|
||||
@ -378,11 +724,11 @@ public class KickCParser extends Parser {
|
||||
{
|
||||
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_expr);
|
||||
setState(21);
|
||||
setState(68);
|
||||
if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)");
|
||||
setState(22);
|
||||
setState(69);
|
||||
_la = _input.LA(1);
|
||||
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__16) | (1L << T__17))) != 0)) ) {
|
||||
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__15) | (1L << T__16) | (1L << T__17) | (1L << T__18) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23))) != 0)) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
}
|
||||
else {
|
||||
@ -390,7 +736,7 @@ public class KickCParser extends Parser {
|
||||
_errHandler.reportMatch(this);
|
||||
consume();
|
||||
}
|
||||
setState(23);
|
||||
setState(70);
|
||||
expr(8);
|
||||
}
|
||||
break;
|
||||
@ -398,11 +744,11 @@ public class KickCParser extends Parser {
|
||||
{
|
||||
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_expr);
|
||||
setState(24);
|
||||
setState(71);
|
||||
if (!(precpred(_ctx, 6))) throw new FailedPredicateException(this, "precpred(_ctx, 6)");
|
||||
setState(25);
|
||||
setState(72);
|
||||
_la = _input.LA(1);
|
||||
if ( !(_la==T__18 || _la==T__19) ) {
|
||||
if ( !(_la==T__24 || _la==T__25) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
}
|
||||
else {
|
||||
@ -410,7 +756,7 @@ public class KickCParser extends Parser {
|
||||
_errHandler.reportMatch(this);
|
||||
consume();
|
||||
}
|
||||
setState(26);
|
||||
setState(73);
|
||||
expr(7);
|
||||
}
|
||||
break;
|
||||
@ -418,11 +764,11 @@ public class KickCParser extends Parser {
|
||||
{
|
||||
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_expr);
|
||||
setState(27);
|
||||
setState(74);
|
||||
if (!(precpred(_ctx, 5))) throw new FailedPredicateException(this, "precpred(_ctx, 5)");
|
||||
setState(28);
|
||||
setState(75);
|
||||
_la = _input.LA(1);
|
||||
if ( !(_la==T__20 || _la==T__21) ) {
|
||||
if ( !(_la==T__26 || _la==T__27) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
}
|
||||
else {
|
||||
@ -430,16 +776,16 @@ public class KickCParser extends Parser {
|
||||
_errHandler.reportMatch(this);
|
||||
consume();
|
||||
}
|
||||
setState(29);
|
||||
setState(76);
|
||||
expr(6);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
setState(34);
|
||||
setState(81);
|
||||
_errHandler.sync(this);
|
||||
_alt = getInterpreter().adaptivePredict(_input,2,_ctx);
|
||||
_alt = getInterpreter().adaptivePredict(_input,7,_ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -456,7 +802,7 @@ public class KickCParser extends Parser {
|
||||
|
||||
public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) {
|
||||
switch (ruleIndex) {
|
||||
case 0:
|
||||
case 3:
|
||||
return expr_sempred((ExprContext)_localctx, predIndex);
|
||||
}
|
||||
return true;
|
||||
@ -478,19 +824,30 @@ public class KickCParser extends Parser {
|
||||
}
|
||||
|
||||
public static final String _serializedATN =
|
||||
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3%&\4\2\t\2\3\2\3\2"+
|
||||
"\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\5\2\20\n\2\3\2\3\2\3\2\3\2\3\2\3"+
|
||||
"\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\7\2!\n\2\f\2\16\2$\13\2\3\2\2\3"+
|
||||
"\2\3\2\2\b\3\2\5\b\3\2\t\n\3\2\5\6\3\2\13\24\3\2\25\26\3\2\27\30\2.\2"+
|
||||
"\17\3\2\2\2\4\5\b\2\1\2\5\6\7\3\2\2\6\7\5\2\2\2\7\b\7\4\2\2\b\20\3\2\2"+
|
||||
"\2\t\n\t\2\2\2\n\20\5\2\2\f\13\20\7$\2\2\f\20\7\33\2\2\r\20\7\31\2\2\16"+
|
||||
"\20\7\32\2\2\17\4\3\2\2\2\17\t\3\2\2\2\17\13\3\2\2\2\17\f\3\2\2\2\17\r"+
|
||||
"\3\2\2\2\17\16\3\2\2\2\20\"\3\2\2\2\21\22\f\13\2\2\22\23\t\3\2\2\23!\5"+
|
||||
"\2\2\f\24\25\f\n\2\2\25\26\t\4\2\2\26!\5\2\2\13\27\30\f\t\2\2\30\31\t"+
|
||||
"\5\2\2\31!\5\2\2\n\32\33\f\b\2\2\33\34\t\6\2\2\34!\5\2\2\t\35\36\f\7\2"+
|
||||
"\2\36\37\t\7\2\2\37!\5\2\2\b \21\3\2\2\2 \24\3\2\2\2 \27\3\2\2\2 \32\3"+
|
||||
"\2\2\2 \35\3\2\2\2!$\3\2\2\2\" \3\2\2\2\"#\3\2\2\2#\3\3\2\2\2$\"\3\2\2"+
|
||||
"\2\5\17 \"";
|
||||
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3,U\4\2\t\2\4\3\t\3"+
|
||||
"\4\4\t\4\4\5\t\5\3\2\3\2\3\2\3\3\6\3\17\n\3\r\3\16\3\20\3\4\3\4\3\4\3"+
|
||||
"\4\3\4\5\4\30\n\4\3\4\3\4\3\4\5\4\35\n\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3"+
|
||||
"\4\3\4\3\4\3\4\5\4*\n\4\3\4\3\4\3\4\3\4\3\4\3\4\5\4\62\n\4\3\5\3\5\3\5"+
|
||||
"\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\5\5?\n\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5"+
|
||||
"\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\7\5P\n\5\f\5\16\5S\13\5\3\5\2\3\b\6\2"+
|
||||
"\4\6\b\2\b\3\2\f\17\3\2\20\21\3\2\f\r\3\2\22\32\3\2\33\34\3\2\35\36\2"+
|
||||
"b\2\n\3\2\2\2\4\16\3\2\2\2\6\61\3\2\2\2\b>\3\2\2\2\n\13\5\4\3\2\13\f\7"+
|
||||
"\2\2\3\f\3\3\2\2\2\r\17\5\6\4\2\16\r\3\2\2\2\17\20\3\2\2\2\20\16\3\2\2"+
|
||||
"\2\20\21\3\2\2\2\21\5\3\2\2\2\22\23\7\3\2\2\23\24\5\4\3\2\24\25\7\4\2"+
|
||||
"\2\25\62\3\2\2\2\26\30\7\37\2\2\27\26\3\2\2\2\27\30\3\2\2\2\30\31\3\2"+
|
||||
"\2\2\31\34\7+\2\2\32\33\7\5\2\2\33\35\5\b\5\2\34\32\3\2\2\2\34\35\3\2"+
|
||||
"\2\2\35\36\3\2\2\2\36\62\7\6\2\2\37 \5\b\5\2 !\7\6\2\2!\62\3\2\2\2\"#"+
|
||||
"\7\7\2\2#$\7\b\2\2$%\5\b\5\2%&\7\t\2\2&)\5\6\4\2\'(\7\n\2\2(*\5\6\4\2"+
|
||||
")\'\3\2\2\2)*\3\2\2\2*\62\3\2\2\2+,\7\13\2\2,-\7\b\2\2-.\5\b\5\2./\7\t"+
|
||||
"\2\2/\60\5\6\4\2\60\62\3\2\2\2\61\22\3\2\2\2\61\27\3\2\2\2\61\37\3\2\2"+
|
||||
"\2\61\"\3\2\2\2\61+\3\2\2\2\62\7\3\2\2\2\63\64\b\5\1\2\64\65\7\b\2\2\65"+
|
||||
"\66\5\b\5\2\66\67\7\t\2\2\67?\3\2\2\289\t\2\2\29?\5\b\5\f:?\7+\2\2;?\7"+
|
||||
"\"\2\2<?\7 \2\2=?\7!\2\2>\63\3\2\2\2>8\3\2\2\2>:\3\2\2\2>;\3\2\2\2><\3"+
|
||||
"\2\2\2>=\3\2\2\2?Q\3\2\2\2@A\f\13\2\2AB\t\3\2\2BP\5\b\5\fCD\f\n\2\2DE"+
|
||||
"\t\4\2\2EP\5\b\5\13FG\f\t\2\2GH\t\5\2\2HP\5\b\5\nIJ\f\b\2\2JK\t\6\2\2"+
|
||||
"KP\5\b\5\tLM\f\7\2\2MN\t\7\2\2NP\5\b\5\bO@\3\2\2\2OC\3\2\2\2OF\3\2\2\2"+
|
||||
"OI\3\2\2\2OL\3\2\2\2PS\3\2\2\2QO\3\2\2\2QR\3\2\2\2R\t\3\2\2\2SQ\3\2\2"+
|
||||
"\2\n\20\27\34)\61>OQ";
|
||||
public static final ATN _ATN =
|
||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||
static {
|
||||
|
@ -10,6 +10,53 @@ import org.antlr.v4.runtime.tree.ParseTreeVisitor;
|
||||
* operations with no return type.
|
||||
*/
|
||||
public interface KickCVisitor<T> extends ParseTreeVisitor<T> {
|
||||
/**
|
||||
* Visit a parse tree produced by {@link KickCParser#file}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitFile(KickCParser.FileContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link KickCParser#stmtSeq}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitStmtSeq(KickCParser.StmtSeqContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code stmtBlock}
|
||||
* labeled alternative in {@link KickCParser#stmt}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitStmtBlock(KickCParser.StmtBlockContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code stmtAssignment}
|
||||
* labeled alternative in {@link KickCParser#stmt}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitStmtAssignment(KickCParser.StmtAssignmentContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code stmtExpr}
|
||||
* labeled alternative in {@link KickCParser#stmt}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitStmtExpr(KickCParser.StmtExprContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code stmtIfElse}
|
||||
* labeled alternative in {@link KickCParser#stmt}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitStmtIfElse(KickCParser.StmtIfElseContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code stmtWhile}
|
||||
* labeled alternative in {@link KickCParser#stmt}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitStmtWhile(KickCParser.StmtWhileContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code exprBinary}
|
||||
* labeled alternative in {@link KickCParser#expr}.
|
||||
|
@ -5,16 +5,110 @@ import dk.camelot64.kickc.parser.KickCParser;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
|
||||
/** Generates program SSA form by visiting the ANTLR4 parse tree*/
|
||||
public class GenerateSSA extends KickCBaseVisitor<SSAFragment> {
|
||||
public class GenerateSSA extends KickCBaseVisitor<SSARValue> {
|
||||
|
||||
SSAVariableManager variableManager;
|
||||
private SymbolManager symbolManager;
|
||||
private SSASequence sequence;
|
||||
|
||||
public GenerateSSA(SSAVariableManager variableManager) {
|
||||
this.variableManager = variableManager;
|
||||
public GenerateSSA() {
|
||||
this.symbolManager = new SymbolManager();
|
||||
this.sequence = new SSASequence();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SSAFragment visitExprNumber(KickCParser.ExprNumberContext ctx) {
|
||||
public SSARValue visitFile(KickCParser.FileContext ctx) {
|
||||
this.visit(ctx.stmtSeq());
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SSARValue visitStmtSeq(KickCParser.StmtSeqContext ctx) {
|
||||
for(int i=0; i<ctx.getChildCount(); i++) {
|
||||
this.visit(ctx.stmt(i));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SSARValue visitStmtBlock(KickCParser.StmtBlockContext ctx) {
|
||||
this.visit(ctx.stmtSeq());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SSARValue visitStmtExpr(KickCParser.StmtExprContext ctx) {
|
||||
this.visit(ctx.expr());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SSARValue visitStmtIfElse(KickCParser.StmtIfElseContext ctx) {
|
||||
SSARValue rValue = this.visit(ctx.expr());
|
||||
SSAJumpLabel ifJumpLabel = symbolManager.newIntermediateJumpLabel();
|
||||
SSAJumpLabel elseJumpLabel = symbolManager.newIntermediateJumpLabel();
|
||||
SSAStatement ifJmpStmt = new SSAStatementConditionalJump(rValue, ifJumpLabel);
|
||||
sequence.addStatement(ifJmpStmt);
|
||||
SSAStatement elseJmpStmt = new SSAStatementJump(elseJumpLabel);
|
||||
sequence.addStatement(elseJmpStmt);
|
||||
SSAStatementJumpTarget ifJumpTarget = new SSAStatementJumpTarget(ifJumpLabel);
|
||||
sequence.addStatement(ifJumpTarget);
|
||||
this.visit(ctx.stmt(0));
|
||||
KickCParser.StmtContext elseStmt = ctx.stmt(1);
|
||||
if(elseStmt!=null) {
|
||||
SSAJumpLabel endJumpLabel = symbolManager.newIntermediateJumpLabel();
|
||||
SSAStatement endJmpStmt = new SSAStatementJump(endJumpLabel);
|
||||
sequence.addStatement(endJmpStmt);
|
||||
SSAStatementJumpTarget elseJumpTarget = new SSAStatementJumpTarget(elseJumpLabel);
|
||||
sequence.addStatement(elseJumpTarget);
|
||||
this.visit(elseStmt);
|
||||
SSAStatementJumpTarget endJumpTarget = new SSAStatementJumpTarget(endJumpLabel);
|
||||
sequence.addStatement(endJumpTarget);
|
||||
} else {
|
||||
SSAStatementJumpTarget elseJumpTarget = new SSAStatementJumpTarget(elseJumpLabel);
|
||||
sequence.addStatement(elseJumpTarget);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SSARValue visitStmtWhile(KickCParser.StmtWhileContext ctx) {
|
||||
SSAJumpLabel beginJumpLabel = symbolManager.newIntermediateJumpLabel();
|
||||
SSAJumpLabel doJumpLabel = symbolManager.newIntermediateJumpLabel();
|
||||
SSAJumpLabel endJumpLabel = symbolManager.newIntermediateJumpLabel();
|
||||
SSAStatementJumpTarget beginJumpTarget = new SSAStatementJumpTarget(beginJumpLabel);
|
||||
sequence.addStatement(beginJumpTarget);
|
||||
SSARValue rValue = this.visit(ctx.expr());
|
||||
SSAStatement doJmpStmt = new SSAStatementConditionalJump(rValue, doJumpLabel);
|
||||
sequence.addStatement(doJmpStmt);
|
||||
SSAStatement endJmpStmt = new SSAStatementJump(endJumpLabel);
|
||||
sequence.addStatement(endJmpStmt);
|
||||
SSAStatementJumpTarget doJumpTarget = new SSAStatementJumpTarget(doJumpLabel);
|
||||
sequence.addStatement(doJumpTarget);
|
||||
this.visit(ctx.stmt());
|
||||
SSAStatement beginJmpStmt = new SSAStatementJump(beginJumpLabel);
|
||||
sequence.addStatement(beginJmpStmt);
|
||||
SSAStatementJumpTarget endJumpTarget = new SSAStatementJumpTarget(endJumpLabel);
|
||||
sequence.addStatement(endJumpTarget);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SSARValue visitStmtAssignment(KickCParser.StmtAssignmentContext ctx) {
|
||||
if(ctx.TYPE()!=null) {
|
||||
symbolManager.newVariableDeclaration(ctx.NAME().getText(), ctx.TYPE().getText());
|
||||
}
|
||||
if(ctx.expr()!=null) {
|
||||
SSARValue rValue = this.visit(ctx.expr());
|
||||
Symbol variable = symbolManager.newVariableAssignment(ctx.NAME().getText());
|
||||
SSAStatement stmt = new SSAStatementAssignment(variable, rValue);
|
||||
sequence.addStatement(stmt);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SSARValue visitExprNumber(KickCParser.ExprNumberContext ctx) {
|
||||
Number number = KickCNumberParser.parseLiteral(ctx.getText());
|
||||
if(number instanceof Integer) {
|
||||
return new SSAConstantInteger((Integer) number);
|
||||
@ -24,54 +118,55 @@ public class GenerateSSA extends KickCBaseVisitor<SSAFragment> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SSAFragment visitExprString(KickCParser.ExprStringContext ctx) {
|
||||
public SSARValue visitExprString(KickCParser.ExprStringContext ctx) {
|
||||
return new SSAConstantString(ctx.getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SSAFragment visitExprBool(KickCParser.ExprBoolContext ctx) {
|
||||
public SSARValue visitExprBool(KickCParser.ExprBoolContext ctx) {
|
||||
String bool = ctx.getText();
|
||||
return new SSAConstantBool(new Boolean(bool));
|
||||
return new SSAConstantBool(Boolean.valueOf(bool));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SSAFragment visitExprBinary(KickCParser.ExprBinaryContext ctx) {
|
||||
SSAFragment left = this.visit(ctx.expr(0));
|
||||
SSAFragment right = this.visit(ctx.expr(1));
|
||||
public SSARValue visitExprBinary(KickCParser.ExprBinaryContext ctx) {
|
||||
SSARValue left = this.visit(ctx.expr(0));
|
||||
SSARValue right = this.visit(ctx.expr(1));
|
||||
String op = ((TerminalNode)ctx.getChild(1)).getSymbol().getText();
|
||||
SSAOperator operator = new SSAOperator(op);
|
||||
SSAVariable tmpVar = variableManager.generateIntermediateVariable();
|
||||
SSAStatement stmt = new SSAStatement(tmpVar, getSSARValue(left), operator, getSSARValue(right));
|
||||
System.out.println(stmt);
|
||||
return stmt;
|
||||
Symbol tmpVar = symbolManager.newIntermediateAssignment();
|
||||
SSAStatement stmt = new SSAStatementAssignment(tmpVar, left, operator, right);
|
||||
sequence.addStatement(stmt);
|
||||
return tmpVar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SSAFragment visitExprUnary(KickCParser.ExprUnaryContext ctx) {
|
||||
SSAFragment child = this.visit(ctx.expr());
|
||||
public SSARValue visitExprUnary(KickCParser.ExprUnaryContext ctx) {
|
||||
SSARValue child = this.visit(ctx.expr());
|
||||
String op = ((TerminalNode)ctx.getChild(0)).getSymbol().getText();
|
||||
SSAOperator operator = new SSAOperator(op);
|
||||
SSAVariable tmpVar = variableManager.generateIntermediateVariable();
|
||||
SSAStatement stmt = new SSAStatement(tmpVar, operator, getSSARValue(child));
|
||||
System.out.println(stmt);
|
||||
return stmt;
|
||||
Symbol tmpVar = symbolManager.newIntermediateAssignment();
|
||||
SSAStatement stmt = new SSAStatementAssignment(tmpVar, operator, child);
|
||||
sequence.addStatement(stmt);
|
||||
return tmpVar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SSAFragment visitExprPar(KickCParser.ExprParContext ctx) {
|
||||
public SSARValue visitExprPar(KickCParser.ExprParContext ctx) {
|
||||
return this.visit(ctx.expr());
|
||||
}
|
||||
|
||||
SSARValue getSSARValue(SSAFragment ssaFragment) {
|
||||
if(ssaFragment instanceof SSARValue) {
|
||||
return (SSARValue) ssaFragment;
|
||||
} if(ssaFragment instanceof SSAStatement) {
|
||||
SSAStatement ssaStatement = (SSAStatement) ssaFragment;
|
||||
return (SSARValue) ssaStatement.getlValue();
|
||||
}
|
||||
throw new RuntimeException("Cannot extract SSA RValue");
|
||||
@Override
|
||||
public SSARValue visitExprId(KickCParser.ExprIdContext ctx) {
|
||||
return symbolManager.newVariableUsage(ctx.NAME().getText());
|
||||
}
|
||||
|
||||
public SSASequence getSequence() {
|
||||
return sequence;
|
||||
}
|
||||
|
||||
public SymbolManager getSymbols() {
|
||||
return this.symbolManager;
|
||||
}
|
||||
}
|
||||
|
84
src/dk/camelot64/kickc/ssa/PassTypeInference.java
Normal file
84
src/dk/camelot64/kickc/ssa/PassTypeInference.java
Normal file
@ -0,0 +1,84 @@
|
||||
package dk.camelot64.kickc.ssa;
|
||||
|
||||
/**
|
||||
* Pass through the SSA statements inferring types of unresolved variables.
|
||||
*/
|
||||
public class PassTypeInference {
|
||||
|
||||
public void inferTypes(SSASequence sequence, SymbolManager symbols) {
|
||||
for (SSAStatement statement : sequence.getStatements()) {
|
||||
if (statement instanceof SSAStatementAssignment) {
|
||||
SSAStatementAssignment assignment = (SSAStatementAssignment) statement;
|
||||
Symbol symbol = (Symbol) assignment.getlValue();
|
||||
if (SymbolType.VAR.equals(symbol.getType())) {
|
||||
// Unresolved symbol - perform inference
|
||||
SSAOperator operator = assignment.getOperator();
|
||||
if (operator == null || assignment.getRValue1() == null) {
|
||||
// Copy operation or Unary operation
|
||||
SSARValue rValue = assignment.getRValue2();
|
||||
SymbolType type = inferType(rValue);
|
||||
symbol.setInferredType(type);
|
||||
} else {
|
||||
// Binary operation
|
||||
SymbolType type1 = inferType(assignment.getRValue1());
|
||||
SymbolType type2 = inferType(assignment.getRValue2());
|
||||
SymbolType type = inferType(type1, operator, type2);
|
||||
symbol.setInferredType(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private SymbolType inferType(SymbolType type1, SSAOperator operator, SymbolType type2) {
|
||||
String op = operator.getOperator();
|
||||
switch (op) {
|
||||
case "==":
|
||||
case "<":
|
||||
case "<=":
|
||||
case "=<":
|
||||
case ">":
|
||||
case ">=":
|
||||
case "=>":
|
||||
case "<>":
|
||||
case "!=":
|
||||
case "&&":
|
||||
case "||":
|
||||
case "and":
|
||||
case "or":
|
||||
return SymbolType.BOOLEAN;
|
||||
case "+":
|
||||
case "-":
|
||||
case "*":
|
||||
case "/":
|
||||
if (type1.equals(SymbolType.WORD) || type2.equals(SymbolType.WORD)) {
|
||||
return SymbolType.WORD;
|
||||
} else {
|
||||
return SymbolType.BYTE;
|
||||
}
|
||||
default:
|
||||
return SymbolType.VAR;
|
||||
}
|
||||
}
|
||||
|
||||
private SymbolType inferType(SSARValue rValue) {
|
||||
SymbolType type = SymbolType.VAR;
|
||||
if (rValue instanceof Symbol) {
|
||||
Symbol rSymbol = (Symbol) rValue;
|
||||
type = rSymbol.getType();
|
||||
} else if (rValue instanceof SSAConstantInteger) {
|
||||
SSAConstantInteger rInt = (SSAConstantInteger) rValue;
|
||||
if (rInt.getNumber() < 256) {
|
||||
type = SymbolType.BYTE;
|
||||
} else {
|
||||
type = SymbolType.WORD;
|
||||
}
|
||||
} else if (rValue instanceof SSAConstantString) {
|
||||
type = SymbolType.STRING;
|
||||
} else if (rValue instanceof SSAConstantBool) {
|
||||
type = SymbolType.BOOLEAN;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,25 @@
|
||||
package dk.camelot64.kickc.ssa;
|
||||
|
||||
/**
|
||||
* Created by jespergravgaard on 02/05/2017.
|
||||
*/
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** A sequence of SSA statements */
|
||||
public class SSABasicBlock {
|
||||
|
||||
List<SSAStatement> statements;
|
||||
|
||||
public SSABasicBlock() {
|
||||
this.statements = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void addStatement(SSAStatement statement) {
|
||||
this.statements.add(statement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SSABasicBlock{" +
|
||||
"statements=" + statements +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,10 @@ public class SSAConstantInteger implements SSAConstant {
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
public Integer getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Integer.toString(number);
|
||||
|
16
src/dk/camelot64/kickc/ssa/SSAJumpLabel.java
Normal file
16
src/dk/camelot64/kickc/ssa/SSAJumpLabel.java
Normal file
@ -0,0 +1,16 @@
|
||||
package dk.camelot64.kickc.ssa;
|
||||
|
||||
/** A label representing a target of a jump in SSA code */
|
||||
public class SSAJumpLabel {
|
||||
|
||||
private String name;
|
||||
|
||||
public SSAJumpLabel(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
@ -9,6 +9,10 @@ public class SSAOperator {
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
public String getOperator() {
|
||||
return operator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return operator ;
|
||||
|
33
src/dk/camelot64/kickc/ssa/SSASequence.java
Normal file
33
src/dk/camelot64/kickc/ssa/SSASequence.java
Normal file
@ -0,0 +1,33 @@
|
||||
package dk.camelot64.kickc.ssa;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A sequence of SSA Statements
|
||||
*/
|
||||
public class SSASequence {
|
||||
|
||||
List<SSAStatement> statements;
|
||||
|
||||
public SSASequence() {
|
||||
this.statements = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void addStatement(SSAStatement statement) {
|
||||
this.statements.add(statement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuffer out = new StringBuffer();
|
||||
for (SSAStatement statement : statements) {
|
||||
out.append(statement.toString()+"\n");
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
public List<SSAStatement> getStatements() {
|
||||
return statements;
|
||||
}
|
||||
}
|
@ -3,50 +3,8 @@ package dk.camelot64.kickc.ssa;
|
||||
/**
|
||||
* Single Static Assignment Form Statement.
|
||||
* Intermediate form used for compiler optimization.
|
||||
* <br>
|
||||
* <i> X<sub>i</sub> := Y<sub>j</sub> <op> Z<sub>k</sub> </i>
|
||||
* <br>
|
||||
* <i> lValue := rValue1 <operator> rValue2 </i>
|
||||
*/
|
||||
public class SSAStatement implements SSAFragment {
|
||||
public interface SSAStatement extends SSAFragment {
|
||||
|
||||
private SSALValue lValue;
|
||||
private SSARValue rValue1;
|
||||
private SSAOperator operator;
|
||||
private SSARValue rValue2;
|
||||
|
||||
public SSAStatement(SSALValue lValue, SSARValue rValue1, SSAOperator operator, SSARValue rValue2) {
|
||||
this.lValue = lValue;
|
||||
this.rValue1 = rValue1;
|
||||
this.operator = operator;
|
||||
this.rValue2 = rValue2;
|
||||
}
|
||||
|
||||
public SSAStatement(SSALValue lValue, SSAOperator operator, SSARValue rValue2) {
|
||||
this.lValue = lValue;
|
||||
this.rValue1 = null;
|
||||
this.operator = operator;
|
||||
this.rValue2 = rValue2;
|
||||
}
|
||||
|
||||
public SSALValue getlValue() {
|
||||
return lValue;
|
||||
}
|
||||
|
||||
public SSARValue getrValue1() {
|
||||
return rValue1;
|
||||
}
|
||||
|
||||
public SSAOperator getOperator() {
|
||||
return operator;
|
||||
}
|
||||
|
||||
public SSARValue getrValue2() {
|
||||
return rValue2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return lValue + " := " + (rValue1==null?"":rValue1) + " " + operator + " " + rValue2 ;
|
||||
}
|
||||
}
|
||||
|
66
src/dk/camelot64/kickc/ssa/SSAStatementAssignment.java
Normal file
66
src/dk/camelot64/kickc/ssa/SSAStatementAssignment.java
Normal file
@ -0,0 +1,66 @@
|
||||
package dk.camelot64.kickc.ssa;
|
||||
|
||||
/**
|
||||
* Single Static Assignment Form Statement.
|
||||
* Intermediate form used for compiler optimization.
|
||||
* <br>
|
||||
* <i> X<sub>i</sub> := Y<sub>j</sub> <op> Z<sub>k</sub> </i>
|
||||
* <br>
|
||||
* <i> lValue := rValue1 <operator> rValue2 </i>
|
||||
*/
|
||||
public class SSAStatementAssignment implements SSAStatement {
|
||||
|
||||
/** The variable being assigned a value by the statement. */
|
||||
private SSALValue lValue;
|
||||
|
||||
private SSARValue rValue1;
|
||||
private SSAOperator operator;
|
||||
private SSARValue rValue2;
|
||||
|
||||
public SSAStatementAssignment(SSALValue lValue, SSARValue rValue2) {
|
||||
this.lValue = lValue;
|
||||
this.rValue1 = null;
|
||||
this.operator = null;
|
||||
this.rValue2 = rValue2;
|
||||
}
|
||||
|
||||
public SSAStatementAssignment(SSALValue lValue, SSARValue rValue1, SSAOperator operator, SSARValue rValue2) {
|
||||
this.lValue = lValue;
|
||||
this.rValue1 = rValue1;
|
||||
this.operator = operator;
|
||||
this.rValue2 = rValue2;
|
||||
}
|
||||
|
||||
public SSAStatementAssignment(SSALValue lValue, SSAOperator operator, SSARValue rValue2) {
|
||||
this.lValue = lValue;
|
||||
this.rValue1 = null;
|
||||
this.operator = operator;
|
||||
this.rValue2 = rValue2;
|
||||
}
|
||||
|
||||
public SSALValue getlValue() {
|
||||
return lValue;
|
||||
}
|
||||
|
||||
public SSARValue getRValue1() {
|
||||
return rValue1;
|
||||
}
|
||||
|
||||
public SSAOperator getOperator() {
|
||||
return operator;
|
||||
}
|
||||
|
||||
public SSARValue getRValue2() {
|
||||
return rValue2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return
|
||||
" "+
|
||||
lValue + " ← " +
|
||||
(rValue1==null?"":rValue1+" ") +
|
||||
(operator==null?"":operator+" ") +
|
||||
rValue2 ;
|
||||
}
|
||||
}
|
31
src/dk/camelot64/kickc/ssa/SSAStatementConditionalJump.java
Normal file
31
src/dk/camelot64/kickc/ssa/SSAStatementConditionalJump.java
Normal file
@ -0,0 +1,31 @@
|
||||
package dk.camelot64.kickc.ssa;
|
||||
|
||||
/**
|
||||
* Single Static Assignment Form Statement with a conditional jump.
|
||||
* Intermediate form used for compiler optimization.
|
||||
* <br>
|
||||
* <i> if ( Y<sub>j</sub> ) goto XX </i>
|
||||
*/
|
||||
public class SSAStatementConditionalJump implements SSAStatement {
|
||||
|
||||
private SSARValue condition;
|
||||
private SSAJumpLabel destination;
|
||||
|
||||
public SSAStatementConditionalJump(SSARValue condition, SSAJumpLabel destination) {
|
||||
this.condition = condition;
|
||||
this.destination = destination;
|
||||
}
|
||||
|
||||
public SSARValue getCondition() {
|
||||
return condition;
|
||||
}
|
||||
|
||||
public SSAJumpLabel getDestination() {
|
||||
return destination;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return " "+"if("+condition+") goto "+destination;
|
||||
}
|
||||
}
|
25
src/dk/camelot64/kickc/ssa/SSAStatementJump.java
Normal file
25
src/dk/camelot64/kickc/ssa/SSAStatementJump.java
Normal file
@ -0,0 +1,25 @@
|
||||
package dk.camelot64.kickc.ssa;
|
||||
|
||||
/**
|
||||
* Single Static Assignment Form Statement unconditional jump.
|
||||
* Intermediate form used for compiler optimization.
|
||||
* <br>
|
||||
* <i> goto XX </i>
|
||||
*/
|
||||
public class SSAStatementJump implements SSAStatement {
|
||||
|
||||
private SSAJumpLabel destination;
|
||||
|
||||
public SSAStatementJump(SSAJumpLabel destination) {
|
||||
this.destination = destination;
|
||||
}
|
||||
|
||||
public SSAJumpLabel getDestination() {
|
||||
return destination;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return " "+"goto "+destination;
|
||||
}
|
||||
}
|
24
src/dk/camelot64/kickc/ssa/SSAStatementJumpTarget.java
Normal file
24
src/dk/camelot64/kickc/ssa/SSAStatementJumpTarget.java
Normal file
@ -0,0 +1,24 @@
|
||||
package dk.camelot64.kickc.ssa;
|
||||
|
||||
/**
|
||||
* Single Static Assignment Form Statement Jump target.
|
||||
*/
|
||||
public class SSAStatementJumpTarget implements SSAStatement {
|
||||
|
||||
private SSAJumpLabel label;
|
||||
|
||||
public SSAStatementJumpTarget(SSAJumpLabel label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public SSAJumpLabel getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return label+":";
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -4,12 +4,21 @@ package dk.camelot64.kickc.ssa;
|
||||
* <ul>
|
||||
* <li>Each potential modification of a language variable becomes a separate versioned SSA variable.</li>
|
||||
* <li>Expressions are broken into separate SSA statements, each defining a new temporary/intermediate variable.</li>
|
||||
* </ul>*/
|
||||
public class SSAVariable implements SSARValue, SSALValue {
|
||||
* </ul>
|
||||
*
|
||||
* Named variables are initially created without serials. These are first added after the basic control blocks have been defined.
|
||||
*
|
||||
* */
|
||||
public class SSAVariable implements SSARValue, SSALValue, SSAFragment {
|
||||
|
||||
private String name;
|
||||
|
||||
private int serial;
|
||||
private Integer serial;
|
||||
|
||||
public SSAVariable(String name) {
|
||||
this.name = name;
|
||||
this.serial = null;
|
||||
}
|
||||
|
||||
public SSAVariable(String name, int serial) {
|
||||
this.name = name;
|
||||
@ -26,6 +35,6 @@ public class SSAVariable implements SSARValue, SSALValue {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + '_' + serial;
|
||||
return name + (serial==null?"":"_"+serial);
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
package dk.camelot64.kickc.ssa;
|
||||
|
||||
/** Manages creation of new variables from declarations or temporary (intermediate) */
|
||||
public class SSAVariableManager {
|
||||
|
||||
private int nxtTemporaryId = 1;
|
||||
|
||||
public SSAVariable generateIntermediateVariable() {
|
||||
return new SSAVariable("@", nxtTemporaryId++);
|
||||
}
|
||||
|
||||
}
|
43
src/dk/camelot64/kickc/ssa/Symbol.java
Normal file
43
src/dk/camelot64/kickc/ssa/Symbol.java
Normal file
@ -0,0 +1,43 @@
|
||||
package dk.camelot64.kickc.ssa;
|
||||
|
||||
/** A Symbol (variable, jump label, etc.) */
|
||||
public class Symbol implements SSARValue, SSALValue, SSAFragment {
|
||||
|
||||
private String name;
|
||||
|
||||
private SymbolType type;
|
||||
|
||||
private boolean intermediate;
|
||||
|
||||
private boolean inferredType;
|
||||
|
||||
public Symbol(String name, SymbolType type, boolean intermediate) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.intermediate = intermediate;
|
||||
this.inferredType = false;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public SymbolType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setInferredType(SymbolType type) {
|
||||
this.type = type;
|
||||
this.inferredType = true;
|
||||
}
|
||||
|
||||
public boolean isIntermediate() {
|
||||
return intermediate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "("+name + (intermediate?"*":"") + ": " + type.getTypeName() + (inferredType ?"*":"") + ")";
|
||||
}
|
||||
|
||||
}
|
68
src/dk/camelot64/kickc/ssa/SymbolManager.java
Normal file
68
src/dk/camelot64/kickc/ssa/SymbolManager.java
Normal file
@ -0,0 +1,68 @@
|
||||
package dk.camelot64.kickc.ssa;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Manages symbols (variables, labels)
|
||||
*/
|
||||
public class SymbolManager {
|
||||
|
||||
private Map<String, Symbol> symbols;
|
||||
|
||||
private int intermediateVarCount = 0;
|
||||
private int intermediateLabelCount = 0;
|
||||
|
||||
public SymbolManager() {
|
||||
this.symbols = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
private Symbol addSymbol(String name, SymbolType symbolType, boolean intermediate) {
|
||||
if(symbols.get(name)!=null) {
|
||||
throw new RuntimeException("Symbol already declared "+name);
|
||||
}
|
||||
Symbol symbol = new Symbol(name, symbolType, intermediate);
|
||||
symbols.put(name, symbol);
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void newVariableDeclaration(String name, String type) {
|
||||
SymbolType symbolType = SymbolType.get(type);
|
||||
addSymbol(name, symbolType, false);
|
||||
}
|
||||
|
||||
public Symbol newVariableAssignment(String varName) {
|
||||
return symbols.get(varName);
|
||||
}
|
||||
|
||||
public Symbol newVariableUsage(String varName) {
|
||||
return symbols.get(varName);
|
||||
}
|
||||
|
||||
public Symbol newIntermediateAssignment() {
|
||||
String name = "$"+intermediateVarCount++;
|
||||
Symbol symbol = addSymbol(name, SymbolType.VAR, true);
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public SSAJumpLabel newNamedJumpLabel(String name) {
|
||||
Symbol symbol = addSymbol(name, SymbolType.LABEL, false);
|
||||
return new SSAJumpLabel(name);
|
||||
}
|
||||
|
||||
public SSAJumpLabel newIntermediateJumpLabel() {
|
||||
String name = "@"+ intermediateLabelCount++;
|
||||
addSymbol(name, SymbolType.LABEL, true);
|
||||
return new SSAJumpLabel(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuffer out = new StringBuffer();
|
||||
for (String name : symbols.keySet()) {
|
||||
Symbol symbol = symbols.get(name);
|
||||
out.append(symbol.toString() + "\n");
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
33
src/dk/camelot64/kickc/ssa/SymbolType.java
Normal file
33
src/dk/camelot64/kickc/ssa/SymbolType.java
Normal file
@ -0,0 +1,33 @@
|
||||
package dk.camelot64.kickc.ssa;
|
||||
|
||||
/** Symbol Types */
|
||||
public enum SymbolType {
|
||||
BYTE("byte"),
|
||||
WORD("word"),
|
||||
STRING("string"),
|
||||
BOOLEAN("boolean"),
|
||||
LABEL("label"),
|
||||
VAR("var");
|
||||
|
||||
private String typeName;
|
||||
|
||||
SymbolType(String typeName) {
|
||||
this.typeName = typeName;
|
||||
}
|
||||
|
||||
public String getTypeName() {
|
||||
return typeName;
|
||||
}
|
||||
|
||||
public static SymbolType get(String name) {
|
||||
switch (name) {
|
||||
case "byte": return BYTE;
|
||||
case "word": return WORD;
|
||||
case "string": return STRING;
|
||||
case "boolean": return BOOLEAN;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -3,7 +3,8 @@ package dk.camelot64.kickc.test;
|
||||
import dk.camelot64.kickc.parser.KickCLexer;
|
||||
import dk.camelot64.kickc.parser.KickCParser;
|
||||
import dk.camelot64.kickc.ssa.GenerateSSA;
|
||||
import dk.camelot64.kickc.ssa.SSAVariableManager;
|
||||
import dk.camelot64.kickc.ssa.PassTypeInference;
|
||||
import dk.camelot64.kickc.ssa.SSASequence;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
@ -18,9 +19,17 @@ public class main {
|
||||
KickCLexer lexer = new KickCLexer(input);
|
||||
KickCParser parser = new KickCParser(new CommonTokenStream(lexer));
|
||||
parser.setBuildParseTree(true);
|
||||
KickCParser.ExprContext expr = parser.expr();
|
||||
GenerateSSA ev = new GenerateSSA(new SSAVariableManager());
|
||||
Object result = ev.visit(expr);
|
||||
KickCParser.FileContext file = parser.file();
|
||||
GenerateSSA ev = new GenerateSSA();
|
||||
ev.visit(file);
|
||||
|
||||
PassTypeInference passTypeInference = new PassTypeInference();
|
||||
passTypeInference.inferTypes(ev.getSequence(), ev.getSymbols());
|
||||
|
||||
System.out.println("PROGRAM");
|
||||
System.out.println(ev.getSequence().toString());
|
||||
System.out.println("SYMBOLS");
|
||||
System.out.println(ev.getSymbols().toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1 +1,7 @@
|
||||
1+2*3/(-$4+%101) = 12 || 1+1=2 && "qwe" < "asd" and not false
|
||||
byte a = 0;
|
||||
word b = 0;
|
||||
while(a<10) {
|
||||
b=b+a;
|
||||
a=a+1;
|
||||
}
|
||||
byte c = -a;
|
Loading…
x
Reference in New Issue
Block a user