📄 nescparser.g
字号:
configuration
{
## = #( popCurrentFileAST(), ## );
}
;
//******
// Module file
moduleFile
:
{
// create the NModuleFile node now, so that the ASTs
// of the include files can be attached to it an attribute
TNode newRoot = #[NModuleFile];
ArrayList includeFileASTs = new ArrayList();
newRoot.setAttribute("includeFileASTs", includeFileASTs);
pushCurrentFileAST(newRoot);
/*
// parse tos.h if it hasn't been parsed beforeee
String inputFileName = "tos.h";
if(!getParserContext().getProcessedIncludes().containsKey(inputFileName)) {
try {
// parse include file
AST includeFileAST = parseIncludeFile(inputFileName);
// add its AST to the includeFileASTs attribute of the nesC file from where
// this include was included
includeFileASTs.add(includeFileAST);
} catch (java.io.FileNotFoundException e) {
// print File not found
System.err.println("Include file not found: " + inputFileName);
e.printStackTrace(System.err);
}
}
*/
}
(includes)*
module
{
## = #( popCurrentFileAST(), ## );
// ## = #( #[NModuleFile], ## );
}
;
module
: "module"^ m:ID
interfaceDescription
moduleImplementation
{ ##.setType(NModule); }
;
configuration
: "configuration"^ c:ID
interfaceDescription
configurationImplementation
{ ##.setType(NConfiguration); }
;
interfaceDescription
: LCURLY^
(
uses
| provides
)*
RCURLY
{ ##.setType(NInterfaceDescription); }
;
uses
: "uses"^
interfaceDescriptionItemList
{ ##.setType(NUses); }
;
provides
: "provides"^
interfaceDescriptionItemList
{ ##.setType(NProvides); }
;
interfaceDescriptionItemList
: interfaceDescriptionItem
| LCURLY (interfaceDescriptionItem)+ RCURLY
;
interfaceDescriptionItem
: declaration
| "interface" /*{ ## = #( #[NInterface], ## ); }*/
interfaceIdentifier (interfaceParameters)? (SEMI!)+
;
interfaceIdentifier
: i:ID^ ("as" r:ID)?
{
String inputFileName = i.getText()+".nc";
AST interfaceFileAST = null;
ParserMessage container = new ParserMessage(ParserMessage.INFO, "Interface file: "+inputFileName, new CodeLocation((CToken)i), null);
getParserContext().addMsg(container);
getParserContext().pushMessages(container);
try {
interfaceFileAST = getParserContext().getAST(inputFileName);
// add its AST as an attribute to the file name ID node
##.setAttribute("interfaceFileAST", interfaceFileAST);
} catch(ParserMessage m) {
getParserContext().addMsg(m);
} finally {
getParserContext().popMessages();
}
}
;
interfaceParameters
: LBRACKET parameterTypeList RBRACKET
;
moduleImplementation
: "implementation"^
LCURLY externalList RCURLY
{ ##.setType(NImplementation); }
;
configurationImplementation
: "implementation"^
LCURLY
(componentList)*
connectionList
RCURLY
{ ##.setType(NImplementation); }
;
componentList
: "components"^
aliasedComponentName (COMMA! aliasedComponentName)*
(SEMI)+
{ ##.setType(NComponentList); }
;
aliasedComponentName
:
i:ID
{
String inputFileName = i.getText()+".nc";
AST componentFileAST = null;
ParserMessage container = new ParserMessage(ParserMessage.INFO, "Component file: "+inputFileName, new CodeLocation((CToken)i), null);
getParserContext().addMsg(container);
getParserContext().pushMessages(container);
try {
componentFileAST = getParserContext().getAST(inputFileName);
##.setAttribute("componentFileAST", componentFileAST);
} catch(ParserMessage m) {
getParserContext().addMsg(m);
} finally {
getParserContext().popMessages();
}
}
("as" ID)?
;
connectionList
: (
( (endpoint ASSIGN) => endpoint ASSIGN endpoint
| (endpoint PTR) => endpoint PTR endpoint
| endpoint BACKPTR endpoint
)
(SEMI)+
)*
{ ## = #( #[NConnectionList], ## ); }
;
endpoint
:
ID (DOT ID)* (interfaceParams)?
;
// we need to recognize InterfaceName.operation as a function name
declarator[boolean isFunctionDefinition] returns [String declName]
{ declName = ""; }
:
( pointerGroup )?
(
(
id:ID { declName = id.getText(); }
(DOT id2:ID { declName = declName + "." + id2.getText(); }
)?
)
| LPAREN declName = declarator[false] RPAREN
)
( {isFunctionDefinition}? (
(interfaceParameterList)?
declaratorParamaterList[isFunctionDefinition, declName]
)
|(
declaratorParamaterList[isFunctionDefinition, declName]
|LBRACKET ( expr )? RBRACKET
)*
)
{ ## = #( #[NDeclarator], ## ); }
;
interfaceParameterList:
(
LBRACKET^
(
(declSpecifiers)=> parameterTypeList
| (idList)?
)
RBRACKET { ##.setType(NInterfaceParameterList); }
)?
;
// we need to accept [uint8_t id] like interface parameters as funtion parameters
declaratorParamaterList[boolean isFunctionDefinition, String declName]
:
LPAREN^
{
if (isFunctionDefinition) {
pushScope(declName);
}
else {
pushScope("!"+declName);
}
}
(
(declSpecifiers)=> parameterTypeList
| (idList)?
)
{
popScope();
}
( COMMA! )?
RPAREN
{ ##.setType(NParameterTypeList); }
;
// catch atomic statements
statement
//{ System.out.println("NesCParser.statement called.");}
:
(
("atomic") => "atomic" gnuCStatement { // System.out.println("atomic keyword found.");
}
| gnuCStatement
)
;
// this is just the GnuCParser's statement renamed
gnuCStatement
: SEMI // Empty statements
| compoundStatement[getAScopeName()] // Group of statements
| expr SEMI! { ## = #( #[NStatementExpr], ## );} // Expressions
// Iteration statements:
| "while"^ LPAREN! expr RPAREN! statement
| "do"^ statement "while"! LPAREN! expr RPAREN! SEMI!
|! "for"
LPAREN ( e1:expr )? SEMI ( e2:expr )? SEMI ( e3:expr )? RPAREN
s:statement
{
if ( #e1 == null) { #e1 = #[ NEmptyExpression ]; }
if ( #e2 == null) { #e2 = #[ NEmptyExpression ]; }
if ( #e3 == null) { #e3 = #[ NEmptyExpression ]; }
## = #( #[LITERAL_for, "for"], #e1, #e2, #e3, #s );
}
// Jump statements:
| "goto"^ expr SEMI!
| "continue" SEMI!
| "break" SEMI!
| "return"^ ( expr )? SEMI!
| ID COLON! (options {warnWhenFollowAmbig=false;}: statement)? { ## = #( #[NLabel], ## ); }
// GNU allows range expressions in case statements
| "case"^ ((constExpr VARARGS)=> rangeExpr | constExpr) COLON! ( options{warnWhenFollowAmbig=false;}:statement )?
| "default"^ COLON! ( options{warnWhenFollowAmbig=false;}: statement )?
// Selection statements:
| "if"^
LPAREN! expr RPAREN! statement
( //standard if-else ambiguity
options {
warnWhenFollowAmbig = false;
} :
"else" statement )?
| "switch"^ LPAREN! expr RPAREN! statement
;
// add norace and volatile to storageClassSpecifier
storageClassSpecifier
: "auto"
| "register"
| "typedef"
| "norace"
| "volatile"
| functionStorageClassSpecifier
;
// add async, default, command, event and task
functionStorageClassSpecifier
: "extern"
| "static"
| "inline"
| "async"
| "default"
| "command"
| "event"
| "task"
;
// modified version of postfixExpr that allows for nesc call types
postfixExpr
: primaryExpr
(
postfixSuffix {## = #( #[NPostfixExpr], ## );}
)?
| ( "call" | "signal" ) ID (DOT ID)?
(interfaceParams
)?
(
functionCall {## = #( #[NPostfixExpr], ## );}
)
| "post" primaryExpr
(
functionCall {## = #( #[NPostfixExpr], ## );}
)
;
interfaceParams
:
LBRACKET^ (a:argExprList) RBRACKET
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -