Precise Details About Using The Ladebug Debugger
For that reason there is a wide variation in the level of information provided here under each sub-topic.
void loopForDebugger()
{
if (!getenv("loopForDebugger")) return;
static volatile int debuggerPresent = 0;
while (!debuggerPresent);
}
and call it at some convenient point.
When you have the process under debugger control, you will be able to assign
a non-zero value to debuggerPresent, and continue your program.
% setenv loopForDebugger ""
% a.out arg1 arg2 &
% ladebug -pid 1709 a.out
^C
(ladebug) assign debuggerPresent = 1
...
(ladebug) cont
/*% cc -g traceback.c -lexc
**% a.out
*/
struct exception_info; // To suppress compilation warnings from sym.h
#include
#include
#include
#include
#include
#include
static void printHeader(void)
{
printf("Diagnostic stack trace ...\n");
}
static void printTrailer(void)
{
printf("end of diagnostic stack trace.\n");
}
#define RETURNADDRREG (26)
#define FAULTING_ADDRESS sc_traparg_a0
extern unsigned long _procedure_string_table;
extern unsigned long _procedure_table_size;
extern unsigned long _procedure_table;
extern unsigned long _ftext; // Start address of the program text.
extern unsigned long _etext; // First address above the program text.
// Turn a PC into the name of the routine containing that PC.
//
char* programCounterToName(
unsigned long programCounter);
// Unwind the stack one level.
//
void unwindOneLevel(
struct sigcontext* unwindSignalContext,
void * runtimeProcedurePtr);
void printFrame(
void * rpdp,
unsigned long programCounter)
{
char* procedureName;
// Get the procedure name.
//
procedureName = programCounterToName(programCounter);
printf("%p %s\n",
(void* ) programCounter, procedureName ? procedureName : "");
}
char* programCounterToName(
unsigned long programCounter)
{
long int procedureTableSize;
char * procedureNameTable;
char * procedureName;
long int currentProcedure;
long int procedure;
pRPDR runTimePDPtr;
int found;
unsigned long int address;
found = 0;
procedureName = 0;
procedureTableSize = (long int)&_procedure_table_size;
procedureNameTable = (char *)&_procedure_string_table;
runTimePDPtr = (pRPDR)&_procedure_table;
// The table of run time procedure descriptors is ordered by
// procedure start address. Search the table (linearly) for the
// first procedure with a start address larger than the one for
// which we are looking.
//
for (currentProcedure = 0;
currentProcedure < procedureTableSize;
currentProcedure++) {
// Because of the way the linker builds the table we need to make
// special cases of the first and last entries. The linker uses 0
// for the address of the procedure in the first entry, here we
// substitute the start address of the text segment. The linker
// uses -1 for the address of the procedure in the last entry,
// here we substitute the end address of the text segment. For all
// other entries the procedure address is obtained from the table.
if (currentProcedure == 0) // first entry
address = (unsigned long int)&_ftext;
else if (currentProcedure == procedureTableSize - 1) // last entry
address = (unsigned long int)&_etext;
else // other entries
address = runTimePDPtr[currentProcedure].adr;
if (address > programCounter) {
if (currentProcedure != 0) {
// the PC is in this image
found = 1;
procedure = currentProcedure - 1; // the PC is in preceeding procedure
break; // stop searching
} else {
// the PC is outside this image (at a lower address)
break; // stop searching
}
}
}
if (found) {
// the PC is inside this image
procedureName = &procedureNameTable[runTimePDPtr[procedure].irpss];
} else {
// the PC is outside this image, probably in a different shared object
procedureName = 0;
}
return procedureName;
}
void unwindOneLevel(
struct sigcontext *unwindSignalContext,
void * runtimeProcedurePtr)
{
unwind(unwindSignalContext, (pdsc_crd *)runtimeProcedurePtr);
}
// Print a stack trace.
//
void printStackWkr(struct sigcontext *signalContextPtr)
{
struct sigcontext unwindSignalContext;
void *runTimeProcedurePtr;
unsigned long int stackpointer = 0;
unsigned long int programCounter = 0;
unsigned long int returnAddress = 0;
unsigned long int faultingAddress = 0;
printHeader();
// Set the initial context for the unwind.
//
unwindSignalContext = *signalContextPtr;
// Pick out the return address and program counter.
//
returnAddress = unwindSignalContext.sc_regs[RETURNADDRREG];
programCounter = unwindSignalContext.sc_pc;
// This is the address that caused the fault when we tried to access
// it.
//
faultingAddress = signalContextPtr->FAULTING_ADDRESS;
// Special cases for bogus program counter values. If the program
// counter is zero or the fault occurred when we were trying to
// fetch an instruction (because the program counter itself was bad)
// then we cannot unwind the stack.
//
if (programCounter == 0) {
printf("PC is zero - stack trace not available.\n");
} else if (programCounter == faultingAddress) {
printf("bad PC (%p) - stack trace not available.\n",
faultingAddress);
} else {
unsigned int sameSpCount = 0;
// Loop through all the stack frames.
//
while ((returnAddress != 0) && (programCounter != 0)) {
// Get the run time procedure descriptor for this frame.
//
runTimeProcedurePtr = find_rpd(programCounter);
// Print a frame.
//
printFrame(runTimeProcedurePtr, programCounter);
// Unwind one level.
//
unwindOneLevel(&unwindSignalContext, runTimeProcedurePtr);
returnAddress = unwindSignalContext.sc_regs[RETURNADDRREG];
programCounter = unwindSignalContext.sc_pc;
if (unwindSignalContext.sc_sp <= stackpointer) {
sameSpCount++;
if (sameSpCount == 10) break;
} else {
sameSpCount = 0;
stackpointer = unwindSignalContext.sc_sp;
}
}
}
printTrailer();
}
// Discard one stack frame by silently unwinding.
//
long int discardOneLevel(
long int programCounter,
struct sigcontext *signalContextPtr)
{
void *runTimeProcedurePtr;
runTimeProcedurePtr = find_rpd(programCounter);
unwindOneLevel(signalContextPtr, runTimeProcedurePtr);
return signalContextPtr->sc_pc;
}
void printStack(int levelsToDiscard)
{
long int programCounter;
void *runTimeProcedurePtr;
jmp_buf context;
struct sigcontext *signalContextPtr;
// Capture the current context.
//
setjmp(context);
signalContextPtr = (struct sigcontext *)context;
programCounter = signalContextPtr->sc_pc;
// Discard the frame for this routine.
//
programCounter = discardOneLevel(programCounter, signalContextPtr);
// Discard any other frames requested by our caller.
//
if (levelsToDiscard > 0) {
int levels;
for (levels = 0; levels < levelsToDiscard; levels++) {
programCounter = discardOneLevel(programCounter, signalContextPtr);
}
}
// Now that we have the right context, print the stack trace.
//
printStackWkr(signalContextPtr);
}
void innermost()
{
printStack(0);
}
void middle()
{
innermost();
}
int main()
{
middle();
return 0;
}
Decimal digits
DG [0-9]
Octal digits
OC [0-7]
Hexadecimal digits
HX [0-9a-fA-F]
Letters
LT [A-Za-z_$]
Letters from the International Character Set
LTI18N [A-Za-z_$\200-\377]
Characters in words separated by spaces, tabs, semicolons, linefeeds, less-than, greater-than, and quoted strings
WD [^ \t;\n<>'"]
Characters allowed in a file name
FL [^ \t\n\}\;\>\<]
Exponents on the ends of numbers
Exponent [eE][+-]?{DG}+
Whitespace
Whitespace [ \t]+
Strings
stringChar ([^"\\\n]|([\\]({simpleEscape}|{octalEscape}|{hexEscape})))
charChar ([^'\\\n]|([\\]({simpleEscape}|{octalEscape}|{hexEscape})))
simpleEscape ([A-Za-z'"?#\\])
octalEscape ([0-7]{1,3})
hexEscape ([xX][0-9a-fA-F]{1,8})
In all lexical states, unescaped newlines produce the NEWLINE token and change the lexical state to be LKEYWORDS. Note - it may not be possible to use an escaped newline when entering commands from a terminal, because the command line editting process regards the line as finished when it sees the first newline, whether or not it is escaped.
LKEYWORDS, LNORM, LFILE, LLINE, LWORDS, LSIGNAL
[\n] NEWLINE, LKEYWORDS
In most lexical states the spaces, tabs, and escaped newlines are ignored.
LKEYWORDS, LNORM, LFILE, LSIGNAL
[ \t]
\\\n
In the LLINE state the spaces and tabs are part of the line. But escaped newlines are still ignored.
LLINE
\\\n
In the LWORDS state the spaces and tabs are ignored, but escaped newlines are not.
LWORDS
[ \t]
LKEYWORDS tokens shared by all languages
Most LKEYWORDS tokens change the lexical state to LNORM as they recognize the beginning of a command that contains language-specific syntax.
Transit to LNORM
"&" AMPERSAND
"." DOT
"@" ATSIGN
// doesn't iParenLevel++ - bug
"(" LPAREN
"/" SLASH
"?" QUESTION
assign ASSIGN
attach ATTACH
call CALL
catch{Whitespace}unaligned CATCH_UNALIGN
condition CONDITION
cont CONT
cont{Whitespace}thread CONT_THREAD
delete DELETE
delete{Whitespace}"*" DELETE_ALL
delete{Whitespace}all DELETE_ALL
detach DETACH
disable DISABLE
disable{Whitespace}"*" DISABLE_ALL
disable{Whitespace}all DISABLE_ALL
down DOWN
dump DUMP
enable ENABLE
enable{Whitespace}"*" ENABLE_ALL
enable{Whitespace}all ENABLE_ALL
func FUNC
goto GOTO
history HISTORY
ignore{Whitespace}unaligned IGNORE_UNALIGN
kill KILL
kps KPS
ladebug_replace{Whitespace}event REPLACEEVENT
list LIST
listobj LISTOBJ
monitor{Whitespace}add MONITOR_ADD
monitor{Whitespace}remove MONITOR_REMOVE
mutex MUTEX
next NEXT
nexti NEXTI
patch PATCH
pop POP
print PRINT
printf PRINTF
printregs PRINTREGS
process PROCESS
process{Whitespace}"*" PROCESS_ALL
process{Whitespace}all PROCESS_ALL
pthread PTHREAD
quit QUIT
return RETURN
set SET
set{Whitespace}thread SET_THREAD
sh SH
status STATUS
step STEP
stepi STEPI
stop STOP
stopi STOPI
thread THREAD
trace TRACE
tracei TRACEI
unload UNLOAD
unset UNSET
unsetenv{Whitespace}"*" UNSETENV_ALL
up UP
watch WATCH
watch{Whitespace}memory WATCH_MEMORY
watch{Whitespace}variable WATCH_VARIABLE
whatis WHATIS
when WHEN
wheni WHENI
where WHERE
whereis WHEREIS
where{Whitespace}thread WHERE_THREAD
where{Whitespace}thread{Whitespace}"*" WHERE_THREAD_ALL
where{Whitespace}thread{Whitespace}all WHERE_THREAD_ALL
which WHICH
ladebug_internal_dumploadable LADEBUG_INTERNAL_DUMPLOADABLE
In addition to changing to LNORM, sometimes setTypeLookup(FALSE) is done...
alias ALIAS
export EXPORT
printenv PRINTENV
setenv SETENV
unalias UNALIAS
unsetenv UNSETENV
Some, however, stay in the LKEYWORDS state because either they start or end
commands sequences, or they are just the first of a burst of keywords, or
because they are the addresses that start "examine" commands.
Stay in LKEYWORDS
"{" LBRACE
"}" RBRACE
playback PLAYBACK
record RECORD
show SHOW
"0"{OC}+ lexUnsignedLong
"0"[xX]{HX}+ lexUnsignedLong
{DG}+ lexUnsignedLong
And some even stay in LKEYWORDS but also setTypeLookup(TRUE).
Why don't "{" and "}" do this? As a matter of fact, this
rule is NEVER invoked since there's no valid context where ";" shows
up in the LKEYWORDS state. The < LNORM>";" rule
(see below) is the
one we really use.
Stay in LKEYWORDS, setTypeLookup(TRUE)
";" SEMICOLON
Others change to specific other states for their commands.
Transit to LLINE
help HELP
Transit to LFILE
delsharedobj DELSHAREDOBJ
edit EDIT
file FILECMD
load LOAD
readsharedobj READSHAREDOBJ
source SOURCE
unuse UNUSE
use USE
input INPUT
io IO
output OUTPUT
Transit to LWORDS
run RUN
rerun RERUN
Transit to LSIGNAL
catch CATCH
ignore IGNORE
LKEYWORD Language Tokens Specific to C
{LTI18N}({LTI18N}|{DG})*
{
SetLexState(lnorm); COPY_KEYWORD;
return (symbolType(yytext, curLexScope, IDENTIFIER, TYPEDEFname));
}
LKEYWORD Language Tokens Specific to C++
class { SetLexState(lnorm); return CLASS; }
{LTI18N}({LTI18N}|{DG})*
{
SetLexState(lnorm); COPY_KEYWORD;
return (symbolType(yytext, curLexScope, IDENTIFIER, TYPEDEFname));
}
{LTI18N}({LTI18N}|{DG})*/::
{
COPY_KEYWORD;
return TYPEDEFname;
}
{LTI18N}({LTI18N}|{DG})*/\<
{
SetLexState(lnorm);
return CheckForTemplate();
}
LKEYWORD Language Tokens Specific to Fortran
Transit to LNORM
HPFGET HPFGET
{LT}({LT}|{DG})*
{
COPY_KEYWORD;
return (symbolType(yytext, curLexScope, IDENTIFIER, TYPEDEFname, PROCEDUREname));
}
LWORDS tokens shared by all languages
Transit to LKEYWORDS
[;] { setTypeLookup(TRUE); return SEMICOLON; }
Stay in LWORDS
\> GREATER
\< LESS
">&" GREATERAMPERSAND
"1>" ONEGREATER
"2>" TWOGREATER
[']{charChar}*['] {
return STRINGliteral;
}
["]{stringChar}*["] {
return STRINGliteral;
}
{WD}* {
COPY_KEYWORD_P;
// If the last byte in the token is \ (Backslash), we have to check whether
// it is part of a multi-byte character. If true, we should not treat the
// Backslash as a real escape character.
//
if (yytext[yyleng-1] == '\\' && !(ClosingMB ((unsigned char *)yytext, yyleng)) )
{
/* replace the backslash with the next char */
yytext[yyleng-1] = yyinput();
//
// Usually, flex will update the HighWaterMark before executing
// any action. But, as here we just input an extra chartacter inside
// an action, a manual update of the HighWaterMark is needed
//
cin_UpdateHighWaterMark(1);
yymore();
}
else
{
/* input(); don't flush the whitespace */
BEGIN LWORDS;
return STRINGliteral;
}
}
[lL][']{charChar}+['] {
return WIDECHARACTERconstant;
}
[lL]["]{stringChar}*["] {
return WIDESTRINGliteral;
}
LLINE tokens shared by all languages
Transit to LKEYWORDS
#Cmn-Tokens-Lines# Common Lines
.+ {
COPY_KEYWORD_P;
return STRINGliteral;
}
LFILE tokens shared by all languages
Transit to LKEYWORDS
[;] SEMICOLON
[\}] RBRACE
Stay in LFILE
{FL}+ {
COPY_KEYWORD;
return(FILENAME);
}
Transit to LWORDS
\> GREATER
\< LESS
">&" GREATERAMPERSAND
LSIGNAL tokens shared by all languages
Transit to LKEYWORDS
[;] SEMICOLON
[\}] RBRACE
Stay in LSIGNAL
{DG}+ lexUnsignedLong(yytext, 10, INTEGERconstant, BOGUS, &yylval)
{LT}({LT}|{DG})* IDENTIFIER
LNORM tokens shared by all languages
Transit to LKEYWORDS
";" setTypeLookup(TRUE); SEMICOLON
"{" LBRACE
// why doesn't the following setTypeLookup(TRUE)?
//
with{Whitespace}event lexReservedWordyy(WITHEVENT)
Stay in LNORM
// why doesn't this SetLexState(lkeywords)
"}" RBRACE
Stay in LNORM
":" COLON
"`" TICK
"@" ATSIGN
"$" DOLLAR
"." DOT
"/" SLASH
"," COMMA
"*" STAR
"<" LESS
">" GREATER
["]{stringChar}*["] STRINGliteral
[']{charChar}+['] {
if (strlen(...) == 1) { /* zero length is disallowed by the grammer */
return CHARACTERconstant;
} else {
return STRINGliteral;
}
}
[lL][']{charChar}+['] {
return WIDECHARACTERconstant;
}
[lL]["]{stringChar}*["] {
return WIDESTRINGliteral;
}
"(" iParenLevel++; LPAREN
")" iParenLevel--; RPAREN
in lexReservedWordyy(IN)
in{Whitespace}all{Whitespace} lexReservedWordyy(IN_ALL)
at lexReservedWordyy(AT)
if lexReservedWordyy(IF)
thread lexReservedWordyy(THREAD)
thread{Whitespace}all lexReservedWordyy(THREAD_ALL)
thread{Whitespace}"*" lexReservedWordyy(THREAD_ALL)
to lexReservedWordyy(TO)
policy lexReservedWordyy(POLICY)
priority lexReservedWordyy(PRIORITY)
state lexReservedWordyy(STATE)
with lexReservedWordyy(WITH)
any lexReservedWordyy(ANY)
changed lexReservedWordyy(CHANGED)
read lexReservedWordyy(READ)
write lexReservedWordyy(WRITE)
#Cmn-Tokens-Reserved# Reserved Words
int lexReservedWordyy(int iReservedToken)
{
if (iParenLevel == 0)
return iReservedToken;
else
{
COPY_KEYWORD;
return symbolType(yytext, curLexScope,
IDENTIFIER, TYPEDEFname,
PROCEDUREname);
}
}
// Function: symbolType
//
// Purpose: This function takes the name of a symbol, and the values
// that correspond to its possible meta-types (i.e. identifier,
// typename, etc.), or -1 if the symbol cannot hold a certain type.
// The function looks up the name in the current language context,
// and based on the language, returns the type of the symbol.
// The default type is "identifier"
//
int symbolType (
const String s,
Scope* const currentLexicalScope,
const int identifier,
const int typedefname,
const int procname)
// Look up the symbol, using the current language.
// This function sets whether the symbolType function looks up types
// in the symbol table, or whether simply returns IDENTIFIER, which is
// much quicker. This gives a toggle switch to the symbol-table-
// feedback-to-the-lexer-hack that's been an integral part of grammars
// for typed languages since the stone age. It also allows a smooth
// migration from using this system to using semantic analysis
// instead.
//
void setTypeLookup(Boolean lookupTypes);
// If yytext[yyleng-1] == '\\' then
// check whether it closes a legal multi-byte character.
//
static inline Boolean ClosingMB (unsigned char *token, int leng)
#Cmn-Concepts-Filename# Common Concepts - Filename
NEED TO DISTINQUISH BETWEEN DIRECTORIES, SOURCE FILES, LOADABLE FILES
filename
: FILENAME
| string
/* The following productions allow a user to use the unload command,
* until it gets fixed in a better way (i.e. redesigned).
*/
| IDENTIFIER /* This is for the (broken) UNLOAD Cmd... */
| IDENTIFIER DOT IDENTIFIER /* This is for the (broken) UNLOAD Cmd... */
Stay in LNORM
"->" ARROW
"++" INCR
"--" DECR
"<<" LS
">>" RS
"<=" LE
">=" GE
"==" EQ
"!=" NE
"&&" ANDAND
"||" OROR
"*=" MULTassign
"/=" DIVassign
"%=" MODassign
"+=" PLUSassign
"-=" MINUSassign
"<<=" LSassign
">>=" RSassign
"&=" ANDassign
"^=" ERassign
"|=" ORassign
"+" PLUS
"-" MINUS
"%" MOD
"^" HAT
"&" AMPERSAND
"|" OR
"~" TWIDDLE
"!" NOT
"[]" BRACKETS
"=" ASSIGNOP
"[" LBRACKET
"]" RBRACKET
"?" QUESTION
char CHAR
double DOUBLE
float FLOAT
int INT
long LONG
short SHORT
signed SIGNED
unsigned UNSIGNED
void VOID
const CONST
volatile VOLATILE
sizeof SIZEOF
enum ENUM
struct STRUCT
union UNION
INTEGER constant
"0"{OC}+
"0"[xX]{HX}+
{DG}+
FLOATING constant (lexDouble)
{DG}*"."{DG}*
{DG}*"."{DG}*{Whitespace}?{Exponent}
{DG}+ {Whitespace}?{Exponent}
IDENTIFIER or TYPEDEFname
{LTI18N}({LTI18N}|{DG})*
"->" ARROW
"++" INCR
"--" DECR
"<<" LS
">>" RS
"<=" LE
">=" GE
"==" EQ
"!=" NE
"&&" ANDAND
"||" OROR
"..." ELLIPSIS
"::" CLCL
".*" DOTstar
"->*" ARROWstar
"*=" MULTassign
"/=" DIVassign
"%=" MODassign
"+=" PLUSassign
"-=" MINUSassign
"<<=" LSassign
">>=" RSassign
"&=" ANDassign
"^=" ERassign
"|=" ORassign
"+" PLUS
"-" MINUS
"%" MOD
"^" HAT
"&" AMPERSAND
"|" OR
"~" TWIDDLE
"!" NOT
"[]" BRACKETS
"()" PARENS
"=" ASSIGNOP
"[" LBRACKET
"]" RBRACKET
"?" QUESTION
operator OPERATOR
char CHAR
double DOUBLE
float FLOAT
int INT
long LONG
short SHORT
signed SIGNED
unsigned UNSIGNED
void VOID
new NEW
delete DELETE
const CONST
volatile VOLATILE
sizeof SIZEOF
class CLASS
enum ENUM
struct STRUCT
union UNION
INTEGERconstant
"0"{OC}+
"0"[xX]{HX}+
{DG}+
FLOATINGconstant (double)
{DG}*"."{DG}*
{DG}*"."{DG}* { Whitespace}?{Exponent}
{DG}+{Whitespace}?{Exponent}
IDENTIFIER, TYPEDEFname
{LTI18N}({LTI18N}|{DG})*
TYPEDEFname
{LTI18N}({LTI18N}|{DG})*/::
IDENTIFIER, TYPEDEFname
{LTI18N}({LTI18N}|{DG})*/\<
{
return CheckForTemplate();
}
int CheckForTemplate()
{
ASSERT(yytext[strlen(yytext)-1] != '<');
// Also if the string before the name is "operator" then don't check
// for this as a template.
//
const char* strOperator = "operator";
const int iLength = strlen(strOperator);
if (strlen(yytext) == iLength &&
strcmp(yytext, strOperator) == 0)
return OPERATOR;
// Possible template - check for it as a type name.
char b[1024];
int opencnt = 0;
// Make a copy of the string.
strcpy(b, yytext);
if (templateLexerDebug)
cout << "yytext = `" << yytext << "'." << endl;
for (char* c = b+strlen(yytext); (c-b) < 1024; )
{
// Read in the next character and NULL-terminate the string.
*c = yyinput();
*(c+1)='\0';
if (templateLexerDebug)
{
cout << "ENTRY:" << endl;
cout << " Just read `" << (char )*c << "'." << endl;
cout << " Buffer `" << b << "'." << endl;
cout << " Paren. Level = " << opencnt << endl;
}
if (*c == '<')
{
opencnt++;
}
if (*c == '\n')
{
for (; c >= (b+strlen(yytext)); c--)
unput((int)*c); // unput < also
COPY_KEYWORD;
return IDENTIFIER;
}
if ((*c == '>')&&(*(c - 1) == '>'))
{
// we've encountered '>>' to close two templates. We need
// to insert a space between them for name lookup. (e.g.
// Foo> => Foo > )
*(c+2) = '\0';
*(c+1) = *c;
*c = ' ';
c++;
}
if ((*c == '>')&&(--opencnt == 0))
{
c++;
*c = '\0';
if (symbolType(b, curLexScope, IDENTIFIER, TYPEDEFname) == TYPEDEFname)
{
yylval.sval = duplicateString(b);
return TYPEDEFname;
}
else
{
for (c--; c >= (b+strlen(yytext)); c--)
unput((int)*c);
COPY_KEYWORD;
return IDENTIFIER;
}
}
else if (!((*c == ' ') || (*c == '\t')))
{
// Omit spaces and tabs because demangler does this also
c++;
}
if (templateLexerDebug)
{
cout << "EXIT:" << endl;
cout << " Just read `" << (char )*c << "'." << endl;
cout << " Buffer `" << b << "'." << endl;
cout << " Paren. Level = " << opencnt << endl;
}
}
COPY_KEYWORD;
return IDENTIFIER;
}
"+" PLUS
"-" MINUS
"**" STARSTAR
".LT." LESS
".LE." LE
".EQ." EQ
".NE." NE
".GE." GE
".GT." GREATER
"<=" LE
"==" EQ
"/=" NE
">=" GE
".NOT." LOGNOT
".AND." LOGAND
".OR." LOGOR
".EQV." LOGEQV
".NEQV." LOGNEQV
".XOR." LOGXOR
"%" PERCENT
"=" ASSIGNOP
"//" SLASHSLASH
"(/" OPENSLASH
"/)" SLASHCLOSE
"[" LBRACKET
"]" RBRACKET
"&" AMPERSAND
sizeof SIZEOF
Integer Constants
".TRUE."
".FALSE."
"0"{OC}+
"0X"{HX}+
{DG}+
Floating Point Constants
{DG}*"."{DG}*
{DG}*"."{DG}*{Whitespace}?{Exponent}
{DG}+{Whitespace}?{Exponent}
IDENTIFIER, TYPEDEFname
{LT}({LT}|{DG})*
"->" ARROW
"++" INCR
"--" DECR
"<<" LS
">>" RS
"<=" LE
">=" GE
"==" EQ
"!=" NE
"&&" ANDAND
"||" OROR
"*=" MULTassign
"/=" DIVassign
"%=" MODassign
"+=" PLUSassign
"-=" MINUSassign
"<<=" LSassign
">>=" RSassign
"&=" ANDassign
"^=" ERassign
"|=" ORassign
"+" PLUS
"-" MINUS
"%" MOD
"^" HAT
"&" AMPERSAND
"|" OR
"~" TWIDDLE
"!" NOT
"[]" BRACKETS
"=" ASSIGNOP
"[" LBRACKET
"]" RBRACKET
"?" QUESTION
INTEGERconstant
"0"{OC}+
"0X"{HX}+
{DG}+
FLOATINGconstant
{DG}*"."{DG}+
{DG}*"."{DG}*{Whitespace}?{Exponent}
{DG}+{Whitespace}?{Exponent}
IDENTIFIER, TYPEDEFname
{LT}({LT}|{DG})*
ALPHASDIGITSI18N [0-9A-Za-z_$\200-\377]
ALPHASDIGITSHYPHENI18N [0-9\-A-Za-z_$\200-\377]
IntLit [-+]?{DG}+
DecLit [-+]?{DG}*\.{DG}+
FloatLit [-+]?(({DG}+\.{DG}*)|({DG}*\.{DG}*))("E"[+-]?{DG}+)
CHexLit "0X"{HX}+
CobolHexLit "X"((\"({HX}{HX})+["\n])|('({HX}{HX})+['\n]))
CobolWord {ALPHASDIGITSI18N}|({ALPHASDIGITSI18N}{ALPHASDIGITSI18N})|({ALPHASDIGITSI18N}+{ALPHASDIGITSHYPHENI18N}+{ALPHASDIGITSI18N}+)
"=" ASSIGNOP
" + " PLUS
" - " MINUS
"**" EXPON
"&" AMPERSAND
AND AND
MOD MOD
NOT NOT
OR OR
REFERENCE([ \t]+"OF")? REFERENCEOF
OF OF
GIVING GIVING
USING USING
(BY[ \t]+)?"REFERENCE" BYREFERENCE
(BY[ \t]+)?"VALUE" BYVALUE
(BY[ \t]+)?"CONTENT" BYCONTENT
(BY[ \t]+)?"DESCRIPTOR" BYDESCRIPTOR
(IS[ \t]+)?"POSITIVE" SIGNPOS
(IS[ \t]+)?"NEGATIVE" SIGNNEG
(IS[ \t]+)?"ZERO" SIGNZERO
(IS[ \t]+)?"NOT"[ \t]+"POSITIVE" SIGNNEG
(IS[ \t]+)?"NOT"[ \t]+"NEGATIVE" SIGNPOS
(IS[ \t]+)?"NOT"[ \t]+"ZERO" SIGNNOTZERO
(IS[ \t]+)?("="|("EQUAL"([ \t]+"TO")?)) EQ
(IS[ \t]+)?("<"|("LESS"([ \t]+"THAN")?)) LESS
(IS[ \t]+)?(">"|("GREATER"([ \t]+"THAN")?)) GREATER
(IS[ \t]+)?"NOT"[ \t]+("="|("EQUAL"([ \t]+"TO")?)) NE
(IS[ \t]+)?"NOT"[ \t]+("<"|("LESS"([ \t]+"THAN")?)) GE
(IS[ \t]+)?"NOT"[ \t]+(">"|("GREATER"([ \t]+"THAN")?)) LE
(IS[ \t]+)?("<="|("LESS" ([ \t]+"THAN")?[ \t]+"OR"[ \t]+"EQUAL"([ \t]+"TO")?)) LE
(IS[ \t]+)?(">="|("GREATER"([ \t]+"THAN")?[ \t]+"OR"[ \t]+"EQUAL"([ \t]+"TO")?)) GE
DECIMALconstant
{DecLit}
INTEGERconstant
{IntLit} DECIMAL
{CHexLit} HEXADECIMAL
{CobolHexLit} HEXADECIMAL
FLOATINGconstant
{FloatLit}
IDENTIFIER
{CobolWord}
#Cmn-Expr-Arglist# Common Expressions - Argument list
argument-expression-list
: assignment-expression
| assignment-expression COMMA argument-expression-list
arg-expression-list-opt
: argument-expression-list
| /* Nothing at all */
#Cmn-Expr-Primitives# Common Expressions - Primitives
string
: STRINGliteral
identifier-or-key-word
: IDENTIFIER
| embedded-key-word
embedded-key-word
: ANY
| CHANGED
| READ
| WRITE
#Cmn-Expr-expression-opt# Common Expressions - Optional expressions
THESE SHOULD BE DISAPPEARED
expression-opt
: expression
| /* Nothing at all */
#Cmn-Expr-filename-opt# Common Expressions - Optional filenames
THESE SHOULD BE DISAPPEARED
filename-opt
: filename
| /* Nothing at all */
#Cmn-Expr-lines# Common Expressions - Line numbers
line-address
: ATSIGN string COLON line-number
| ATSIGN line-number
line-number
: INTEGERconstant /* line number int */
| DOLLAR /* last line */
#Cmn-Expr-rescoping# Common Expressions - Rescoping
THIS WHOLE AREA IS TRUELY BIZARRE
qual-symbol-opt
: expression /* Base (global) name */
| qual-symbol-opt TICK expression /* Qualified name */
qual-symbol-with-null-opt
: qual-symbol-opt
| /* Nothing at all */
string-tick
: string TICK
filename-tick
: string-tick
rescoped-typedef
: filename-tick qual-typedef-opt
| TICK qual-typedef-opt
rescoped-expression
: filename-tick qual-symbol-opt
| TICK qual-symbol-opt
Miscellaneous
address
: AMPERSAND postfix-expression
| line-address
| postfix-expression
address-exp
: address
| address-exp PLUS address
| address-exp MINUS address
| address-exp STAR address
call-expression
: expression
identifier-or-typedef-name
: identifier-or-key-word
| TYPEDEFname
loc
: expression
| rescoped-expression
loc-address
: AMPERSAND postfix-expression
| AMPERSAND identifier-or-typedef-name PLUS INTEGERconstant
| AMPERSAND identifier-or-typedef-name MINUS INTEGERconstant
qual-typedef-opt
: TYPEDEFname
| qual-typedef-opt TICK TYPEDEFname
whatis-expressions
: expression
| rescoped-expression
| type-name
| rescoped-typedef
Expressions
expression
: assignment-expression
constant-expression
: conditional-expression
assignment-expression
: conditional-expression
| unary-expression ASSIGNOP assignment-expression
| unary-expression MULTassign assignment-expression
| unary-expression DIVassign assignment-expression
| unary-expression MODassign assignment-expression
| unary-expression PLUSassign assignment-expression
| unary-expression MINUSassign assignment-expression
| unary-expression LSassign assignment-expression
| unary-expression RSassign assignment-expression
| unary-expression ANDassign assignment-expression
| unary-expression ERassign assignment-expression
| unary-expression ORassign assignment-expression
conditional-expression
: logical-OR-expression
| logical-OR-expression QUESTION expression COLON conditional-expression
logical-OR-expression
: logical-AND-expression
| logical-OR-expression OROR logical-AND-expression
logical-AND-expression
: inclusive-OR-expression
| logical-AND-expression ANDAND inclusive-OR-expression
inclusive-OR-expression
: exclusive-OR-expression
| inclusive-OR-expression OR exclusive-OR-expression
exclusive-OR-expression
: AND-expression
| exclusive-OR-expression HAT AND-expression
AND-expression
: equality-expression
| AND-expression AMPERSAND equality-expression
equality-expression
: relational-expression
| equality-expression EQ relational-expression
| equality-expression NE relational-expression
relational-expression
: shift-expression
| relational-expression LESS shift-expression
| relational-expression GREATER shift-expression
| relational-expression LE shift-expression
| relational-expression GE shift-expression
shift-expression
: additive-expression
| shift-expression LS additive-expression
| shift-expression RS additive-expression
additive-expression
: multiplicative-expression
| additive-expression PLUS multiplicative-expression
| additive-expression MINUS multiplicative-expression
multiplicative-expression
: cast-expression
| multiplicative-expression STAR cast-expression
| multiplicative-expression SLASH cast-expression
| multiplicative-expression MOD cast-expression
cast-expression
: unary-expression
| LPAREN type-name RPAREN cast-expression
unary-expression
: postfix-expression
| INCR unary-expression
| DECR unary-expression
| AMPERSAND cast-expression
| STAR cast-expression
| PLUS cast-expression
| MINUS cast-expression
| TWIDDLE cast-expression
| NOT cast-expression
| SIZEOF unary-expression
| SIZEOF LPAREN type-name RPAREN
| line-address
postfix-expression
: primary-expression
| postfix-expression LBRACKET expression RBRACKET
| postfix-expression LPAREN arg-expression-list-opt RPAREN
| postfix-expression DOT identifier-or-typedef-name
| postfix-expression ARROW identifier-or-typedef-name
| postfix-expression INCR
| postfix-expression DECR
primary-expression
: identifier-or-key-word
| constant
| string-literal-list
| LPAREN expression RPAREN
string-literal-list
: string
| string-literal-list string
constant
: FLOATINGconstant
| INTEGERconstant
| CHARACTERconstant
| WIDECHARACTERconstant
| WIDESTRINGliteral
// Note: ENUMERATIONconstant are treated as identifiers
Types
type-specifier
: basic-type-specifier
| struct-union-enum-type-specifier
| typedef-type-specifier
basic-type-specifier
: basic-type-name
| type-qualifier-list basic-type-name
| basic-type-specifier type-qualifier
| basic-type-specifier basic-type-name
type-qualifier-list
: type-qualifier
| type-qualifier-list type-qualifier
type-qualifier
: CONST
| VOLATILE
basic-type-name
: VOID
| CHAR
| SHORT
| INT
| LONG
| FLOAT
| DOUBLE
| SIGNED
| UNSIGNED
struct-union-enum-type-specifier
: elaborated-type-name
| type-qualifier-list elaborated-type-name
| struct-union-enum-type-specifier type-qualifier
typedef-type-specifier
: TYPEDEFname
| type-qualifier-list TYPEDEFname
| typedef-type-specifier type-qualifier
elaborated-type-name
: struct-or-union-specifier
| enum-specifier
struct-or-union-specifier
: struct-or-union identifier-or-typedef-name
struct-or-union
: STRUCT
| UNION
enum-specifier
: ENUM identifier-or-typedef-name
type-name
: type-specifier
| type-specifier abstract-declarator
| type-qualifier-list // Implicit "int"
| type-qualifier-list abstract-declarator // Implicit "int"
abstract-declarator
: unary-abstract-declarator
| postfix-abstract-declarator
| postfixing-abstract-declarator
postfixing-abstract-declarator
: array-abstract-declarator
| LPAREN RPAREN
array-abstract-declarator
: BRACKETS
| LBRACKET constant-expression RBRACKET
| array-abstract-declarator LBRACKET constant-expression RBRACKET
unary-abstract-declarator
: STAR
| STAR type-qualifier-list
| STAR abstract-declarator
| STAR type-qualifier-list abstract-declarator
postfix-abstract-declarator
: LPAREN unary-abstract-declarator RPAREN
| LPAREN postfix-abstract-declarator RPAREN
| LPAREN postfixing-abstract-declarator RPAREN
| LPAREN unary-abstract-declarator RPAREN postfixing-abstract-declarator
#C++Expr#
/* Limitations in this grammar include:
*
* In new, casts, and sizeof, we do not allow functions to be specified with
* arguments. That is, the following is not supported:
*
* int (*) (double)
*
* but the following is supported:
*
* int (*) ()
*
* Similarly, all other ambiguities between expressions and declarations are
* resolved in favor of expressions. This is because we are a debugger and we
* do not support declarations at all.
address
: AMPERSAND postfix-expression /* Address of */
| line-address
| postfix-expression
address-exp
: address
| address-exp PLUS address
| address-exp MINUS address
| address-exp STAR address
call-expression
: expression
/* We are not including ENUMERATIONconstant here because we
* are treating it like a variable with a type of "enumeration
* constant".
*/
constant
: FLOATINGconstant
| INTEGERconstant
| CHARACTERconstant
| WIDECHARACTERconstant
| WIDESTRINGliteral
identifier-or-typedef-name
: identifier-or-key-word
| TYPEDEFname
loc
: TWIDDLE TYPEDEFname
| TYPEDEFname
| CLCL TYPEDEFname
| expression
| rescoped-expression
loc-address
: AMPERSAND postfix-expression
| LPAREN type-name RPAREN AMPERSAND postfix-expression PLUS INTEGERconstant
| AMPERSAND postfix-expression PLUS INTEGERconstant
| LPAREN type-name RPAREN AMPERSAND postfix-expression MINUS INTEGERconstant
| AMPERSAND postfix-expression MINUS INTEGERconstant
qual-typedef-opt
: TYPEDEFname /* Base (global) name */
| TWIDDLE TYPEDEFname /* Base (global) name */
| qual-typedef-opt TICK TYPEDEFname /* Qualified name */
| qual-typedef-opt TICK TWIDDLE TYPEDEFname /* Qualified name */
string-literal-list
: string
| string-literal-list string
whatis-expressions
: expression
| rescoped-expression
| rescoped-typedef
| type-name
| TWIDDLE TYPEDEFname
rescoped-identifier
: operator-function-name /* C++, not ANSI C */
| namespace-rescoped-identifier
namespace-rescoped-identifier
: TYPEDEFname CLCL namespace-rescoped-follower
namespace-rescoped-follower
: TWIDDLE TYPEDEFname /* C++, not ANSI C */
| namespace-rescoped-identifier /* C++, not ANSI C */
| operator-function-name /* C++, not ANSI C */
| identifier-or-typedef-name /* C++, not ANSI C */
primary-expression
: THIS /* C++, not ANSI C */
| CLCL identifier-or-key-word
| CLCL operator-function-name
| rescoped-identifier
| identifier-or-key-word /* Or typedefname? */
| constant
| string-literal-list
| LPAREN expression RPAREN
operator-function-name
: OPERATOR PLUS
| OPERATOR MINUS
| OPERATOR STAR
| OPERATOR SLASH
| OPERATOR MOD
| OPERATOR HAT
| OPERATOR AMPERSAND
| OPERATOR OR
| OPERATOR TWIDDLE
| OPERATOR NOT
| OPERATOR LESS
| OPERATOR GREATER
| OPERATOR LS
| OPERATOR RS
| OPERATOR ANDAND
| OPERATOR OROR
| OPERATOR ARROW
| OPERATOR INCR
| OPERATOR DECR
| OPERATOR LE
| OPERATOR GE
| OPERATOR EQ
| OPERATOR NE
| OPERATOR ASSIGNOP
| OPERATOR MULTassign
| OPERATOR DIVassign
| OPERATOR MODassign
| OPERATOR PLUSassign
| OPERATOR MINUSassign
| OPERATOR LSassign
| OPERATOR RSassign
| OPERATOR ANDassign
| OPERATOR ERassign
| OPERATOR ORassign
| OPERATOR PARENS
| OPERATOR BRACKETS
| OPERATOR NEW
| OPERATOR DELETE
| OPERATOR COMMA
| OPERATOR basic-type-name
| OPERATOR TYPEDEFname
| OPERATOR LPAREN type-name RPAREN
| OPERATOR type-qualifier
type-qualifier-list-opt
: /* Nothing at all */
| type-qualifier-list
postfix-expression
: primary-expression
| postfix-expression LBRACKET expression RBRACKET
| postfix-expression PARENS
| postfix-expression LPAREN argument-expression-list RPAREN
| postfix-expression LPAREN type-name-list RPAREN
| postfix-expression DOT identifier-or-typedef-name
| postfix-expression DOT TWIDDLE TYPEDEFname
| postfix-expression DOT rescoped-identifier
| postfix-expression ARROW identifier-or-typedef-name
| postfix-expression ARROW rescoped-identifier
| postfix-expression ARROW TWIDDLE TYPEDEFname
| postfix-expression INCR
| postfix-expression DECR
| TYPEDEFname LPAREN argument-expression-list RPAREN
| TWIDDLE TYPEDEFname LPAREN argument-expression-list RPAREN
| TYPEDEFname LPAREN type-name-list RPAREN
| TWIDDLE TYPEDEFname LPAREN type-name-list RPAREN
| basic-type-name LPAREN assignment-expression RPAREN
/* For disambiguating overloaded function names */
type-name-list
: type-name
| type-name COMMA type-name-list
| type-name comma-opt-ellipsis
| ELLIPSIS /* C++, not ANSI C */
comma-opt-ellipsis
: ELLIPSIS /* C++ */
| ',' ELLIPSIS
unary-expression
: postfix-expression
| INCR unary-expression
| DECR unary-expression
| line-address
| AMPERSAND cast-expression
| STAR cast-expression
| MINUS cast-expression
| PLUS cast-expression
| TWIDDLE LPAREN cast-expression RPAREN
| NOT cast-expression
| SIZEOF unary-expression
| SIZEOF LPAREN type-name RPAREN
| allocation-expression
allocation-expression
: operator-new LPAREN type-name RPAREN operator-new-initializer
| operator-new LPAREN argument-expression-list RPAREN LPAREN type-name
operator-new
: NEW
| CLCL NEW
operator-new-initializer
: /* Nothing at all */
| PARENS
| LPAREN argument-expression-list RPAREN
cast-expression
: unary-expression
| LPAREN type-name RPAREN cast-expression
deallocation-expression
: cast-expression
| DELETE deallocation-expression
| CLCL DELETE deallocation-expression
| DELETE BRACKETS deallocation-expression
| CLCL DELETE BRACKETS deallocation-expression
point-member-expression
: deallocation-expression
| point-member-expression DOTstar deallocation-expression
| point-member-expression ARROWstar deallocation-expression
multiplicative-expression
: point-member-expression
| multiplicative-expression STAR point-member-expression
| multiplicative-expression SLASH point-member-expression
| multiplicative-expression MOD point-member-expression
additive-expression
: multiplicative-expression
| additive-expression PLUS multiplicative-expression
| additive-expression MINUS multiplicative-expression
shift-expression
: additive-expression
| shift-expression LS additive-expression
| shift-expression RS additive-expression
relational-expression
: shift-expression
| relational-expression LESS shift-expression
| relational-expression GREATER shift-expression
| relational-expression LE shift-expression
| relational-expression GE shift-expression
equality-expression
: relational-expression
| equality-expression EQ relational-expression
| equality-expression NE relational-expression
AND-expression
: equality-expression
| AND-expression AMPERSAND equality-expression
exclusive-OR-expression
: AND-expression
| exclusive-OR-expression HAT AND-expression
inclusive-OR-expression
: exclusive-OR-expression
| inclusive-OR-expression OR exclusive-OR-expression
logical-AND-expression
: inclusive-OR-expression
| logical-AND-expression ANDAND inclusive-OR-expression
logical-OR-expression
: logical-AND-expression
| logical-OR-expression OROR logical-AND-expression
conditional-expression
: logical-OR-expression
| logical-OR-expression QUESTION expression COLON conditional-expression
assignment-expression
: conditional-expression
| unary-expression ASSIGNOP assignment-expression
| unary-expression MULTassign assignment-expression
| unary-expression DIVassign assignment-expression
| unary-expression MODassign assignment-expression
| unary-expression PLUSassign assignment-expression
| unary-expression MINUSassign assignment-expression
| unary-expression LSassign assignment-expression
| unary-expression RSassign assignment-expression
| unary-expression ANDassign assignment-expression
| unary-expression ERassign assignment-expression
| unary-expression ORassign assignment-expression
expression
: assignment-expression
constant-expression
: conditional-expression
type-specifier
: basic-type-specifier
| struct-union-enum-type-specifier
| typedef-type-specifier
type-qualifier-list
: type-qualifier
| type-qualifier-list type-qualifier
type-qualifier
: CONST
| VOLATILE
basic-type-specifier
: basic-type-name basic-type-name
| basic-type-name type-qualifier
| type-qualifier-list basic-type-name
| basic-type-specifier type-qualifier
| basic-type-specifier basic-type-name
struct-union-enum-type-specifier
: elaborated-type-name
| type-qualifier-list elaborated-type-name
| struct-union-enum-type-specifier type-qualifier
typedef-type-specifier
: TYPEDEFname type-qualifier
| type-qualifier-list TYPEDEFname
| typedef-type-specifier type-qualifier
basic-type-name
: VOID
| CHAR
| SHORT
| INT
| LONG
| FLOAT
| DOUBLE
| SIGNED
| UNSIGNED
elaborated-type-name
: aggregate-name
| enum-name
aggregate-name
: aggregate-key identifier-or-typedef-name
aggregate-key
: STRUCT
| UNION
| CLASS
enum-name
: ENUM identifier-or-typedef-name
parameter-type-list
: PARENS type-qualifier-list-opt
type-name
: type-specifier
| basic-type-name
| CLCL TYPEDEFname
| TYPEDEFname
| type-qualifier-list
| type-specifier abstract-declarator
| basic-type-name abstract-declarator
| CLCL TYPEDEFname abstract-declarator
| TYPEDEFname abstract-declarator
| type-qualifier-list abstract-declarator
abstract-declarator
: unary-abstract-declarator
| postfix-abstract-declarator
| postfixing-abstract-declarator
postfixing-abstract-declarator
: array-abstract-declarator
| parameter-type-list
array-abstract-declarator
: BRACKETS
| LBRACKET constant-expression RBRACKET
| array-abstract-declarator LBRACKET constant-expression RBRACKET
unary-abstract-declarator
: STAR
| AMPERSAND
| pointer-operator-type
| STAR abstract-declarator
| AMPERSAND abstract-declarator
| pointer-operator-type abstract-declarator
postfix-abstract-declarator
: LPAREN unary-abstract-declarator RPAREN
| LPAREN postfix-abstract-declarator RPAREN
| LPAREN postfixing-abstract-declarator RPAREN
| LPAREN unary-abstract-declarator RPAREN postfixing-abstract-declarator
pointer-operator-type
: TYPEDEFname CLCL STAR type-qualifier-list-opt
| STAR type-qualifier-list
| AMPERSAND type-qualifier-list
Miscellaneous
address
: line-address
| primary /* includes AMPERSAND variable */
address-exp
: address
| address-exp PLUS address
| address-exp MINUS address
| address-exp STAR address
loc
: expression
| rescoped-expression
loc-address
: AMPERSAND variable
| AMPERSAND identifier-or-typedef-name PLUS INTEGERconstant
| AMPERSAND identifier-or-typedef-name MINUS INTEGERconstant
qual-typedef-opt
: TYPEDEFname /* Base (global) name */
| qual-typedef-opt TICK TYPEDEFname /* Qualified name */
whatis-expressions
: expression
| rescoped-expression
| rescoped-typedef
| type-name
Expressions
expression
: expr
| named-procedure
assignment-expression
: expr
constant-expression
: constant
unary-expression
: variable
expr
: level-5-expr
| expr defined-binary-op level-5-expr
level-5-expr
: equiv-operand
| level-5-expr LOGEQV equiv-operand
| level-5-expr LOGNEQV equiv-operand
| level-5-expr LOGXOR equiv-operand
equiv-operand
: or-operand
| equiv-operand LOGOR or-operand
or-operand
: and-operand
| or-operand LOGAND and-operand
and-operand
: level-4-expr
| LOGNOT and-operand
level-4-expr
: level-3-expr
| level-3-expr LESS level-3-expr
| level-3-expr GREATER level-3-expr
| level-3-expr LE level-3-expr
| level-3-expr GE level-3-expr
| level-3-expr EQ level-3-expr
| level-3-expr NE level-3-expr
level-3-expr
: level-2-expr
| level-3-expr SLASHSLASH level-2-expr
level-2-expr
: add-operand
| level-2-expr PLUS add-operand
| level-2-expr MINUS add-operand
add-operand
: add-operand-f90
| add-operand-dec
| unary-expr-dec
add-operand-f90
: mult-operand-f90
| add-operand-f90 STAR mult-operand-f90
| add-operand-f90 SLASH mult-operand-f90
mult-operand-f90
: level-1-expr
| level-1-expr STARSTAR mult-operand-f90
add-operand-dec
: mult-operand-dec
| add-operand-f90 STAR mult-operand-dec
| add-operand-f90 SLASH mult-operand-dec
| add-operand-f90 STAR unary-expr-dec
| add-operand-f90 SLASH unary-expr-dec
mult-operand-dec
: level-1-expr STARSTAR mult-operand-dec
| level-1-expr STARSTAR unary-expr-dec
unary-expr-dec
: PLUS add-operand
| MINUS add-operand
level-1-expr
: primary
| defined-unary-op primary
defined-unary-op
: DOT_LETTERS_DOT
primary
: constant
| variable
| function-reference
| LPAREN expr RPAREN
| AMPERSAND variable /* Address of */
constant
: FLOATINGconstant
| INTEGERconstant
| complex-constant
| string
complex-constant
: LPAREN real-or-imag-part COMMA real-or-imag-part RPAREN
real-or-imag-part
: FLOATINGconstant
| PLUS FLOATINGconstant
| MINUS FLOATINGconstant
| INTEGERconstant
| PLUS INTEGERconstant
| MINUS INTEGERconstant
defined-binary-op
: DOT_LETTERS_DOT
int-expr
: expr
scalar-int-expr
: int-expr
variable
: named-variable
| subobject
named-variable
: variable-name
subobject
: array-elt-or-sect
| structure-component
| known-substring
known-substring
: disabled-array-elt-or-sect LPAREN substring-range RPAREN
| hf-array-abomination
substring-range
: scalar-int-expr COLON scalar-int-expr
| scalar-int-expr COLON
| COLON scalar-int-expr
| COLON
hf-array-abomination
: named-variable
LPAREN section-subscript-list RPAREN
LPAREN section-subscript RPAREN
| structure PERCENT any-identifier
LPAREN section-subscript-list RPAREN
LPAREN section-subscript RPAREN
| structure DOT any-identifier
LPAREN section-subscript-list RPAREN
LPAREN section-subscript RPAREN
disabled-array-elt-or-sect
: DISABLER array-elt-or-sect
array-elt-or-sect
: named-variable LPAREN section-subscript-list RPAREN
| structure PERCENT any-identifier LPAREN section-subscript-list RPAREN
| structure DOT any-identifier LPAREN section-subscript-list RPAREN
section-subscript-list
: section-subscript
| section-subscript COMMA section-subscript-list
subscript
: scalar-int-expr
section-subscript
: subscript
| subscript-triplet
subscript-triplet
: subscript COLON subscript COLON stride
| subscript COLON COLON stride
| COLON subscript COLON stride
| COLON COLON stride
| subscript COLON subscript
| subscript COLON
| COLON subscript
| COLON
stride
: scalar-int-expr
structure-component
: structure PERCENT any-identifier
| structure DOT any-identifier
structure
: named-variable
| structure-component
| array-elt-or-sect
function-reference
: SIZEOF LPAREN expr RPAREN
| named-function LPAREN RPAREN
| named-function LPAREN actual-arg-spec-list RPAREN
named-procedure
: PROCEDUREname
named-function
: PROCEDUREname
named-subroutine
: PROCEDUREname
actual-arg-spec-list
: actual-arg-spec
| actual-arg-spec COMMA actual-arg-spec-list
actual-arg-spec
: actual-arg
actual-arg
: expr
any-identifier
: variable-name
| PROCEDUREname
variable-name
: identifier-or-key-word
identifier-or-typedef-name
: identifier-or-key-word
| TYPEDEFname
| PROCEDUREname
call-expression
: call-stmt
call-stmt
: named-subroutine
| named-subroutine LPAREN RPAREN
| named-subroutine LPAREN actual-arg-spec-list RPAREN
Types
type-name
: TYPEDEFname
#Ada#
address
: INTEGERconstant /* Numeric address */
| line-address
| AMPERSAND identifier-or-typedef-name /* Address of */
| LPAREN expression RPAREN
address-exp
: address
| address-exp PLUS address
| address-exp MINUS address
| address-exp STAR address
call-expression
: expression
/* CONSTANTS: We are not including ENUMERATIONconstant here because we
* are treating it like a variable with a type of "enumeration constant".
*/
constant
: FLOATINGconstant
| INTEGERconstant
| CHARACTERconstant
loc
: expression
| rescoped-expression
loc-address
: AMPERSAND identifier-or-typedef-name
| AMPERSAND identifier-or-typedef-name PLUS INTEGERconstant
| AMPERSAND identifier-or-typedef-name MINUS INTEGERconstant
qual-typedef-opt
: TYPEDEFname /* Base (global) name */
| qual-symbol-opt TICK TYPEDEFname /* Qualified name */
whatis-expressions
: expression
| rescoped-expression
| rescoped-typedef
| type-name
primary-expression
: identifier-or-key-word /* Cannot use typedef name as variable */
| constant /* Const */
| string-literal-list
| LPAREN expression RPAREN
postfix-expression
: primary-expression
| postfix-expression LBRACKET expression RBRACKET
| postfix-expression LPAREN arg-expression-list-opt RPAREN
| postfix-expression DOT identifier-or-typedef-name
| postfix-expression ARROW identifier-or-typedef-name
| postfix-expression INCR
| postfix-expression DECR
string-literal-list
: string
| string-literal-list string
unary-expression
: postfix-expression
| INCR unary-expression
| DECR unary-expression
| AMPERSAND cast-expression
| line-address
| STAR cast-expression
| PLUS cast-expression
| MINUS cast-expression
| TWIDDLE cast-expression
| NOT cast-expression
cast-expression
: unary-expression
| LPAREN type-name RPAREN cast-expression
multiplicative-expression
: cast-expression
| multiplicative-expression STAR cast-expression
| multiplicative-expression SLASH cast-expression
| multiplicative-expression MOD cast-expression
additive-expression
: multiplicative-expression
| additive-expression PLUS multiplicative-expression
| additive-expression MINUS multiplicative-expression
shift-expression
: additive-expression
| shift-expression LS additive-expression
| shift-expression RS additive-expression
relational-expression
: shift-expression
| relational-expression LESS shift-expression
| relational-expression GREATER shift-expression
| relational-expression LE shift-expression
| relational-expression GE shift-expression
equality-expression
: relational-expression
| equality-expression EQ relational-expression
| equality-expression NE relational-expression
AND-expression
: equality-expression
| AND-expression AMPERSAND equality-expression
exclusive-OR-expression
: AND-expression
| exclusive-OR-expression HAT AND-expression
inclusive-OR-expression
: exclusive-OR-expression
| inclusive-OR-expression OR exclusive-OR-expression
logical-AND-expression
: inclusive-OR-expression
| logical-AND-expression ANDAND inclusive-OR-expression
logical-OR-expression
: logical-AND-expression
| logical-OR-expression OROR logical-AND-expression
conditional-expression
: logical-OR-expression
| logical-OR-expression QUESTION expression COLON conditional-expression
assignment-expression
: conditional-expression
| unary-expression ASSIGNOP assignment-expression
| unary-expression MULTassign assignment-expression
| unary-expression DIVassign assignment-expression
| unary-expression MODassign assignment-expression
| unary-expression PLUSassign assignment-expression
| unary-expression MINUSassign assignment-expression
| unary-expression LSassign assignment-expression
| unary-expression RSassign assignment-expression
| unary-expression ANDassign assignment-expression
| unary-expression ERassign assignment-expression
| unary-expression ORassign assignment-expression
expression
: assignment-expression
constant-expression
: conditional-expression
type-specifier
: typedef-type-specifier
typedef-type-specifier
: TYPEDEFname
identifier-or-typedef-name
: identifier-or-key-word
| TYPEDEFname
type-name
: type-specifier
| type-specifier abstract-declarator
abstract-declarator
: unary-abstract-declarator
| postfix-abstract-declarator
| postfixing-abstract-declarator
postfixing-abstract-declarator
: array-abstract-declarator
| LPAREN RPAREN
array-abstract-declarator
: BRACKETS
| LBRACKET constant-expression RBRACKET
| array-abstract-declarator LBRACKET constant-expression RBRACKET
unary-abstract-declarator
: STAR
| STAR abstract-declarator
postfix-abstract-declarator
: LPAREN unary-abstract-declarator RPAREN
| LPAREN postfix-abstract-declarator RPAREN
| LPAREN postfixing-abstract-declarator RPAREN
| LPAREN unary-abstract-declarator RPAREN postfixing-abstract-declarator
#Cobol#
address
: INTEGERconstant /* Absolute */
| line-address
| address-language /* Language-specific address format */
| LPAREN cobol-expression RPAREN
address-exp
: address
| address-exp PLUS address
| address-exp MINUS address
| address-exp STAR address
address-language
/* Address of, C way (for convenience in COBOL only) */
: AMPERSAND cobol-identifier
/* Address of, COBOL way (COBOL extension by Digital) */
| REFERENCEOF cobol-identifier
assignment-expression
: expression
call-expression
: identifier-or-key-word
| identifier-or-key-word USING cobol-expression-list
cobol-expression
: cobol-identifier
| constant
| string
| cobol-expression PLUS cobol-expression
| cobol-expression MINUS cobol-expression
| cobol-expression STAR cobol-expression
| cobol-expression SLASH cobol-expression
| cobol-expression EXPON cobol-expression
| '-' cobol-expression %prec UMINUS
| '+' cobol-expression %prec UPLUS
| LPAREN cobol-expression RPAREN
cobol-expression-list
: cobol-expression
| cobol-expression COMMA cobol-expression-list
cobol-identifier
: qualification
| subscript
| refmod
condition-expression
: combined-condition
| negated-simple-condition
combined-condition
: negated-simple-condition AND negated-simple-condition
| negated-simple-condition OR negated-simple-condition
| LPAREN combined-condition RPAREN
negated-simple-condition
: simple-condition
| NOT simple-condition
| LPAREN NOT simple-condition RPAREN
simple-condition
: cobol-expression EQ cobol-expression
| cobol-expression ASSIGNOP cobol-expression
| cobol-expression NE cobol-expression
| cobol-expression LESS cobol-expression
| cobol-expression GREATER cobol-expression
| cobol-expression LE cobol-expression
| cobol-expression GE cobol-expression
| cobol-expression SIGNPOS
| cobol-expression SIGNNEG
| cobol-expression SIGNZERO
| cobol-expression SIGNNOTZERO
| LPAREN simple-condition RPAREN
constant
: FLOATINGconstant
| INTEGERconstant
| DECIMALconstant
| CHARACTERconstant
constant-expression
: cobol-expression
expression
: constant-expression
| condition-expression
| address-language
identifier-or-typedef-name
: identifier-or-key-word
loc
: cobol-identifier
| rescoped-expression
loc-address
: AMPERSAND identifier-or-typedef-name
| AMPERSAND identifier-or-typedef-name PLUS INTEGERconstant
| AMPERSAND identifier-or-typedef-name MINUS INTEGERconstant
lvalue-expression
: cobol-identifier
qual-typedef-opt
: TYPEDEFname
| qual-typedef-opt TICK TYPEDEFname
qualification
: identifier-or-key-word OF qualification
| identifier-or-key-word
refmod
: qualification LPAREN cobol-expression COLON RPAREN
| qualification LPAREN cobol-expression COLON cobol-expression RPAREN
| subscript LPAREN cobol-expression COLON RPAREN
| subscript LPAREN cobol-expression COLON cobol-expression RPAREN
subscript
: qualification LPAREN cobol-expression-list RPAREN
unary-expression
: lvalue-expression
whatis-expressions
: expression
| rescoped-expression
| rescoped-typedef