mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-26 12:49:21 +00:00
Now supports multi-line #defines, nested #defines and ends recursive #defines correctly. #169
This commit is contained in:
parent
a2de5faf47
commit
ea49dc910a
@ -1,15 +1,13 @@
|
||||
package dk.camelot64.kickc.macros;
|
||||
|
||||
import org.antlr.v4.runtime.CommonToken;
|
||||
import org.antlr.v4.runtime.ListTokenSource;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.TokenSource;
|
||||
import dk.camelot64.kickc.model.CompileError;
|
||||
import org.antlr.v4.runtime.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* C Macro expander.
|
||||
*
|
||||
* <p>
|
||||
* The macro expander takes one token source as input and produces a new expanded token source as output
|
||||
*/
|
||||
public class CMacroExpander {
|
||||
@ -22,12 +20,24 @@ public class CMacroExpander {
|
||||
private final int tokenDefine;
|
||||
/** The token type for identifiers. */
|
||||
private final int tokenIdentifier;
|
||||
/** The token type for parenthesis begin. */
|
||||
private final int tokenParBegin;
|
||||
/** The token type for parenthesis end. */
|
||||
private final int tokenParEnd;
|
||||
/** The token type for comma. */
|
||||
private final int tokenComma;
|
||||
/** The token type for define multi-line. */
|
||||
private final int tokenDefineMultiline;
|
||||
|
||||
public CMacroExpander(int channelWhitespace, int tokenWhitespace, int tokenDefine, int tokenIdentifier) {
|
||||
public CMacroExpander(int channelWhitespace, int tokenWhitespace, int tokenDefine, int tokenIdentifier, int tokenParBegin, int tokenParEnd, int tokenComma, int tokenDefineMultiline) {
|
||||
this.channelWhitespace = channelWhitespace;
|
||||
this.tokenWhitespace = tokenWhitespace;
|
||||
this.tokenDefine = tokenDefine;
|
||||
this.tokenIdentifier = tokenIdentifier;
|
||||
this.tokenParBegin = tokenParBegin;
|
||||
this.tokenParEnd = tokenParEnd;
|
||||
this.tokenComma = tokenComma;
|
||||
this.tokenDefineMultiline = tokenDefineMultiline;
|
||||
}
|
||||
|
||||
public TokenSource expandMacros(TokenSource inputTokenSource) {
|
||||
@ -39,31 +49,66 @@ public class CMacroExpander {
|
||||
Token inputToken = tokenIterator.next();
|
||||
if(inputToken.getType() == tokenDefine) {
|
||||
// #define a new macro - find the name
|
||||
Token macroName = tokenIterator.next();
|
||||
while(macroName.getType() == tokenWhitespace)
|
||||
macroName = tokenIterator.next();
|
||||
skipWhitespace(tokenIterator);
|
||||
String macroName = getToken(tokenIterator, tokenIdentifier).getText();
|
||||
// Examine whether the macro has parameters
|
||||
skipWhitespace(tokenIterator);
|
||||
if(tokenIterator.peek().getType() == tokenParBegin) {
|
||||
// Macro has parameters - find parameter name list
|
||||
throw new CompileError("Macros with parameters not supported!");
|
||||
}
|
||||
// Find body by gobbling tokens until the line ends
|
||||
final ArrayList<Token> macroBody = new ArrayList<>();
|
||||
boolean macroRead = true;
|
||||
while(macroRead) {
|
||||
final Token bodyToken = tokenIterator.next();
|
||||
if(bodyToken.getType() == tokenDefineMultiline) {
|
||||
// Skip the multi-line token, add a newline token and continue reading body on the next line
|
||||
final CommonToken newlineToken = new CommonToken(bodyToken);
|
||||
newlineToken.setType(tokenWhitespace);
|
||||
newlineToken.setChannel(channelWhitespace);
|
||||
newlineToken.setText("\n");
|
||||
macroBody.add(newlineToken);
|
||||
continue;
|
||||
}
|
||||
if(bodyToken.getChannel() == channelWhitespace && bodyToken.getText().contains("\n")) {
|
||||
macroRead = false;
|
||||
} else {
|
||||
macroBody.add(bodyToken);
|
||||
}
|
||||
}
|
||||
macros.put(macroName.getText(), macroBody);
|
||||
macros.put(macroName, macroBody);
|
||||
} else {
|
||||
if(inputToken.getType() == tokenIdentifier && macros.containsKey(inputToken.getText())) {
|
||||
// Macro expansion is needed
|
||||
final List<Token> macroBody = macros.get(inputToken.getText());
|
||||
for(Token bodyToken : macroBody) {
|
||||
final CommonToken expandedToken = new CommonToken(inputToken);
|
||||
expandedToken.setText(bodyToken.getText());
|
||||
expandedToken.setType(bodyToken.getType());
|
||||
expandedToken.setChannel(bodyToken.getChannel());
|
||||
expandedTokens.add(expandedToken);
|
||||
if(inputToken.getType() == tokenIdentifier) {
|
||||
final String macroName = inputToken.getText();
|
||||
if(macros.containsKey(macroName)) {
|
||||
// Check for macro recursion
|
||||
if(inputToken instanceof ExpansionToken) {
|
||||
if(((ExpansionToken) inputToken).getMacroNames().contains(macroName)) {
|
||||
// Detected macro recursion in the expansion - add directly to output and move on!
|
||||
expandedTokens.add(inputToken);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Macro expansion is needed
|
||||
final List<Token> macroBody = macros.get(macroName);
|
||||
List<Token> expandedBody = new ArrayList<>();
|
||||
for(Token bodyToken : macroBody) {
|
||||
final CommonToken expandedToken = new CommonToken(inputToken);
|
||||
expandedToken.setText(bodyToken.getText());
|
||||
expandedToken.setType(bodyToken.getType());
|
||||
expandedToken.setChannel(bodyToken.getChannel());
|
||||
Set<String> macroNames = new HashSet<>();
|
||||
if(inputToken instanceof ExpansionToken) {
|
||||
// Transfer macro names to the new expansion
|
||||
macroNames = ((ExpansionToken) inputToken).getMacroNames();
|
||||
}
|
||||
macroNames.add(macroName);
|
||||
expandedBody.add(new ExpansionToken(expandedToken, macroNames));
|
||||
}
|
||||
tokenIterator.addFirst(expandedBody);
|
||||
} else {
|
||||
expandedTokens.add(inputToken);
|
||||
}
|
||||
} else {
|
||||
expandedTokens.add(inputToken);
|
||||
@ -73,6 +118,26 @@ public class CMacroExpander {
|
||||
return new ListTokenSource(expandedTokens);
|
||||
}
|
||||
|
||||
|
||||
private Token getToken(TokenIterator tokenIterator, int tokenType) {
|
||||
if(!tokenIterator.hasNext())
|
||||
throw new CompileError("File ended unexpectedly. Was expecting token " + tokenType);
|
||||
final Token token = tokenIterator.next();
|
||||
if(token.getType() != tokenType)
|
||||
throw new CompileError("Unexpected token. Was expecting " + tokenType);
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip whitespace tokens, positioning iterator at the next non-whitespace
|
||||
*
|
||||
* @param tokenIterator The token iterator
|
||||
*/
|
||||
private void skipWhitespace(TokenIterator tokenIterator) {
|
||||
while(tokenIterator.hasNext() && tokenIterator.peek().getChannel() == channelWhitespace)
|
||||
tokenIterator.next();
|
||||
}
|
||||
|
||||
private List<Token> getTokenList(TokenSource inputTokenSource) {
|
||||
List<Token> inputTokens = new ArrayList<>();
|
||||
Token inputToken;
|
||||
@ -84,43 +149,121 @@ public class CMacroExpander {
|
||||
return inputTokens;
|
||||
}
|
||||
|
||||
interface PeekingIterator<T> extends Iterator<T> {
|
||||
/** A token iterator supporting peeking backed by a list of lists of tokens.
|
||||
* Macro expansion works by prepending a new list of tokens which contains the body of the macro being expanded */
|
||||
static class TokenIterator implements Iterator<Token> {
|
||||
|
||||
/**
|
||||
* Return the next element without progressing the cursot
|
||||
* @return The current element. Null if after the end
|
||||
*/
|
||||
T peek();
|
||||
|
||||
}
|
||||
|
||||
/** A token iterator. */
|
||||
static class TokenIterator implements PeekingIterator<Token> {
|
||||
|
||||
ArrayList<Token> tokens;
|
||||
int idx = 0;
|
||||
Deque<Token> tokens;
|
||||
|
||||
public TokenIterator(Collection<Token> tokens) {
|
||||
this.tokens = new ArrayList<>(tokens);
|
||||
this.tokens = new LinkedList<>(tokens);
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Get the next token without advancing the cursor.
|
||||
*
|
||||
* @return The next token. null if there are no more tokens.
|
||||
*/
|
||||
public Token peek() {
|
||||
return tokens.get(idx);
|
||||
return tokens.getFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return idx<tokens.size();
|
||||
return !tokens.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token next() {
|
||||
final Token token = tokens.get(idx);
|
||||
idx++;
|
||||
return token;
|
||||
return tokens.removeFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a bunch of tokens to the start of the iterator.
|
||||
* This is called when a macro is expanded to add the macro body to the start of the input.
|
||||
* @param tokens The tokens to add
|
||||
*/
|
||||
public void addFirst(List<Token> tokens) {
|
||||
Collections.reverse(tokens);
|
||||
for(Token token : tokens) {
|
||||
this.tokens.addFirst(token);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** A token that is the result of macro expansion.
|
||||
* Keeps track of which macros was used for the expansion.
|
||||
* */
|
||||
public class ExpansionToken implements Token {
|
||||
|
||||
/** The underlying token. */
|
||||
private Token subToken;
|
||||
|
||||
/** The names of all macros used for expanding this token. */
|
||||
private Set<String> macroNames;
|
||||
|
||||
public ExpansionToken(Token subToken, Set<String> macroNames) {
|
||||
this.subToken = subToken;
|
||||
this.macroNames = macroNames;
|
||||
}
|
||||
|
||||
public Set<String> getMacroNames() {
|
||||
return macroNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return subToken.getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType() {
|
||||
return subToken.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLine() {
|
||||
return subToken.getLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharPositionInLine() {
|
||||
return subToken.getCharPositionInLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChannel() {
|
||||
return subToken.getChannel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTokenIndex() {
|
||||
return subToken.getTokenIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStartIndex() {
|
||||
return subToken.getStartIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStopIndex() {
|
||||
return subToken.getStopIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TokenSource getTokenSource() {
|
||||
return subToken.getTokenSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharStream getInputStream() {
|
||||
return subToken.getInputStream();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -22,16 +22,20 @@ stmt
|
||||
;
|
||||
|
||||
expr
|
||||
: '(' SIMPLETYPE ')' expr #exprCast
|
||||
: PAR_BEGIN SIMPLETYPE PAR_END expr #exprCast
|
||||
| IDENTIFIER #exprName
|
||||
| NUMBER #exprNumber
|
||||
| '(' expr ')' #exprPar
|
||||
| PAR_BEGIN expr PAR_END #exprPar
|
||||
| expr '*' expr #exprBinary
|
||||
| expr '/' expr #exprBinary
|
||||
| expr '+' expr #exprBinary
|
||||
| expr '-' expr #exprBinary
|
||||
| expr COMMA expr #exprBinary
|
||||
;
|
||||
|
||||
PAR_BEGIN: '(' ;
|
||||
PAR_END: ')' ;
|
||||
COMMA : ',' ;
|
||||
SIMPLETYPE: 'char' | 'int' ;
|
||||
IDENTIFIER: [a-zA-Z_]+ ;
|
||||
NUMBER: [0-9]+ ;
|
||||
|
@ -1,12 +1,13 @@
|
||||
token literal names:
|
||||
null
|
||||
';'
|
||||
'('
|
||||
')'
|
||||
'*'
|
||||
'/'
|
||||
'+'
|
||||
'-'
|
||||
'('
|
||||
')'
|
||||
','
|
||||
null
|
||||
null
|
||||
null
|
||||
@ -21,8 +22,9 @@ null
|
||||
null
|
||||
null
|
||||
null
|
||||
null
|
||||
null
|
||||
PAR_BEGIN
|
||||
PAR_END
|
||||
COMMA
|
||||
SIMPLETYPE
|
||||
IDENTIFIER
|
||||
NUMBER
|
||||
@ -37,4 +39,4 @@ expr
|
||||
|
||||
|
||||
atn:
|
||||
[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 15, 48, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 3, 2, 7, 2, 10, 10, 2, 12, 2, 14, 2, 13, 11, 2, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 5, 4, 29, 10, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 7, 4, 43, 10, 4, 12, 4, 14, 4, 46, 11, 4, 3, 4, 2, 3, 6, 5, 2, 4, 6, 2, 2, 2, 52, 2, 11, 3, 2, 2, 2, 4, 14, 3, 2, 2, 2, 6, 28, 3, 2, 2, 2, 8, 10, 5, 4, 3, 2, 9, 8, 3, 2, 2, 2, 10, 13, 3, 2, 2, 2, 11, 9, 3, 2, 2, 2, 11, 12, 3, 2, 2, 2, 12, 3, 3, 2, 2, 2, 13, 11, 3, 2, 2, 2, 14, 15, 5, 6, 4, 2, 15, 16, 7, 3, 2, 2, 16, 5, 3, 2, 2, 2, 17, 18, 8, 4, 1, 2, 18, 19, 7, 4, 2, 2, 19, 20, 7, 10, 2, 2, 20, 21, 7, 5, 2, 2, 21, 29, 5, 6, 4, 10, 22, 29, 7, 11, 2, 2, 23, 29, 7, 12, 2, 2, 24, 25, 7, 4, 2, 2, 25, 26, 5, 6, 4, 2, 26, 27, 7, 5, 2, 2, 27, 29, 3, 2, 2, 2, 28, 17, 3, 2, 2, 2, 28, 22, 3, 2, 2, 2, 28, 23, 3, 2, 2, 2, 28, 24, 3, 2, 2, 2, 29, 44, 3, 2, 2, 2, 30, 31, 12, 6, 2, 2, 31, 32, 7, 6, 2, 2, 32, 43, 5, 6, 4, 7, 33, 34, 12, 5, 2, 2, 34, 35, 7, 7, 2, 2, 35, 43, 5, 6, 4, 6, 36, 37, 12, 4, 2, 2, 37, 38, 7, 8, 2, 2, 38, 43, 5, 6, 4, 5, 39, 40, 12, 3, 2, 2, 40, 41, 7, 9, 2, 2, 41, 43, 5, 6, 4, 4, 42, 30, 3, 2, 2, 2, 42, 33, 3, 2, 2, 2, 42, 36, 3, 2, 2, 2, 42, 39, 3, 2, 2, 2, 43, 46, 3, 2, 2, 2, 44, 42, 3, 2, 2, 2, 44, 45, 3, 2, 2, 2, 45, 7, 3, 2, 2, 2, 46, 44, 3, 2, 2, 2, 6, 11, 28, 42, 44]
|
||||
[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 16, 51, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 3, 2, 7, 2, 10, 10, 2, 12, 2, 14, 2, 13, 11, 2, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 5, 4, 29, 10, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 7, 4, 46, 10, 4, 12, 4, 14, 4, 49, 11, 4, 3, 4, 2, 3, 6, 5, 2, 4, 6, 2, 2, 2, 56, 2, 11, 3, 2, 2, 2, 4, 14, 3, 2, 2, 2, 6, 28, 3, 2, 2, 2, 8, 10, 5, 4, 3, 2, 9, 8, 3, 2, 2, 2, 10, 13, 3, 2, 2, 2, 11, 9, 3, 2, 2, 2, 11, 12, 3, 2, 2, 2, 12, 3, 3, 2, 2, 2, 13, 11, 3, 2, 2, 2, 14, 15, 5, 6, 4, 2, 15, 16, 7, 3, 2, 2, 16, 5, 3, 2, 2, 2, 17, 18, 8, 4, 1, 2, 18, 19, 7, 8, 2, 2, 19, 20, 7, 11, 2, 2, 20, 21, 7, 9, 2, 2, 21, 29, 5, 6, 4, 11, 22, 29, 7, 12, 2, 2, 23, 29, 7, 13, 2, 2, 24, 25, 7, 8, 2, 2, 25, 26, 5, 6, 4, 2, 26, 27, 7, 9, 2, 2, 27, 29, 3, 2, 2, 2, 28, 17, 3, 2, 2, 2, 28, 22, 3, 2, 2, 2, 28, 23, 3, 2, 2, 2, 28, 24, 3, 2, 2, 2, 29, 47, 3, 2, 2, 2, 30, 31, 12, 7, 2, 2, 31, 32, 7, 4, 2, 2, 32, 46, 5, 6, 4, 8, 33, 34, 12, 6, 2, 2, 34, 35, 7, 5, 2, 2, 35, 46, 5, 6, 4, 7, 36, 37, 12, 5, 2, 2, 37, 38, 7, 6, 2, 2, 38, 46, 5, 6, 4, 6, 39, 40, 12, 4, 2, 2, 40, 41, 7, 7, 2, 2, 41, 46, 5, 6, 4, 5, 42, 43, 12, 3, 2, 2, 43, 44, 7, 10, 2, 2, 44, 46, 5, 6, 4, 4, 45, 30, 3, 2, 2, 2, 45, 33, 3, 2, 2, 2, 45, 36, 3, 2, 2, 2, 45, 39, 3, 2, 2, 2, 45, 42, 3, 2, 2, 2, 46, 49, 3, 2, 2, 2, 47, 45, 3, 2, 2, 2, 47, 48, 3, 2, 2, 2, 48, 7, 3, 2, 2, 2, 49, 47, 3, 2, 2, 2, 6, 11, 28, 45, 47]
|
@ -3,20 +3,22 @@ T__1=2
|
||||
T__2=3
|
||||
T__3=4
|
||||
T__4=5
|
||||
T__5=6
|
||||
T__6=7
|
||||
SIMPLETYPE=8
|
||||
IDENTIFIER=9
|
||||
NUMBER=10
|
||||
DEFINE=11
|
||||
DEFINE_CONTINUE=12
|
||||
WHITESPACE=13
|
||||
PAR_BEGIN=6
|
||||
PAR_END=7
|
||||
COMMA=8
|
||||
SIMPLETYPE=9
|
||||
IDENTIFIER=10
|
||||
NUMBER=11
|
||||
DEFINE=12
|
||||
DEFINE_CONTINUE=13
|
||||
WHITESPACE=14
|
||||
';'=1
|
||||
'('=2
|
||||
')'=3
|
||||
'*'=4
|
||||
'/'=5
|
||||
'+'=6
|
||||
'-'=7
|
||||
'#define'=11
|
||||
'\\\n'=12
|
||||
'*'=2
|
||||
'/'=3
|
||||
'+'=4
|
||||
'-'=5
|
||||
'('=6
|
||||
')'=7
|
||||
','=8
|
||||
'#define'=12
|
||||
'\\\n'=13
|
||||
|
@ -1,12 +1,13 @@
|
||||
token literal names:
|
||||
null
|
||||
';'
|
||||
'('
|
||||
')'
|
||||
'*'
|
||||
'/'
|
||||
'+'
|
||||
'-'
|
||||
'('
|
||||
')'
|
||||
','
|
||||
null
|
||||
null
|
||||
null
|
||||
@ -21,8 +22,9 @@ null
|
||||
null
|
||||
null
|
||||
null
|
||||
null
|
||||
null
|
||||
PAR_BEGIN
|
||||
PAR_END
|
||||
COMMA
|
||||
SIMPLETYPE
|
||||
IDENTIFIER
|
||||
NUMBER
|
||||
@ -36,8 +38,9 @@ T__1
|
||||
T__2
|
||||
T__3
|
||||
T__4
|
||||
T__5
|
||||
T__6
|
||||
PAR_BEGIN
|
||||
PAR_END
|
||||
COMMA
|
||||
SIMPLETYPE
|
||||
IDENTIFIER
|
||||
NUMBER
|
||||
@ -53,4 +56,4 @@ mode names:
|
||||
DEFAULT_MODE
|
||||
|
||||
atn:
|
||||
[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 15, 80, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 51, 10, 9, 3, 10, 6, 10, 54, 10, 10, 13, 10, 14, 10, 55, 3, 11, 6, 11, 59, 10, 11, 13, 11, 14, 11, 60, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 14, 6, 14, 75, 10, 14, 13, 14, 14, 14, 76, 3, 14, 3, 14, 2, 2, 15, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 3, 2, 5, 5, 2, 67, 92, 97, 97, 99, 124, 3, 2, 50, 59, 5, 2, 11, 12, 15, 15, 34, 34, 2, 83, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 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, 3, 29, 3, 2, 2, 2, 5, 31, 3, 2, 2, 2, 7, 33, 3, 2, 2, 2, 9, 35, 3, 2, 2, 2, 11, 37, 3, 2, 2, 2, 13, 39, 3, 2, 2, 2, 15, 41, 3, 2, 2, 2, 17, 50, 3, 2, 2, 2, 19, 53, 3, 2, 2, 2, 21, 58, 3, 2, 2, 2, 23, 62, 3, 2, 2, 2, 25, 70, 3, 2, 2, 2, 27, 74, 3, 2, 2, 2, 29, 30, 7, 61, 2, 2, 30, 4, 3, 2, 2, 2, 31, 32, 7, 42, 2, 2, 32, 6, 3, 2, 2, 2, 33, 34, 7, 43, 2, 2, 34, 8, 3, 2, 2, 2, 35, 36, 7, 44, 2, 2, 36, 10, 3, 2, 2, 2, 37, 38, 7, 49, 2, 2, 38, 12, 3, 2, 2, 2, 39, 40, 7, 45, 2, 2, 40, 14, 3, 2, 2, 2, 41, 42, 7, 47, 2, 2, 42, 16, 3, 2, 2, 2, 43, 44, 7, 101, 2, 2, 44, 45, 7, 106, 2, 2, 45, 46, 7, 99, 2, 2, 46, 51, 7, 116, 2, 2, 47, 48, 7, 107, 2, 2, 48, 49, 7, 112, 2, 2, 49, 51, 7, 118, 2, 2, 50, 43, 3, 2, 2, 2, 50, 47, 3, 2, 2, 2, 51, 18, 3, 2, 2, 2, 52, 54, 9, 2, 2, 2, 53, 52, 3, 2, 2, 2, 54, 55, 3, 2, 2, 2, 55, 53, 3, 2, 2, 2, 55, 56, 3, 2, 2, 2, 56, 20, 3, 2, 2, 2, 57, 59, 9, 3, 2, 2, 58, 57, 3, 2, 2, 2, 59, 60, 3, 2, 2, 2, 60, 58, 3, 2, 2, 2, 60, 61, 3, 2, 2, 2, 61, 22, 3, 2, 2, 2, 62, 63, 7, 37, 2, 2, 63, 64, 7, 102, 2, 2, 64, 65, 7, 103, 2, 2, 65, 66, 7, 104, 2, 2, 66, 67, 7, 107, 2, 2, 67, 68, 7, 112, 2, 2, 68, 69, 7, 103, 2, 2, 69, 24, 3, 2, 2, 2, 70, 71, 7, 94, 2, 2, 71, 72, 7, 12, 2, 2, 72, 26, 3, 2, 2, 2, 73, 75, 9, 4, 2, 2, 74, 73, 3, 2, 2, 2, 75, 76, 3, 2, 2, 2, 76, 74, 3, 2, 2, 2, 76, 77, 3, 2, 2, 2, 77, 78, 3, 2, 2, 2, 78, 79, 8, 14, 2, 2, 79, 28, 3, 2, 2, 2, 7, 2, 50, 55, 60, 76, 3, 2, 3, 2]
|
||||
[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 16, 84, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 5, 10, 55, 10, 10, 3, 11, 6, 11, 58, 10, 11, 13, 11, 14, 11, 59, 3, 12, 6, 12, 63, 10, 12, 13, 12, 14, 12, 64, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 3, 15, 6, 15, 79, 10, 15, 13, 15, 14, 15, 80, 3, 15, 3, 15, 2, 2, 16, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 3, 2, 5, 5, 2, 67, 92, 97, 97, 99, 124, 3, 2, 50, 59, 5, 2, 11, 12, 15, 15, 34, 34, 2, 87, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 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, 29, 3, 2, 2, 2, 3, 31, 3, 2, 2, 2, 5, 33, 3, 2, 2, 2, 7, 35, 3, 2, 2, 2, 9, 37, 3, 2, 2, 2, 11, 39, 3, 2, 2, 2, 13, 41, 3, 2, 2, 2, 15, 43, 3, 2, 2, 2, 17, 45, 3, 2, 2, 2, 19, 54, 3, 2, 2, 2, 21, 57, 3, 2, 2, 2, 23, 62, 3, 2, 2, 2, 25, 66, 3, 2, 2, 2, 27, 74, 3, 2, 2, 2, 29, 78, 3, 2, 2, 2, 31, 32, 7, 61, 2, 2, 32, 4, 3, 2, 2, 2, 33, 34, 7, 44, 2, 2, 34, 6, 3, 2, 2, 2, 35, 36, 7, 49, 2, 2, 36, 8, 3, 2, 2, 2, 37, 38, 7, 45, 2, 2, 38, 10, 3, 2, 2, 2, 39, 40, 7, 47, 2, 2, 40, 12, 3, 2, 2, 2, 41, 42, 7, 42, 2, 2, 42, 14, 3, 2, 2, 2, 43, 44, 7, 43, 2, 2, 44, 16, 3, 2, 2, 2, 45, 46, 7, 46, 2, 2, 46, 18, 3, 2, 2, 2, 47, 48, 7, 101, 2, 2, 48, 49, 7, 106, 2, 2, 49, 50, 7, 99, 2, 2, 50, 55, 7, 116, 2, 2, 51, 52, 7, 107, 2, 2, 52, 53, 7, 112, 2, 2, 53, 55, 7, 118, 2, 2, 54, 47, 3, 2, 2, 2, 54, 51, 3, 2, 2, 2, 55, 20, 3, 2, 2, 2, 56, 58, 9, 2, 2, 2, 57, 56, 3, 2, 2, 2, 58, 59, 3, 2, 2, 2, 59, 57, 3, 2, 2, 2, 59, 60, 3, 2, 2, 2, 60, 22, 3, 2, 2, 2, 61, 63, 9, 3, 2, 2, 62, 61, 3, 2, 2, 2, 63, 64, 3, 2, 2, 2, 64, 62, 3, 2, 2, 2, 64, 65, 3, 2, 2, 2, 65, 24, 3, 2, 2, 2, 66, 67, 7, 37, 2, 2, 67, 68, 7, 102, 2, 2, 68, 69, 7, 103, 2, 2, 69, 70, 7, 104, 2, 2, 70, 71, 7, 107, 2, 2, 71, 72, 7, 112, 2, 2, 72, 73, 7, 103, 2, 2, 73, 26, 3, 2, 2, 2, 74, 75, 7, 94, 2, 2, 75, 76, 7, 12, 2, 2, 76, 28, 3, 2, 2, 2, 77, 79, 9, 4, 2, 2, 78, 77, 3, 2, 2, 2, 79, 80, 3, 2, 2, 2, 80, 78, 3, 2, 2, 2, 80, 81, 3, 2, 2, 2, 81, 82, 3, 2, 2, 2, 82, 83, 8, 15, 2, 2, 83, 30, 3, 2, 2, 2, 7, 2, 54, 59, 64, 80, 3, 2, 3, 2]
|
@ -19,8 +19,9 @@ public class MacrosLexer extends Lexer {
|
||||
protected static final PredictionContextCache _sharedContextCache =
|
||||
new PredictionContextCache();
|
||||
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, SIMPLETYPE=8,
|
||||
IDENTIFIER=9, NUMBER=10, DEFINE=11, DEFINE_CONTINUE=12, WHITESPACE=13;
|
||||
T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, PAR_BEGIN=6, PAR_END=7, COMMA=8,
|
||||
SIMPLETYPE=9, IDENTIFIER=10, NUMBER=11, DEFINE=12, DEFINE_CONTINUE=13,
|
||||
WHITESPACE=14;
|
||||
public static String[] channelNames = {
|
||||
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
|
||||
};
|
||||
@ -31,23 +32,23 @@ public class MacrosLexer extends Lexer {
|
||||
|
||||
private static String[] makeRuleNames() {
|
||||
return new String[] {
|
||||
"T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "SIMPLETYPE",
|
||||
"IDENTIFIER", "NUMBER", "DEFINE", "DEFINE_CONTINUE", "WHITESPACE"
|
||||
"T__0", "T__1", "T__2", "T__3", "T__4", "PAR_BEGIN", "PAR_END", "COMMA",
|
||||
"SIMPLETYPE", "IDENTIFIER", "NUMBER", "DEFINE", "DEFINE_CONTINUE", "WHITESPACE"
|
||||
};
|
||||
}
|
||||
public static final String[] ruleNames = makeRuleNames();
|
||||
|
||||
private static String[] makeLiteralNames() {
|
||||
return new String[] {
|
||||
null, "';'", "'('", "')'", "'*'", "'/'", "'+'", "'-'", null, null, null,
|
||||
"'#define'", "'\\\n'"
|
||||
null, "';'", "'*'", "'/'", "'+'", "'-'", "'('", "')'", "','", null, null,
|
||||
null, "'#define'", "'\\\n'"
|
||||
};
|
||||
}
|
||||
private static final String[] _LITERAL_NAMES = makeLiteralNames();
|
||||
private static String[] makeSymbolicNames() {
|
||||
return new String[] {
|
||||
null, null, null, null, null, null, null, null, "SIMPLETYPE", "IDENTIFIER",
|
||||
"NUMBER", "DEFINE", "DEFINE_CONTINUE", "WHITESPACE"
|
||||
null, null, null, null, null, null, "PAR_BEGIN", "PAR_END", "COMMA",
|
||||
"SIMPLETYPE", "IDENTIFIER", "NUMBER", "DEFINE", "DEFINE_CONTINUE", "WHITESPACE"
|
||||
};
|
||||
}
|
||||
private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
|
||||
@ -111,28 +112,28 @@ public class MacrosLexer extends Lexer {
|
||||
public ATN getATN() { return _ATN; }
|
||||
|
||||
public static final String _serializedATN =
|
||||
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\17P\b\1\4\2\t\2\4"+
|
||||
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\20T\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\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6"+
|
||||
"\3\7\3\7\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\t\3\t\5\t\63\n\t\3\n\6\n\66\n\n"+
|
||||
"\r\n\16\n\67\3\13\6\13;\n\13\r\13\16\13<\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3"+
|
||||
"\f\3\r\3\r\3\r\3\16\6\16K\n\16\r\16\16\16L\3\16\3\16\2\2\17\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\3\2\5\5\2C\\aac"+
|
||||
"|\3\2\62;\5\2\13\f\17\17\"\"\2S\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\3\35\3\2\2\2"+
|
||||
"\5\37\3\2\2\2\7!\3\2\2\2\t#\3\2\2\2\13%\3\2\2\2\r\'\3\2\2\2\17)\3\2\2"+
|
||||
"\2\21\62\3\2\2\2\23\65\3\2\2\2\25:\3\2\2\2\27>\3\2\2\2\31F\3\2\2\2\33"+
|
||||
"J\3\2\2\2\35\36\7=\2\2\36\4\3\2\2\2\37 \7*\2\2 \6\3\2\2\2!\"\7+\2\2\""+
|
||||
"\b\3\2\2\2#$\7,\2\2$\n\3\2\2\2%&\7\61\2\2&\f\3\2\2\2\'(\7-\2\2(\16\3\2"+
|
||||
"\2\2)*\7/\2\2*\20\3\2\2\2+,\7e\2\2,-\7j\2\2-.\7c\2\2.\63\7t\2\2/\60\7"+
|
||||
"k\2\2\60\61\7p\2\2\61\63\7v\2\2\62+\3\2\2\2\62/\3\2\2\2\63\22\3\2\2\2"+
|
||||
"\64\66\t\2\2\2\65\64\3\2\2\2\66\67\3\2\2\2\67\65\3\2\2\2\678\3\2\2\28"+
|
||||
"\24\3\2\2\29;\t\3\2\2:9\3\2\2\2;<\3\2\2\2<:\3\2\2\2<=\3\2\2\2=\26\3\2"+
|
||||
"\2\2>?\7%\2\2?@\7f\2\2@A\7g\2\2AB\7h\2\2BC\7k\2\2CD\7p\2\2DE\7g\2\2E\30"+
|
||||
"\3\2\2\2FG\7^\2\2GH\7\f\2\2H\32\3\2\2\2IK\t\4\2\2JI\3\2\2\2KL\3\2\2\2"+
|
||||
"LJ\3\2\2\2LM\3\2\2\2MN\3\2\2\2NO\b\16\2\2O\34\3\2\2\2\7\2\62\67<L\3\2"+
|
||||
"\3\2";
|
||||
"\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3"+
|
||||
"\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3\n\3\n\5\n\67"+
|
||||
"\n\n\3\13\6\13:\n\13\r\13\16\13;\3\f\6\f?\n\f\r\f\16\f@\3\r\3\r\3\r\3"+
|
||||
"\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3\17\6\17O\n\17\r\17\16\17P\3\17\3\17"+
|
||||
"\2\2\20\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\3\2\5\5\2C\\aac|\3\2\62;\5\2\13\f\17\17\"\"\2W\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\3\37\3\2\2\2\5!\3\2\2\2\7#\3\2\2\2\t%\3\2\2\2\13"+
|
||||
"\'\3\2\2\2\r)\3\2\2\2\17+\3\2\2\2\21-\3\2\2\2\23\66\3\2\2\2\259\3\2\2"+
|
||||
"\2\27>\3\2\2\2\31B\3\2\2\2\33J\3\2\2\2\35N\3\2\2\2\37 \7=\2\2 \4\3\2\2"+
|
||||
"\2!\"\7,\2\2\"\6\3\2\2\2#$\7\61\2\2$\b\3\2\2\2%&\7-\2\2&\n\3\2\2\2\'("+
|
||||
"\7/\2\2(\f\3\2\2\2)*\7*\2\2*\16\3\2\2\2+,\7+\2\2,\20\3\2\2\2-.\7.\2\2"+
|
||||
".\22\3\2\2\2/\60\7e\2\2\60\61\7j\2\2\61\62\7c\2\2\62\67\7t\2\2\63\64\7"+
|
||||
"k\2\2\64\65\7p\2\2\65\67\7v\2\2\66/\3\2\2\2\66\63\3\2\2\2\67\24\3\2\2"+
|
||||
"\28:\t\2\2\298\3\2\2\2:;\3\2\2\2;9\3\2\2\2;<\3\2\2\2<\26\3\2\2\2=?\t\3"+
|
||||
"\2\2>=\3\2\2\2?@\3\2\2\2@>\3\2\2\2@A\3\2\2\2A\30\3\2\2\2BC\7%\2\2CD\7"+
|
||||
"f\2\2DE\7g\2\2EF\7h\2\2FG\7k\2\2GH\7p\2\2HI\7g\2\2I\32\3\2\2\2JK\7^\2"+
|
||||
"\2KL\7\f\2\2L\34\3\2\2\2MO\t\4\2\2NM\3\2\2\2OP\3\2\2\2PN\3\2\2\2PQ\3\2"+
|
||||
"\2\2QR\3\2\2\2RS\b\17\2\2S\36\3\2\2\2\7\2\66;@P\3\2\3\2";
|
||||
public static final ATN _ATN =
|
||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||
static {
|
||||
|
@ -3,20 +3,22 @@ T__1=2
|
||||
T__2=3
|
||||
T__3=4
|
||||
T__4=5
|
||||
T__5=6
|
||||
T__6=7
|
||||
SIMPLETYPE=8
|
||||
IDENTIFIER=9
|
||||
NUMBER=10
|
||||
DEFINE=11
|
||||
DEFINE_CONTINUE=12
|
||||
WHITESPACE=13
|
||||
PAR_BEGIN=6
|
||||
PAR_END=7
|
||||
COMMA=8
|
||||
SIMPLETYPE=9
|
||||
IDENTIFIER=10
|
||||
NUMBER=11
|
||||
DEFINE=12
|
||||
DEFINE_CONTINUE=13
|
||||
WHITESPACE=14
|
||||
';'=1
|
||||
'('=2
|
||||
')'=3
|
||||
'*'=4
|
||||
'/'=5
|
||||
'+'=6
|
||||
'-'=7
|
||||
'#define'=11
|
||||
'\\\n'=12
|
||||
'*'=2
|
||||
'/'=3
|
||||
'+'=4
|
||||
'-'=5
|
||||
'('=6
|
||||
')'=7
|
||||
','=8
|
||||
'#define'=12
|
||||
'\\\n'=13
|
||||
|
@ -19,8 +19,9 @@ public class MacrosParser extends Parser {
|
||||
protected static final PredictionContextCache _sharedContextCache =
|
||||
new PredictionContextCache();
|
||||
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, SIMPLETYPE=8,
|
||||
IDENTIFIER=9, NUMBER=10, DEFINE=11, DEFINE_CONTINUE=12, WHITESPACE=13;
|
||||
T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, PAR_BEGIN=6, PAR_END=7, COMMA=8,
|
||||
SIMPLETYPE=9, IDENTIFIER=10, NUMBER=11, DEFINE=12, DEFINE_CONTINUE=13,
|
||||
WHITESPACE=14;
|
||||
public static final int
|
||||
RULE_stmtSeq = 0, RULE_stmt = 1, RULE_expr = 2;
|
||||
private static String[] makeRuleNames() {
|
||||
@ -32,15 +33,15 @@ public class MacrosParser extends Parser {
|
||||
|
||||
private static String[] makeLiteralNames() {
|
||||
return new String[] {
|
||||
null, "';'", "'('", "')'", "'*'", "'/'", "'+'", "'-'", null, null, null,
|
||||
"'#define'", "'\\\n'"
|
||||
null, "';'", "'*'", "'/'", "'+'", "'-'", "'('", "')'", "','", null, null,
|
||||
null, "'#define'", "'\\\n'"
|
||||
};
|
||||
}
|
||||
private static final String[] _LITERAL_NAMES = makeLiteralNames();
|
||||
private static String[] makeSymbolicNames() {
|
||||
return new String[] {
|
||||
null, null, null, null, null, null, null, null, "SIMPLETYPE", "IDENTIFIER",
|
||||
"NUMBER", "DEFINE", "DEFINE_CONTINUE", "WHITESPACE"
|
||||
null, null, null, null, null, null, "PAR_BEGIN", "PAR_END", "COMMA",
|
||||
"SIMPLETYPE", "IDENTIFIER", "NUMBER", "DEFINE", "DEFINE_CONTINUE", "WHITESPACE"
|
||||
};
|
||||
}
|
||||
private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
|
||||
@ -132,7 +133,7 @@ public class MacrosParser extends Parser {
|
||||
setState(9);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__1) | (1L << IDENTIFIER) | (1L << NUMBER))) != 0)) {
|
||||
while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << PAR_BEGIN) | (1L << IDENTIFIER) | (1L << NUMBER))) != 0)) {
|
||||
{
|
||||
{
|
||||
setState(6);
|
||||
@ -223,7 +224,9 @@ public class MacrosParser extends Parser {
|
||||
}
|
||||
}
|
||||
public static class ExprCastContext extends ExprContext {
|
||||
public TerminalNode PAR_BEGIN() { return getToken(MacrosParser.PAR_BEGIN, 0); }
|
||||
public TerminalNode SIMPLETYPE() { return getToken(MacrosParser.SIMPLETYPE, 0); }
|
||||
public TerminalNode PAR_END() { return getToken(MacrosParser.PAR_END, 0); }
|
||||
public ExprContext expr() {
|
||||
return getRuleContext(ExprContext.class,0);
|
||||
}
|
||||
@ -249,6 +252,7 @@ public class MacrosParser extends Parser {
|
||||
public ExprContext expr(int i) {
|
||||
return getRuleContext(ExprContext.class,i);
|
||||
}
|
||||
public TerminalNode COMMA() { return getToken(MacrosParser.COMMA, 0); }
|
||||
public ExprBinaryContext(ExprContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
@ -265,9 +269,11 @@ public class MacrosParser extends Parser {
|
||||
}
|
||||
}
|
||||
public static class ExprParContext extends ExprContext {
|
||||
public TerminalNode PAR_BEGIN() { return getToken(MacrosParser.PAR_BEGIN, 0); }
|
||||
public ExprContext expr() {
|
||||
return getRuleContext(ExprContext.class,0);
|
||||
}
|
||||
public TerminalNode PAR_END() { return getToken(MacrosParser.PAR_END, 0); }
|
||||
public ExprParContext(ExprContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
@ -343,13 +349,13 @@ public class MacrosParser extends Parser {
|
||||
_prevctx = _localctx;
|
||||
|
||||
setState(16);
|
||||
match(T__1);
|
||||
match(PAR_BEGIN);
|
||||
setState(17);
|
||||
match(SIMPLETYPE);
|
||||
setState(18);
|
||||
match(T__2);
|
||||
match(PAR_END);
|
||||
setState(19);
|
||||
expr(8);
|
||||
expr(9);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
@ -376,16 +382,16 @@ public class MacrosParser extends Parser {
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(22);
|
||||
match(T__1);
|
||||
match(PAR_BEGIN);
|
||||
setState(23);
|
||||
expr(0);
|
||||
setState(24);
|
||||
match(T__2);
|
||||
match(PAR_END);
|
||||
}
|
||||
break;
|
||||
}
|
||||
_ctx.stop = _input.LT(-1);
|
||||
setState(42);
|
||||
setState(45);
|
||||
_errHandler.sync(this);
|
||||
_alt = getInterpreter().adaptivePredict(_input,3,_ctx);
|
||||
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
|
||||
@ -393,7 +399,7 @@ public class MacrosParser extends Parser {
|
||||
if ( _parseListeners!=null ) triggerExitRuleEvent();
|
||||
_prevctx = _localctx;
|
||||
{
|
||||
setState(40);
|
||||
setState(43);
|
||||
_errHandler.sync(this);
|
||||
switch ( getInterpreter().adaptivePredict(_input,2,_ctx) ) {
|
||||
case 1:
|
||||
@ -401,11 +407,11 @@ public class MacrosParser extends Parser {
|
||||
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_expr);
|
||||
setState(28);
|
||||
if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)");
|
||||
if (!(precpred(_ctx, 5))) throw new FailedPredicateException(this, "precpred(_ctx, 5)");
|
||||
setState(29);
|
||||
match(T__3);
|
||||
match(T__1);
|
||||
setState(30);
|
||||
expr(5);
|
||||
expr(6);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
@ -413,11 +419,11 @@ public class MacrosParser extends Parser {
|
||||
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_expr);
|
||||
setState(31);
|
||||
if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)");
|
||||
if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)");
|
||||
setState(32);
|
||||
match(T__4);
|
||||
match(T__2);
|
||||
setState(33);
|
||||
expr(4);
|
||||
expr(5);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
@ -425,11 +431,11 @@ public class MacrosParser extends Parser {
|
||||
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_expr);
|
||||
setState(34);
|
||||
if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)");
|
||||
if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)");
|
||||
setState(35);
|
||||
match(T__5);
|
||||
match(T__3);
|
||||
setState(36);
|
||||
expr(3);
|
||||
expr(4);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
@ -437,17 +443,29 @@ public class MacrosParser extends Parser {
|
||||
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_expr);
|
||||
setState(37);
|
||||
if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
|
||||
if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)");
|
||||
setState(38);
|
||||
match(T__6);
|
||||
match(T__4);
|
||||
setState(39);
|
||||
expr(3);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
{
|
||||
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_expr);
|
||||
setState(40);
|
||||
if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
|
||||
setState(41);
|
||||
match(COMMA);
|
||||
setState(42);
|
||||
expr(2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
setState(44);
|
||||
setState(47);
|
||||
_errHandler.sync(this);
|
||||
_alt = getInterpreter().adaptivePredict(_input,3,_ctx);
|
||||
}
|
||||
@ -474,31 +492,34 @@ public class MacrosParser extends Parser {
|
||||
private boolean expr_sempred(ExprContext _localctx, int predIndex) {
|
||||
switch (predIndex) {
|
||||
case 0:
|
||||
return precpred(_ctx, 4);
|
||||
return precpred(_ctx, 5);
|
||||
case 1:
|
||||
return precpred(_ctx, 3);
|
||||
return precpred(_ctx, 4);
|
||||
case 2:
|
||||
return precpred(_ctx, 2);
|
||||
return precpred(_ctx, 3);
|
||||
case 3:
|
||||
return precpred(_ctx, 2);
|
||||
case 4:
|
||||
return precpred(_ctx, 1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static final String _serializedATN =
|
||||
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\17\60\4\2\t\2\4\3"+
|
||||
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\20\63\4\2\t\2\4\3"+
|
||||
"\t\3\4\4\t\4\3\2\7\2\n\n\2\f\2\16\2\r\13\2\3\3\3\3\3\3\3\4\3\4\3\4\3\4"+
|
||||
"\3\4\3\4\3\4\3\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\3\4\7\4+\n\4\f\4\16\4.\13\4\3\4\2\3\6\5\2\4\6\2\2\2\64"+
|
||||
"\2\13\3\2\2\2\4\16\3\2\2\2\6\34\3\2\2\2\b\n\5\4\3\2\t\b\3\2\2\2\n\r\3"+
|
||||
"\2\2\2\13\t\3\2\2\2\13\f\3\2\2\2\f\3\3\2\2\2\r\13\3\2\2\2\16\17\5\6\4"+
|
||||
"\2\17\20\7\3\2\2\20\5\3\2\2\2\21\22\b\4\1\2\22\23\7\4\2\2\23\24\7\n\2"+
|
||||
"\2\24\25\7\5\2\2\25\35\5\6\4\n\26\35\7\13\2\2\27\35\7\f\2\2\30\31\7\4"+
|
||||
"\2\2\31\32\5\6\4\2\32\33\7\5\2\2\33\35\3\2\2\2\34\21\3\2\2\2\34\26\3\2"+
|
||||
"\2\2\34\27\3\2\2\2\34\30\3\2\2\2\35,\3\2\2\2\36\37\f\6\2\2\37 \7\6\2\2"+
|
||||
" +\5\6\4\7!\"\f\5\2\2\"#\7\7\2\2#+\5\6\4\6$%\f\4\2\2%&\7\b\2\2&+\5\6\4"+
|
||||
"\5\'(\f\3\2\2()\7\t\2\2)+\5\6\4\4*\36\3\2\2\2*!\3\2\2\2*$\3\2\2\2*\'\3"+
|
||||
"\2\2\2+.\3\2\2\2,*\3\2\2\2,-\3\2\2\2-\7\3\2\2\2.,\3\2\2\2\6\13\34*,";
|
||||
"\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\7\4.\n\4\f\4\16\4\61\13\4\3\4\2\3\6\5\2"+
|
||||
"\4\6\2\2\28\2\13\3\2\2\2\4\16\3\2\2\2\6\34\3\2\2\2\b\n\5\4\3\2\t\b\3\2"+
|
||||
"\2\2\n\r\3\2\2\2\13\t\3\2\2\2\13\f\3\2\2\2\f\3\3\2\2\2\r\13\3\2\2\2\16"+
|
||||
"\17\5\6\4\2\17\20\7\3\2\2\20\5\3\2\2\2\21\22\b\4\1\2\22\23\7\b\2\2\23"+
|
||||
"\24\7\13\2\2\24\25\7\t\2\2\25\35\5\6\4\13\26\35\7\f\2\2\27\35\7\r\2\2"+
|
||||
"\30\31\7\b\2\2\31\32\5\6\4\2\32\33\7\t\2\2\33\35\3\2\2\2\34\21\3\2\2\2"+
|
||||
"\34\26\3\2\2\2\34\27\3\2\2\2\34\30\3\2\2\2\35/\3\2\2\2\36\37\f\7\2\2\37"+
|
||||
" \7\4\2\2 .\5\6\4\b!\"\f\6\2\2\"#\7\5\2\2#.\5\6\4\7$%\f\5\2\2%&\7\6\2"+
|
||||
"\2&.\5\6\4\6\'(\f\4\2\2()\7\7\2\2).\5\6\4\5*+\f\3\2\2+,\7\n\2\2,.\5\6"+
|
||||
"\4\4-\36\3\2\2\2-!\3\2\2\2-$\3\2\2\2-\'\3\2\2\2-*\3\2\2\2.\61\3\2\2\2"+
|
||||
"/-\3\2\2\2/\60\3\2\2\2\60\7\3\2\2\2\61/\3\2\2\2\6\13\34-/";
|
||||
public static final ATN _ATN =
|
||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||
static {
|
||||
|
@ -7,7 +7,6 @@ import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
|
||||
public class TestMacrosParser {
|
||||
|
||||
private int CHANNEL_WHITESPACE = 1;
|
||||
@ -16,7 +15,7 @@ public class TestMacrosParser {
|
||||
* Test some parsing without macros
|
||||
*/
|
||||
@Test
|
||||
public void testParserSimple() {
|
||||
public void testParser() {
|
||||
// Simple addition
|
||||
assertEquals("+(name:a,num:7);", parse("a+7;"));
|
||||
// Addition & multiplication
|
||||
@ -30,10 +29,10 @@ public class TestMacrosParser {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parsing with simple defines
|
||||
* Test some simple defines
|
||||
*/
|
||||
@Test
|
||||
public void testParserDefine() {
|
||||
public void testSimpleDefine() {
|
||||
// A simple unused define
|
||||
assertEquals("+(name:b,num:1);*(name:c,num:2);", parse("#define A a\nb+1;\nc*2;\n"));
|
||||
// A simple used define
|
||||
@ -44,6 +43,46 @@ public class TestMacrosParser {
|
||||
assertEquals("+(name:a,num:1);", parse("#define A a+\nA 1;"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test define where the body uses another define
|
||||
*/
|
||||
@Test
|
||||
public void testDefineSub() {
|
||||
// A uses B
|
||||
assertEquals("+(*(name:c,num:2),num:1);", parse("#define A B+1\n#define B c*2\nA;"));
|
||||
// A uses B uses C
|
||||
assertEquals("+(*(name:c,num:2),name:c);", parse("#define A B+C\n#define B C*2\n#define C c\nA;"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test define with recursion
|
||||
*/
|
||||
@Test
|
||||
public void testDefineRecursion() {
|
||||
// A uses A
|
||||
assertEquals("+(name:A,num:1);", parse("#define A A+1\nA;"));
|
||||
// A uses B uses A
|
||||
assertEquals("+(*(name:A,num:2),num:1);+(name:B,*(num:1,num:2));", parse("#define A B+1\n#define B A*2\nA;B;"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test define with multi-line body
|
||||
*/
|
||||
@Test
|
||||
public void testDefineMultiline() {
|
||||
// A simple unused define
|
||||
assertEquals("name:a;+(name:b,num:1);", parse("#define A a;\\\nb\nA+1;"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test define with parameters
|
||||
*/
|
||||
//@Test
|
||||
//public void testDefineParams() {
|
||||
// // A simple unused define
|
||||
// assertEquals("+(name:b,num:1);*(name:c,num:2);", parse("#define A(a) a+1\nA(b)"));
|
||||
//}
|
||||
|
||||
/**
|
||||
* Parse a program with macros and return the resulting syntax tree
|
||||
*
|
||||
@ -67,7 +106,7 @@ public class TestMacrosParser {
|
||||
}
|
||||
});
|
||||
|
||||
final CMacroExpander cMacroExpander = new CMacroExpander(CHANNEL_WHITESPACE, MacrosLexer.WHITESPACE, MacrosLexer.DEFINE, MacrosLexer.IDENTIFIER);
|
||||
final CMacroExpander cMacroExpander = new CMacroExpander(CHANNEL_WHITESPACE, MacrosLexer.WHITESPACE, MacrosLexer.DEFINE, MacrosLexer.IDENTIFIER, MacrosLexer.PAR_BEGIN, MacrosLexer.PAR_END, MacrosLexer.COMMA, MacrosLexer.DEFINE_CONTINUE);
|
||||
final TokenSource expandedTokenSource = cMacroExpander.expandMacros(lexer);
|
||||
MacrosParser parser = new MacrosParser(new CommonTokenStream(expandedTokenSource));
|
||||
parser.setBuildParseTree(true);
|
||||
|
Loading…
Reference in New Issue
Block a user