Project

General

Profile

Lexer

Overview

FWD has a lexer that is compatible with Progress 4GL source code. The lexer is responsible for converting a valid, preprocessed Progress 4GL source file (as represented by a stream of characters) into a stream of tokens. A token is a word in the Progress 4GL language, where the word is a set of one or more sequentially located (contiguous) characters. Each token contains:

  • an integer that represents the type of the token
  • the unmodified text from the original source file
  • the line and column numbers that mark the location of the start of the text in the source file

Since the lexer's input is the fully preprocessed source file, the text, line and column numbers are all derived from the preprocessor cache file. This means that this data may not match the originally coded input files. See the chapter on Resolving Parsing Issues in the FWD Conversion Handbook.

The lexer is generated from a grammar encoded in com/goldencode/p2j/uast/progress.g. This is the primary ANTLR input file for the lexer and the output is generated into the ProgressLexer class. In this chapter, the ProgressLexer is simply referred to as the lexer.

The primary output of the lexer is a stream of tokens. That stream of tokens is read by the FWD parser (see the chapter entitled Parser) which constructs an abstract syntax tree (AST) to define the language structure. Each node in the AST corresponds to a token read from the input stream.

The lexer is functionally complete at the OpenEdge v10.1B level.

Symbol Recognition

Symbol resolution in Progress 4GL is complex. The following are the primary reasons:

  • The very large number of language keywords (thousands) in the language adds massive ambiguity that can only be differentiated by context and a list of other rules.
  • With so many keywords, it is a necessity that many or most keywords must be left as unreserved keywords. This means that it is valid for the user to define symbols that duplicate the text of a keyword. Some of the keywords are reserved as is done in most languages, but the majority are not reserved.
  • Some keywords can be arbitrarily abbreviated (e.g. DISPLAY, DISPLA, DISPL and DISP are all the same keyword).
  • Symbol processing is completely case-insensitive. Symbols may be in lowercase, uppercase or any kind of mixed case without any difference in the result.
  • Some keywords are polymorphic (the same language keywords can be used for different meaning depending on context).
  • The basic lexical rules can change based on the context of the language. This means that a single set of consistent lexical rules do not universally apply to all cases.
  • In the Progress 4GL there are 20 or more namespaces including: language keywords, variables, functions, procedures, classes/interfaces, methods, packages, labels, databases, tables, fields, indexes, frames, menus/sub-menus, menu-items, streams, datasets, data-sources, data-relations and queries. User-defined symbols can be duplicated between these namespaces and must be differentiated based on context and precedence rules.
  • Table (including temp-table) and field names are user-defined symbols which can be arbitrarily abbreviated to the shortest unambiguous match. This matching is modified by block structure of the language in relation to the most recently used prior references to tables. These rules are undocumented and somewhat arbitrary.

Some constructs cannot be disambiguated by looking ahead on a character basis. Instead, the context depends upon a lookahead at the token level. This means that such items must be handled by the parser rather than the lexer. For this reason, the lexer is only partially able to participate in the process of symbol resolution.

There are many different types of symbols. Language keywords are the most obvious symbol that are visible in all Progress 4GL source files. Other types include variables, procedure names, function names, labels, temp table names, etc. All of these symbols follow the same basic rules by which they are matched in the lexer. The common symbol rule in the lexer matches all of these types but it cannot set the token type properly since it doesn't have enough information to do so at the time it is matching.

Symbol resolution is the process by which the proper token type is assigned to a token created from a match to the generic symbol rule. In the lexer, the only symbol resolution that can be done is to match with language keywords. Language keywords are given preference over other symbol types in any case where there is a conflict. This is done because there are significantly more locations in the parser that are matching on language keywords than there are locations where a user defined symbol can be in use. Thus it makes sense to handle the conflicts at the smaller number of locations in the parser, and assume that a keyword match is first a keyword. This has a great simplifying effect on the parser design. The result is selected locations in the parser that override (reassign) the token type based on context.

It seems that the parser could provide feedback to the lexer at certain points in its parsing. By storing shared state with the lexer, the lexer could then assign the token type properly instead of taking the "error on the side of keywords" approach which it takes now. However, due to the manner in which the parser does lookahead, this shared state implementation is not possible. The lookahead can be done at a level in the parser at which the context is not yet known (outside of the rules that actually handle the matching). If the lookahead depth (the "k") is greater than 1, then symbolic tokens (with the default token type set) can be returned before the parser can set the state variables that would properly control the assignment of those same tokens. The decoupling of parser lookahead from the rules that know enough to set the state causes it to be infeasible to implement shared state between the parser and the lexer.

Case Sensitivity

Progress 4GL is generally case-insensitive and for this reason this grammar has been designed to ignore case. All symbol definitions use lowercase characters and ANTLR generates code to match both the uppercase and lowercase version of each character.

The Dot Kludge

The dot . character separates language statements, assignments and expressions in Progress 4GL. On the last line of the file, Progress allows the dot to be omitted. To simplify the parser design, the assumption is made that every Progress 4GL source file comes with a dot after the last statement. To compensate for this, the lexer is responsible for injection of a fake dot character if this is the case.

Token Types

The parser primarily (but not exclusively) makes it's matching decisions based on the type of each token. All token types are defined as integer constants in the com.goldencode.p2j.uast.ProgressParserTokenTypes interface that the parser, lexer and other related classes all implement. This allows all of these classes to directly refer to the token types and share this common set of definitions. More specifically, this interface is dynamically generated by ANTLR when the progress.g grammar is processed. That is the time at which integer values are mapped into each token type and the result is written into that interface definition. To examine the exact mapping of integers to the symbolic token type constant names, the ProgressParserTokenTypes.java file must be examined.

Schema Processing

Due to the near total lexical overlap between the file format for schema dumps (.df files) and Progress 4GL source code, the lexer supports a mode with schema-specific keywords such that it can lex the standard schema dump-file. The only difference is the addition of a small set of schema-specific keywords that are activated when used for schema parsing. Once activated in the lexer, it cannot be removed during that run.

See the chapter Schema Loader for details on the syntax and tokens which are accepted.

The following is the list of the keywords that are added in the lexer's keyword dictionary when schema processing is activated:

Full Keyword Text Token Type Notes
abbreviated KW_ABBV  
area KW_AREA  
bigint KW_BIGINT  
crc KW_CRC  
cycle-on-limit KW_CYCLE  
description KW_DESCR  
dump-name KW_DMP_NAME  
field-trigger KW_FLD_TRG  
fixchar KW_FIXCHAR  
frozen KW_FROZEN  
index-field KW_IDX_FLD  
increment KW_INCR  
lob-area KW_LOB_AREA  
lob-bytes KW_LOB_BYTE  
lob-size KW_LOB_SIZE  
no-override KW_NO_OVRRD  
psc KW_PSC  
sequence KW_SEQUENCE  
sql-width KW_SQL_WID  
table-trigger KW_TAB_TRG  
timestamp KW_TIMESTMP  
word KW_WORD_IDX This is a synonym for word-index which already is a documented keyword in the Keyword Index (and which already exists in non-schema mode in the lexer). The word-index keyword cannot be abbreviated normally, but this is essentially a special case abbreviation for that keyword.
valexp KW_VALEXP  
valmsg KW_VALMSG  

None of the above keywords are officially documented in the Progress 4GL documentation. It is known that schema dump files from versions later than OpenEdge v10.1B do contain new keywords that will have to be added to the lexer for schema processing mode. As far as can be known, none of the above keywords support abbreviations and none of them are reserved. These factors are not really at issue in lexing a schema dump file since the file is generated by the data dictionary tools, so the format is quite regular.

Top Level Token Types

At the top level of the lexer, all tokens are one of the following types.

Comments

Matches an entire /* ... */ style comment, including any nested comments. The lexer is defined to create a single token for the entire comment, including nested comments. The result is accumulated into a COMMENT token.

Whitespace is maintained inside the resulting comment text and the lexer's line counter is properly incremented upon encountering a newline.

Since comments and strings are at the same precedence level, each can be embedded in the other.

If the token stream is read by the ProgressParser, the COMMENT token is marked as hidden and is routed to the hidden token stream. The parser then selectively reads from the hidden token stream as needed to make decisions.

Other users of the lexer (such as the SchemaParser) which do not activate hidden processing, will cause this COMMENT token to be dropped from the main token stream (and they cannot be read by the parser because they have been “skipped”).

Whitespace

Matches any amount of whitespace in a program. Each newline character causes the lexer's line counter to be incremented in order to properly maintain each token's line information. The result is accumulated into a WS token.

Spaces (0x20), tabs (0x09), carriage returns (0x0D) and line feeds/newlines (0x0A) are all matched. Although the preprocessor generally removes carriage returns, if the input file was to include a ~015 (escaped carriage return), it would be placed in the output file. For safety, the carriage return processing is left in this rule to ensure that any such matches can be consumed as whitespace. Normally such escaped carriage returns would only be found inside strings, but in complex preprocessor replacements, it is possible that a coding error could leave such characters outside a string in some cases. Progress 4GL is tolerant of such escaped carriage returns so the whitespace rule must also handle this condition.

Non-visible ASCII codes decimal 127 and below are matched here as well. This is text that should not appear in Progress 4GL source code outside of a string or comment. Extended ASCII characters are not matched here. The characters in question: 0x00 through 0x08, 0x0B, 0x0C, 0x0E through 0x1F and 0x7F.

If the token stream is read by the ProgressParser, the WS token is marked as hidden and is routed to the hidden token stream. The parser then selectively reads from the hidden token stream as needed to make decisions.

Other users of the lexer (such as the SchemaParser) which do not activate hidden processing, will cause this WS token to be dropped from the main token stream (and they cannot be read by the parser because they have been “skipped”).

Operators

The following operators are supported:

Input Text Output Token Type Operator Type Notes
= EQUALS Comparison  
EQ KW_EQ Comparison Coerced to EQUALS by the parser.
<> NOT_EQ Comparison  
NE KW_NE Comparison Coerced to NOT_EQ by the parser.
> GT Comparison  
GT KW_GT Comparison Coerced to GT by the parser.
< LT Comparison  
LT KW_LT Comparison Coerced to LT by the parser.
>= GTE Comparison  
GE KW_GTE Comparison Coerced to GTE by the parser.
<= LTE Comparison  
LE KW_LTE Comparison Coerced to LTE by the parser.
+ PLUS Arithmetic  
- MINUS Arithmetic  
* MULTIPLY Arithmetic  
/ DIVIDE Arithmetic  
MOD, MODU,
MODUL
MODULO
KW_MOD Arithmetic  
( LPAREN Precedence  
) RPAREN Precedence  
[ RBRACKET Array Subscripting  
] LBRACKET Array Subscripting  

In Progress 4GL, the assignment operator is the same as the operator for EQUALS. The parser must differentiate these based on context.

Statement or Parameter Separators

The following separator characters are processed:

Input Text Output Token Type Notes
. DOT This is the “standalone” use of the period character as an end of statement delimiter. The same character is used in the following cases which are excluded:
     inside a string literal or comment
     as a decimal point
     inside a filename
     as a date field separator (like / or -)
     as a database name separator (e.g. database.table.field)
     inside a library reference
In all of the above cases, the . character can be present and it will not be matched as the DOT token.
: COLON The hidden token stream can be used to determine whether the colon was followed by whitespace or not. This is needed in the parser to differentiate between labels (which must always be followed by whitespace) and attributes/methods where the colon cannot be followed by whitespace.
, COMMA  
@ AT  

String Literals

Matches various string literal types depending upon the processing mode: raw, export or normal.

In raw processing mode, matches a double-quoted string encoded string which represents encoded binary (i.e., raw) data, setting the token type to RAW_STRING. Matches an opening double quote, arbitrary contents and an ending double quote. Opening and closing double quotes are discarded. No assumptions are made about the contents of the string, except that it will not contain an instance of a double quote, since this is the end delimiter. All other data is accepted exactly as is. No decoding is performed. This mode is only used by code that is reading files written using the EXPORT language statement or the equivalent. The FWD tools only use this mode when calculating field length statistics on the exported .d data files. This mode can be enabled and disabled dynamically and the code that uses this only enables it when the field being parsed is known to be of the RAW data type.

If not in raw mode, the lexer checks if it is in export processing mode. In export mode, the lexer matches a double-quoted string which represents a Progress string as it would appear at runtime. Export strings are essentially runtime strings which have no escape sequences, except an embedded double quote character &quot; is doubled up as &quot;" to avoid confusion with the closing delimiter. In this case, the lexer will match an opening double quote, arbitrary contents and an ending double quote. Two contiguous double quote characters are accepted as contents (they do not terminate the string), but they are collapsed into one double quote character. Opening and closing double quotes are discarded. This mode is only used by code that is reading files written using the EXPORT language statement or the equivalent. The FWD tools only use this mode when calculating field length statistics on the exported .d data files. Once set into export mode, it cannot be reset to normal mode. However, since raw mode supersedes export and normal modes and since raw mode can be dynamically enabled and disabled, the export mode can be temporarily switched into raw mode when needed.

Except for raw mode, the result of any string literal parsing is a STRING token.

In both export and normal modes, any newlines inside the string are identified and the lexer's internal newline counter is properly maintained.

In normal mode, the lexer matches a single or double quoted string followed by any (optional) string options. The lexical rules for both string types are identical except for the delimiting quote character. For single quoted strings, the delimiter is the ' character, for double quoted strings the delimiter is the character. The key here is that whichever delimiter character starts the string must also end the string. The other character can be freely included in the contents of the string. This means that the following are legal string literals:

“It's not a single quoted string!”
'Some “tests” are better than others!'

In the following description the term quote will refer to whichever starting and ending quote character is used for the string being lexed.

The lexer matches an opening quote, arbitrary contents and an ending quote. Two contiguous quote characters and an escape prefixed quote character are accepted as contents (they do not terminate the string). As noted above double quote characters can be freely used inside single quote delimited strings and vice versa. Tabs and spaces and all non-printing characters are maintained inside strings (including embedded binary control characters). Any Unicode character can be included in the contents of a string. This matches the internationalization support that Progress 4GL provides.

Any newlines inside the string are identified and the lexer's internal newline counter is properly maintained. All such newlines are maintained in the output string because these are the escaped chars that have been left behind by the preprocessor. If such characters are not escaped, then the preprocessor will have removed those characters (carriage returns and line feeds). This is the same as how Progress 4GL handles these characters. This means that in an input file that has not been preprocessed, a string literal can be split across any number of lines and the Progress preprocessor will put the string back together, ignoring the carriage returns and newlines.

Tilde and the backslash can BOTH be Progress escape characters and as such, they need special attention. Backslash is only honored if UNIX escapes mode is set on. In particular, string lexing matches 3 or 6 constructs as part of a string depending on which escape sequences are honored. For single quoted strings:

~'
\'
~~
~\
\\
\~
~
\

For double quoted strings:

~'
\'
~~
~\
\\
\~
~
\

In either case, the first 2 are a way of embedding a quote in a string. The next 4 are important because if this the lexer were to encounter '~~', '\\', '~\' or '\~' (which are valid strings) the rule would consume the first escape and then encounter an escaped quote which would not terminate the string properly, leading to a non-ending string. The lexer matches on any escaped escape char to eliminate this situation. Finally, a single ~ or \ that is not followed by a " or a duplicate escape character is matched as a single character. For contents, anything that isn't an unescaped quote character is valid, including whitespace and other control characters. As opposed to the results in raw and export mode, in normal mode the enclosing quotation marks are not deleted. This allows the downstream processing to know exactly which kind of quotation marks were used in the original code.

In normal mode, the lexer will also match the options that can be appended to a Progress 4GL string literal. These options consist of 4 parts, some of which are not required. String options always start with a : which must follow the string's ending single or double quote with no intervening whitespace. After that colon, there must be one or more of a justification, size allocation in characters and a flag noting if this string is translatable or not.

justification          'r' | 'l' | 'c' | 't'
translatable           'u'
size                   integer literal (one or more contiguous digits)

These options can come in any order and at least one of them must appear. Whitespace cannot be placed between any of the options.

Since comments and strings are at the same precedence level, each can be embedded in the other.

The entire contents of a lexed string is placed into the text of the resulting single STRING or RAW_STRING token.

Integer or Decimal Literals

Integer constants will lex as token type NUM_LITERAL. The following cases are matched:

  • a sequence of one or more digits (without a following decimal point and additional digits)
  • - or + sign character followed by a sequence of one or more digits (without a following decimal point and additional digits)
  • a sequence of one or more digits (without a following decimal point and additional digits) followed by a postfixed sign (negative - or positive +)
  • a sequence of one or more digits followed by a . but no additional following digits (it does not consume the following . in this case)
  • - or + character followed by a sequence of one or more digits followed by a . but no additional following digits (it does not consume the following . in this case)

Decimal constants will lex as token type DEC_LITERAL. The following cases are matched:

  • one or more numeric digits followed by a decimal point and another sequence of numeric digits
  • - or + sign character followed by digits and then a . (decimal point) and more digits
  • - or + sign character followed by a . and digits
  • one or more numeric digits followed by a decimal point and another sequence of numeric digits with a postfixed - of + sign character
  • a decimal point followed by a sequence of numeric digits as a decimal constant
  • a decimal point followed by a sequence of numeric digits as a decimal constant with a postfixed - of + sign character

The key to this processing is that there cannot be any intervening whitespace between digits and decimal points. Likewise, there cannot be any intervening whitespace between a leading or trailing '-' or '+' and the numeric or decimal literal it precedes or follows respectively. In such a case the '-' is lexed as a MINUS token, the '+' is lexed as a PLUS token and the parser must use context to determine if it is a unary or binary operator.

Any use of the + sign character (leading or postfixed) is discarded as syntactic sugar.

In the case of a decimal with no digits on the right side of the decimal point, this is always interpreted as an integer literal and a subsequent 2nd token of DOT. This oddity cannot be easily resolved but interestingly enough this is exactly how Progress 4GL itself handles this situation and this is a perfectly valid match since it essentially is an integer.

Although the runtime Progress 4GL processing allows formatting of numbers to include a numeric group separator (which defaults to a comma, but can be overridden), group separators of any kind cannot be used in integer or decimal constants.

Although the runtime Progress 4GL processing allows formatting of numbers to be generated with a locale-specific decimal separator (which defaults to a period but can be overridden), only the . can be used as a decimal separator (the decimal point) in integer or decimal constants.

Date Literals

Date literals are not documented but are fully supported in Progress 4GL. FWD lexes these constants as a single token of type DATE_LITERAL.

The lexer matches digits followed by a separator (-, / or .) and one or two following digits. If there are no following digits after the separator, then it is not matched as a date, instead it is an integer literal followed by an operator. The second separator for the year portion is optional, as is the year itself and there is an optional negative sign for BC dates. The second separator can also be any of the same separator characters. Interestingly, the first and second separators can be any combination of these characters (the two separators don't have to be the same character in a single date literal).

The key to this lexing is that there cannot be any intervening whitespace between digits and the date separators.

Date literals are generally matched in mm/dd/yyyy or mm-dd-yyyy formats, although the -, / or . separators can be mixed in the same literal (mm-dd/yyyy or mm/dd-yyyy). Both months and days can be specified in 1 or 2 digits. Generally, any separator character can be used, although in Progress one cannot use the - between the mm and dd if the constant is being used in an expression. This lexer has no such limitation. There can be an optional negative sign preceding any year digits and one can specify a dd and yyyy separator without specifying any year digits at all. Any number of year digits are valid, though in Progress the year 0 is treated specially. A year of 0, -0 and 00 all are valid and resolve to the year 2000. A year of 000, 0000, 00000 (and so on...), -00 and -000 (and so on...) are all invalid. In Progress 4GL, these invalid cases each complain about specifying the year 0.

So y, yy, yyy, yyyy, yyyyy... and -y, -yy, -yyy, -yyyy... all are valid year specifications, except for the specific year zero issue noted above. These limitations on how the year digits work are not implemented here. Over all, this rule supports a superset of the possible date literal formats in Progress 4GL and no checking of the values is done.

See the section below on Date Literal Limitations for details on those date literal features that are not supported.

Unknown Value Literal

The question mark ? when found outside of a string literal or comment, is matched and the result is an UNKNOWN_VAL token.

User-Defined Symbol

All symbols must start with an alphabetic character. Starting in the second character and continuing to a maximum of 32 characters (including the initial character), can be any alphabetic and numeric characters or one of the special symbol characters (# $ % & - _). Symbols are matched case-insensitively.

An exception to the previous rule that a symbol must start with an alphabetic character is for special meta-data entries in the Progress schema dictionary, whose table and field names start with an underscore. For this reason, such entries are allowed more generally such that the rule as implemented is: the first letter of every symbol must be an alphabetic character or an underscore.

The result of this is a token of type SYMBOL. An underscore _ can be matched by itself. The result does not have a token type of its own, it is a generic symbol if found on its own.

The SYMBOL lexing process has post-processing that may modify the resulting token type to more closely match the meaning of the symbol. Please see the sections on Language Keyword, Filename, R-Code Library Reference and Database Symbol for more details.

Language Keyword

Once a symbol has been found, the text of that symbol is used in a keyword lookup. That lookup utilizes a dictionary of the keywords, whether they are reserved or not and their possible abbreviations. If a match is found, the token type is overridden from the default (SYMBOL) to the artificial token type associated with the keyword (see com.goldencode.p2j.uast.ProgressLexer.initializeKeywordDictionary()). The text is not modified.

The parser may subsequently override this token type yet again (based on context), but this is the extent of the lexer's symbol resolution. Keyword token types take precedence over the default token type SYMBOL.

The lexer provides a mechanism to specify keywords that should be ignored. This provides the backing support for the keyword ignore list that both Progress 4GL and FWD support. The idea is that those keywords are removed from the lexer's keyword dictionary. The result is that the specified keyword's token type will never appear in the lexer's output. Instead the text will appear as a SYMBOL and can be used for user-defined names.

It is beyond the scope of this book to duplicate the full list of Progress 4GL keywords which are supported. For that, the book from Progress Software Corporation entitled Progress Language Reference has a Keyword Index which is useful in this regard. However, it is interesting to note that there are many deviations from the keyword index and there are undocumented keywords required to be implemented in the lexer.

The following is the list of the differences that exist between the FWD lexer's keyword processing and that which is documented in the official Progress 4GL Keyword Index. These differences are believed to be correct in FWD and simply reflect defects in the Progress documentation. If a keyword appears in the OpenEdge v10.1B Keyword Index and does not appear here, it can be assumed that the keyword is included in the lexer's keyword dictionary with the same settings as documented in the Keyword Index.

The Minimum Match Characters column indicates the abbreviation support for the given keyword. If that value is set to 0, no abbreviation is possible. Otherwise, the number represents the minimum number of characters at the front of the keyword that must be present to match that keyword.

Full Keyword Text Token Type Minimum Match Characters Reserved Keyword? Notes
_cbit KW_CBIT 0 No Completely undocumented.
_control KW_U_CTRL 0 Yes Completely undocumented.
_msg KW_U_MSG 0 Yes Completely undocumented.
_pcontrol KW_U_PCTRL 0 Yes Completely undocumented.
_serial-num KW_U_SERIAL 7 Yes Completely undocumented.
abort KW_ABORT 0 No Missing in the keyword index, found elsewhere in the language reference.
accept-changes KW_ACC_CHG 0 No Missing in the keyword index, untested at this time.
accept-row-changes KW_ACC_RCHG 0 No Missing in the keyword index, untested at this time.
accumulate KW_ACCUM 5 Yes Handles the “separate” keyword accum as well.
active KW_ACTIVE 0 No Missing in the keyword index, untested at this time.
actor KW_ACTOR 0 No Missing in the keyword index, untested at this time.
add-header-entry KW_ADD_HENT 0 No Missing in the keyword index, untested at this time.
add-interval KW_ADD_INVL 0 No Missing in the keyword index, untested at this time.
add-relation KW_ADD_REL 0 No Missing in the keyword index, untested at this time.
add-source-buffer KW_ADD_SRCB 0 No Missing in the keyword index, untested at this time.
adm-timing-out KW_ADM_TO 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
after-buffer KW_AFT_BUFF 0 No Missing in the keyword index, untested at this time.
after-fill KW_AFT_FILL 0 No Missing in the keyword index, untested at this time.
after-row-fill KW_AFT_R_F 0 No Missing in the keyword index, untested at this time.
after-rowid KW_AFT_ROID 0 No Missing in the keyword index, untested at this time.
after-table KW_AFT_TBL 0 No Missing in the keyword index, untested at this time.
analyze KW_ANALYZ 6 Yes Completely undocumented.
any-key KW_ANY_KEY 0 No Missing in the keyword index, found elsewhere in the language reference.
any-printable KW_ANY_PRT 0 No Missing in the keyword index, found elsewhere in the language reference.
append-line KW_APPEND_L 0 No Missing in the keyword index, found in customer source.
apply-callback KW_APPL_CBK 0 No Missing in the keyword index, untested at this time.
asc KW_ASC 0 No Technically, this is a duplicate keyword with ASCENDING (abbrv of 3) but this is made separate to allow its use for the built-in function ASC.
asciitohtml KW_ASCII_2H 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
attach-data-source KW_ATT_DSRC 0 No Missing in the keyword index, untested at this time.
auto-delete KW_AUTO_DEL 0 No Missing in the keyword index, untested at this time.
auto-delete-xml KW_AUTO_D_X 0 No Missing in the keyword index, found elsewhere in the language reference.
available-messages KW_AVL_MSGS 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
basic-logging KW_BAS_LOGG 0 No Missing in the keyword index, untested at this time.
before-buffer KW_B4_BUFF 0 No Missing in the keyword index, untested at this time.
before-fill KW_B4_FILL 0 No Missing in the keyword index, untested at this time.
before-row-fill KW_B4_R_F 0 No Missing in the keyword index, untested at this time.
before-rowid KW_B4_ROWID 0 No Missing in the keyword index, untested at this time.
before-table KW_B4_TABLE 0 No Missing in the keyword index, untested at this time.
blob KW_BLOB 0 No Missing in the keyword index, untested at this time.
both KW_BOTH 0 No Missing in the keyword index, found elsewhere in the language reference.
bottom KW_BOTTOM 0 No Missing in the keyword index, found elsewhere in the language reference.
btos KW_BTOS 0 Yes Completely undocumented.
buffer-validate KW_BUF_VLID 0 No Missing in the keyword index, untested at this time.
buttons KW_BUTTON 6 No Handles both buttons and the “separate” keyword button.
by-reference KW_BY_REF 0 No Missing in the keyword index, found elsewhere in the language reference.
by-value KW_BY_VALUE 0 No Missing in the keyword index, found elsewhere in the language reference.
byte KW_BYTE 0 No Missing in the keyword index, found elsewhere in the the external program Interface reference.
upper KW_CAPS 0 No Missing in the keyword index, found elsewhere in the the SQL reference.
character_length KW_CHAR_LEN 0 No Possible SQL keyword in the keyword index but no reference was found in the SQL 89 reference.
check-agent-mode KW_CHECK_AM 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
child-buffer KW_CHLD_BUF 0 No Missing in the keyword index, untested at this time.
clob KW_CLOB 0 No Missing in the keyword index, untested at this time.
closeallprocs KW_CLOSE_AP 0 No Missing in the keyword index, found elsewhere in the language reference.
column-codepage KW_COL_CP 0 No Missing in the keyword index, untested at this time.
com-handle KW_COM_HNDL 0 No Missing in the keyword index, found elsewhere in the the external program Interface reference.
control-name KW_CNTRL_NM 0 No Missing in the keyword index, found elsewhere in the language reference.
controls KW_CONTROLS 0 No Missing in the keyword index, found elsewhere in the language reference.
convert-datetime KW_CVT_DT 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
cookie-date KW_COOKIE_D 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
ctos KW_CTOS 0 Yes Completely undocumented.
currency KW_CURRENCY 0 No Missing in the keyword index, found elsewhere in the language reference.
current_date KW_CUR_DATE 0 No Possible SQL keyword in the keyword index but no reference was found in the SQL 89 reference.
cursor-down KW_CUR_DOWN 0 No Missing in the keyword index, found elsewhere in the language reference.
cursor-left KW_CUR_LEFT 0 No Missing in the keyword index, found elsewhere in the language reference.
cursor-right KW_CUR_RGHT 0 No Missing in the keyword index, found elsewhere in the language reference.
cursor-up KW_CUR_UP 0 No Missing in the keyword index, found elsewhere in the language reference.
data-relation KW_DATA_REL 0 No Missing in the keyword index, untested at this time.
datetime KW_DATETIME 0 No Missing in the keyword index, untested at this time.
datetime-tz KW_DATE_TZ 0 No Missing in the keyword index, untested at this time.
dde-notify KW_DDE_NOTI 0 No Missing in the keyword index, found elsewhere in the language reference.
default-action KW_DEF_ACTN 0 No Missing in the keyword index, found elsewhere in the language reference.
deletecookie KW_DEL_COOK 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
delete-cookie KW_DEL_COOK 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
delete-header-entry KW_DEL_H_EN 0- No Missing in the keyword index, untested at this time.
descending KW_DESCEND 4 Yes Also handles the “separate” keyword desc.
detach-data-source KW_DET_DSRC 0 No Missing in the keyword index, untested at this time.
dispatch KW_DISPATCH 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
display-timezone KW_DISP_TZ 0 No Missing in the keyword index, untested at this time.
dump-logging-now KW_DUMP_LGN 0 No Missing in the keyword index, untested at this time.
dynamic-current-value KW_DYN_CURV 0 No Missing in the keyword index, untested at this time.
dynamic-next-value KW_DYN_NEXV 0 No Missing in the keyword index, untested at this time.
editor-tab KW_EDIT_TAB 0 No Missing in the keyword index, found in the programming handbook.
empty-dataset KW_EMPTY_DS 0 No Missing in the keyword index, untested at this time.
empty-selection KW_EMPTY_SN 0 No Missing in the keyword index, found elsewhere in the language reference.
enable-events KW_ENABLE_E 0 No Missing in the keyword index, found elsewhere in the language reference.
end-box-selection KW_END_B_SN 0 No Missing in the keyword index, found elsewhere in the language reference.
end-search KW_END_SEAR 0 No Missing in the keyword index, found elsewhere in the language reference.
enter-menubar KW_ENTER_MB 0 No Missing in the keyword index, found elsewhere in the language reference.
entry-types-list KW_ENT_TLST 0 No Missing in the keyword index, untested at this time.
error-code KW_ERR_CODE 0 No Missing in the keyword index, found elsewhere in the the external program Interface reference.
error-object-detail KW_ERR_OBJD 0 No Missing in the keyword index, untested at this time.
error-string KW_ERR_STR 0 No Missing in the keyword index, untested at this time.
execution-log KW_EXEC_LOG 0 No Missing in the keyword index, untested at this time.
fields KW_FIELD 5 Yes Also handles the separate keyword “field”.
fill-mode KW_FILL_MOD 0 No Missing in the keyword index, untested at this time.
fill-where-string KW_FILL_WST 0 No Missing in the keyword index, untested at this time.
find-failed KW_FIND_FD 0 No Missing in the keyword index, untested at this time.
first-data-source KW_FIRST_DS 0 No Missing in the keyword index, untested at this time.
first-dataset KW_FIR_DSET 0 No Missing in the keyword index, untested at this time.
first-query KW_FIRST_QR 0 No Missing in the keyword index, untested at this time.
fix-codepage KW_FIX_CP 0 No Missing in the keyword index, untested at this time.
format KW_FORMAT 4 Yes Also handles the separate keyword “form”.
format-datetime KW_FMT_DT 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
forward-only KW_FWD_ONLY 0 No Missing in the keyword index, untested at this time.
forwards KW_FORWARD 7 No Also handles the separate keyword “forward”.
getattribute KW_GETATTRI 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
get-callback-proc-context KW_GET_CBPC 0 No Missing in the keyword index, untested at this time.
get-callback-proc-name KW_GET_CBPN 0 No Missing in the keyword index, untested at this time.
getcgi KW_GET_CGI 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
get-cgi KW_GET_CGI 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
get-cgi-long KW_GET_CGL 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
get-changes KW_GET_CHG 0 No Missing in the keyword index, untested at this time.
get-child-relation KW_GET_CREL 0 No Missing in the keyword index, untested at this time.
get-codepage KW_GET_CODP 0 No Missing in the keyword index, untested at this time.
get-collation KW_GET_CLL 0 No Missing in the keyword index, untested at this time.
getcookie KW_GET_COOK 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
get-cookie KW_GET_COOK 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
get-config KW_GET_CFG 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
get-dataset-buffer KW_GET_DS_B 0 No Missing in the keyword index, untested at this time.
get-dir KW_GET_DIR 0 No Missing in the keyword index, untested at this time.
getfield KW_GET_FLD 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
get-field KW_GET_FLD 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
get-header-entry KW_GET_HD_E 0 No Missing in the keyword index, untested at this time.
get-long-value KW_GET_L_V 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
get-message-groups KW_GET_MSGG 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
get-messages KW_GET_MSGS 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
get-node KW_GET_NODE 0 No Missing in the keyword index, untested at this time.
get-relation KW_GET_REL 0 No Missing in the keyword index, untested at this time.
get-serialized KW_GET_SER 0 No Missing in the keyword index, untested at this time.
get-source-buffer KW_GET_SRCB 0 No Missing in the keyword index, untested at this time.
get-top-buffer KW_GET_TOPB 0 No Missing in the keyword index, untested at this time.
get-transaction-state KW_GET_T_S 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
get-user-field KW_GET_U_F 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
get-value KW_GET_VAL 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
group-box KW_GROUP_BX 0 No Missing in the keyword index, untested at this time.
has-lobs KW_HAS_LOBS 0 No Missing in the keyword index, untested at this time.
hidden-field KW_HID_FLD 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
hidden-field-list KW_HID_FLD 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
hint KW_HINT 0 No Missing in the keyword index, found elsewhere in the language reference.
home KW_HOME 0 No Missing in the keyword index, found elsewhere in the language reference.
html-encode KW_HTML_ENC 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
htmlerror KW_HTMLERR 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
honorprokeys KW_HONOR_PK 0 No Missing in the keyword index, found elsewhere in the language reference.
honorreturnkey KW_HONOR_RK 0 No Missing in the keyword index, found elsewhere in the language reference.
ignore-current-modified KW_IGN_CMOD 0 No Missing in the keyword index, untested at this time.
inherit-bgcolor KW_INH_BGC 0 No Missing in the keyword index, untested at this time.
inherit-fgcolor KW_INH_FGC 0 No Missing in the keyword index, untested at this time.
init-session KW_INIT_SES 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
inner KW_INNER 0 No Missing in the keyword index, found elsewhere in the language reference.
input-value KW_SCRN_VAL 0 No Missing in the keyword index, found in a product update bulletin.
insert-mode KW_INS_MODE 0 No Missing in the keyword index, found elsewhere in the language reference.
instantiating-procedure KW_INST_PRC 0 No Missing in the keyword index, untested at this time.
interval KW_INTERVAL 0 No Missing in the keyword index, untested at this time.
is-codepage-fixed KW_IS_CP_FX 0 No Missing in the keyword index, untested at this time.
is-column-codepage KW_IS_COLCP 0 No Missing in the keyword index, untested at this time.
is-xml KW_IS_XML 0 No Missing in the keyword index, found elsewhere in the language reference.
iso-date KW_ISO_DATE 0 No Missing in the keyword index, untested at this time.
iteration-changed KW_ITER_CHG 0 No Missing in the keyword index, found elsewhere in the language reference.
iunknown KW_IUNKNOWN 0 No Missing in the keyword index, found in the external program interface reference.
lower KW_LC 0 No Missing in the keyword index, found in SQL 89 reference.
left KW_LEFT 0 No Missing in the keyword index, found elsewhere in the language reference.
left-end KW_LEFT_END 0 No Missing in the keyword index, found elsewhere in the language reference.
left-mouse-click KW_LEFT_MC 0 No Missing in the keyword index, found elsewhere in the language reference.
left-mouse-dblclick KW_LEFT_MDC 0 No Missing in the keyword index, found elsewhere in the language reference.
left-mouse-down KW_LEFT_MD 0 No Missing in the keyword index, found elsewhere in the language reference.
left-mouse-up KW_LEFT_MU 0 No Missing in the keyword index, found elsewhere in the language reference.
loadcontrols KW_LOADCTRL 0 No Missing in the keyword index, found elsewhere in the language reference.
lob-dir KW_LOB_DIR 0 No Missing in the keyword index, untested at this time.
log-entry-types KW_LOG_EN_T 0 No Missing in the keyword index, untested at this time.
log-threshold KW_LOG_THRS 0 No Missing in the keyword index, untested at this time.
logfile-name KW_LOGF_NAM 0 No Missing in the keyword index, untested at this time.
logging-level KW_LOGG_LEV 0 No Missing in the keyword index, untested at this time.
long KW_LONG 0 No Missing in the keyword index, found elsewhere in the language reference.
longchar KW_LONGCHAR 0 No Missing in the keyword index, untested at this time.
longchar-to-node-value KW_LCHR_2NV 0 No Missing in the keyword index, untested at this time.
maximum KW_MAX 3 No Also handles separate keyword “max”.
md5-value KW_MD5_VAL 0 No Missing in the keyword index, untested at this time.
menu-drop KW_MENU_DRP 0 No Missing in the keyword index, found elsewhere in the language reference.
merge-changes KW_MERGE_CH 0 No Missing in the keyword index, untested at this time.
merge-row-changes KW_MERGE_RC 0 No Missing in the keyword index, untested at this time.
middle-mouse-click KW_MDL_MC 0 No Missing in the keyword index, found elsewhere in the language reference.
middle-mouse-dblclick KW_MDL_MDC 0 No Missing in the keyword index, found elsewhere in the language reference.
middle-mouse-down KW_MDL_MD 0 No Missing in the keyword index, found elsewhere in the language reference.
middle-mouse-up KW_MDL_MU 0 No Missing in the keyword index, found elsewhere in the language reference.
minimum KW_MIN 3 No Also handles the separate keyword “min”.
min-column-width-chars KW_MIN_CWCH 0 No Missing in the keyword index, untested at this time.
min-column-width-pixels KW_MIN_CWPX 0 No Missing in the keyword index, untested at this time.
min-schema-marshal KW_MIN_SCHM 0 No Missing in the keyword index, untested at this time.
mouse-extend-click KW_MOU_XC 0 No Missing in the keyword index, found elsewhere in the language reference.
mouse-extend-dblclick KW_MOU_XDC 0 No Missing in the keyword index, found elsewhere in the language reference.
mouse-extend-down KW_MOU_XD 0 No Missing in the keyword index, found elsewhere in the language reference.
mouse-extend-up KW_MOU_XU 0 No Missing in the keyword index, found elsewhere in the language reference.
mouse-menu-click KW_MOU_MC 0 No Missing in the keyword index, found elsewhere in the language reference.
mouse-menu-dblclick KW_MOU_MDC 0 No Missing in the keyword index, found elsewhere in the language reference.
mouse-menu-down KW_MOU_MD 0 No Missing in the keyword index, found elsewhere in the language reference.
mouse-menu-up KW_MOU_MU 0 No Missing in the keyword index, found elsewhere in the language reference.
mouse-move-click KW_MOU_MVC 0 No Missing in the keyword index, found elsewhere in the language reference.
mouse-move-dblclick KW_MOU_MVDC 0 No Missing in the keyword index, found elsewhere in the language reference.
mouse-move-down KW_MOU_MVD 0 No Missing in the keyword index, found elsewhere in the language reference.
mouse-move-up KW_MOU_MVU 0 No Missing in the keyword index, found elsewhere in the language reference.
mouse-select-click KW_MOU_SC 0 No Missing in the keyword index, found elsewhere in the language reference.
mouse-select-dblclick KW_MOU_SDC 0 No Missing in the keyword index, found elsewhere in the language reference.
mouse-select-down KW_MOU_SD 0 No Missing in the keyword index, found elsewhere in the language reference.
mouse-select-up KW_MOU_SU 0 No Missing in the keyword index, found elsewhere in the language reference.
mtime KW_MTIME 0 No Missing in the keyword index, untested at this time.
must-understand KW_MUST_UND 0 No Missing in the keyword index, untested at this time.
nested KW_NESTED 0 No Missing in the keyword index, untested at this time.
new-line KW_NEW_LINE 0 No Missing in the keyword index, found in application source code.
no-return-value KW_NO_RET_V 13 Yes Missing in the keyword index, found external program interface reference.
no-schema-marshal KW_NO_SCH_M 0 No Missing in the keyword index, untested at this time.
node-value-to-longchar KW_NODV_2LC 0 No Missing in the keyword index, untested at this time.
num-child-relations KW_NUM_CH_R 0 No Missing in the keyword index, untested at this time.
num-header-entries KW_NUM_HD_E 0 No Missing in the keyword index, untested at this time.
num-log-files KW_NUM_LOGF 0 No Missing in the keyword index, untested at this time.
num-relations KW_NUM_REL 0 No Missing in the keyword index, untested at this time.
num-source-buffers KW_NUM_SRCB 0 No Missing in the keyword index, untested at this time.
num-top-buffers KW_NUM_TOPB 0 No Missing in the keyword index, untested at this time.
off-end KW_OFF_END 0 No Missing in the keyword index, found elsewhere in the language reference.
off-home KW_OFF_HOME 0 No Missing in the keyword index, found elsewhere in the language reference.
order KW_ORDER 0 No Missing in the keyword index, found in the SQL 89 reference.
origin-handle KW_ORG_HAND 0 No Missing in the keyword index, untested at this time.
origin-rowid KW_ORG_ROID 0 No Missing in the keyword index, untested at this time.
os2 KW_OS2 0 Yes Completely undocumented.
outer-join KW_OUT_JOIN 0 No Missing in the keyword index, found elsewhere in the language reference.
outer KW_OUTER 0 No Missing in the keyword index, found elsewhere in the language reference.
outputcontenttype KW_OUTPUTCT 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
output-content-type KW_OUTPUTCT 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
outputheaders KW_OUT_HDR 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
outputheader KW_OUT_HDR 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
outputhttpheader KW_OUT_HH 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
output-http-header KW_OUT_HH 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
output-messages KW_OUT_MSGS 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
parent-buffer KW_PAR_BUFF 0 No Missing in the keyword index, untested at this time.
parent-relation KW_PAR_REL 0 No Missing in the keyword index, untested at this time.
parent-window-close KW_PAR_W_C 0 No Missing in the keyword index, found elsewhere in the language reference.
performance KW_PERF 0 No Missing in the keyword index, found elsewhere in the language reference.
procedure-complete KW_PROC_COM 0 No Missing in the keyword index, found elsewhere in the language reference.
process-web-request KW_PROC_W_R 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
prodataset KW_PRODATAS 0 No Missing in the keyword index, untested at this time.
put-unsigned-short KW_PUT_USHT 0 No Missing in the keyword index, found elsewhere in the language reference.
queue-message KW_QUE_MSG 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
read-response KW_READ_RES 0 No Missing in the keyword index, found elsewhere in the language reference.
reject-changes KW_REJ_CHGS 0 No Missing in the keyword index, untested at this time.
reject-row-change KW_REJ_RCHG 0 No Missing in the keyword index, untested at this time.
rejected KW_REJECTED 0 No Missing in the keyword index, untested at this time.
relation-fields KW_REL_FLDS 0 No Missing in the keyword index, untested at this time.
relations-active KW_RELS_ACT 0 No Missing in the keyword index, untested at this time.
right KW_RIGHT 0 No Missing in the keyword index, found elsewhere in the language reference.
right-end KW_RT_END 0 No Missing in the keyword index, found elsewhere in the language reference.
right-mouse-click KW_RT_MC 0 No Missing in the keyword index, found elsewhere in the language reference.
right-mouse-dblclick KW_RT_MDC 0 No Missing in the keyword index, found elsewhere in the language reference.
right-mouse-down KW_RT_MD 0 No Missing in the keyword index, found elsewhere in the language reference.
right-mouse-up KW_RT_MU 0 No Missing in the keyword index, found elsewhere in the language reference.
rounded KW_ROUNDED 0 No Missing in the keyword index, untested at this time.
row-create KW_ROW_CRT 0 No Missing in the keyword index, untested at this time.
row-delete KW_ROW_DEL 0 No Missing in the keyword index, untested at this time.
row-display KW_ROW_DISP 0 No Missing in the keyword index, found elsewhere in the language reference.
row-entry KW_ROW_ENTR 0 No Missing in the keyword index, found elsewhere in the language reference.
row-leave KW_ROW_LEAV 0 No Missing in the keyword index, found elsewhere in the language reference.
row-state KW_ROW_STAT 0 No Missing in the keyword index, untested at this time.
row-update KW_ROW_UPD 0 No Missing in the keyword index, untested at this time.
rowid KW_ROWID 0 No Documented in the keyword index as reserved, but this has been found to be unreserved.
run-web-object KW_RUN_W_O 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
save-row-changes KW_SAVE_RCH 0 No Missing in the keyword index, untested at this time.
save-where-string KW_SAVE_WST 0 No Missing in the keyword index, untested at this time.
sax-attributes KW_SAX_ATTR 0 No Missing in the keyword index, untested at this time.
sax-reader KW_SAX_READ 0 No Missing in the keyword index, untested at this time.
schema-change KW_SCH_CHG 0 No Missing in the keyword index, untested at this time.
scroll-mode KW_SCR_MODE 0 No Missing in the keyword index, found elsewhere in the language reference.
scroll-notify KW_SCR_NOT 0 No Missing in the keyword index, found elsewhere in the language reference.
server-socket KW_SRV_SOCK 0 No Missing in the keyword index, found elsewhere in the language reference.
session-end KW_SESS_END 0 No Missing in the keyword index, untested at this time.
set-actor KW_SET_ACTOR 0 No Missing in the keyword index, untested at this time.
set-attribute-list KW_SET_A_L 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
set-callback-procedure KW_SET_CB_P 0 No Missing in the keyword index, untested at this time.
setcookie KW_SET_COOK 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
set-cookie KW_SET_COOK 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
set-must-understand KW_SET_M_UN 0 No Missing in the keyword index, untested at this time.
set-node KW_SET_NODE 0 No Missing in the keyword index, untested at this time.
set-serialized KW_SET_SERD 0 No Missing in the keyword index, untested at this time.
set-transaction-state KW_SET_T_S 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
set-user-field KW_SET_U_F 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
setwebstate KW_SET_W_S 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
short KW_SHORT 0 No Missing in the keyword index, found elsewhere in the language reference.
soap-header KW_SOAP_HDR 0 No Missing in the keyword index, untested at this time.
soap-header-entryref KW_SOAP_HER 0 No Missing in the keyword index, untested at this time.
soap-fault KW_SOAP_F 0 No Missing in the keyword index, untested at this time.
soap-fault-actor KW_SOAP_F_A 0 No Missing in the keyword index, untested at this time.
soap-fault-code KW_SOAP_F_C 0 No Missing in the keyword index, untested at this time.
soap-fault-detail KW_SOAP_F_D 0 No Missing in the keyword index, untested at this time.
soap-fault-string KW_SOAP_F_S 0 No Missing in the keyword index, untested at this time.
socket KW_SOCKET 0 No Missing in the keyword index, found elsewhere in the language reference.
start-box-selection KW_START_BS 0 No Missing in the keyword index, found elsewhere in the language reference.
start-search KW_START_SC 0 No Missing in the keyword index, found elsewhere in the language reference.
starting KW_STARTING 0 No Missing in the keyword index, found elsewhere in the language reference.
startup-parameters KW_STUP_PAR 0 No Missing in the keyword index, untested at this time.
super KW_SUPER 0 Yes Documented as unreserved but actually is reserved.
synchronize KW_SYNCHRON 0 No Missing in the keyword index, untested at this time.
table-crc-list KW_TAB_CRCL 0 No Missing in the keyword index, untested at this time.
table-list KW_TAB_LIST 0 No Missing in the keyword index, untested at this time.
tag KW_TAG 0 No Missing in the keyword index, found elsewhere in the language reference.
timezone KW_TIMEZONE 0 No Missing in the keyword index, untested at this time.
top KW_TOP 0 No Missing in the keyword index, found elsewhere in the language reference.
tracking-changes KW_TRAC_CHG 0 No Missing in the keyword index, untested at this time.
ttcodepage KW_TTCP 0 No Missing in the keyword index, untested at this time.
unsigned-byte KW_UNS_BYTE 0 No Missing in the keyword index, found in the external program interface reference.
unsigned-short KW_UNS_SHRT 0 No Missing in the keyword index, found elsewhere in the language reference.
urldecode KW_URL_DECO 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
urlencode KW_URL_ENCO 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
url-field KW_URL_FLD 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
url-field-list KW_URL_FLDL 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
url-format KW_URL_FMT 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
validate-xml KW_VAL_XML 0 No Missing in the keyword index, found elsewhere in the language reference.
vms KW_VMS 0 Yes Completely undocumented.
web KW_WEB 0 No Missing in the keyword index, found in WebSpeed reference.
web-output KW_WEB_OUT 0 No Not a real keyword, but can be defined in the WebSpeed 4GL include files.
where-string KW_WHERE_ST 0 No Missing in the keyword index, untested at this time.
window-close KW_WIN_CLOS 0 No Missing in the keyword index, found elsewhere in the language reference.
window-delayed-minimize KW_WIN_DMIN 17 Yes Missing in the keyword index, found elsewhere in the language reference.
window-resized KW_WIN_RESI 0 No Missing in the keyword index, found elsewhere in the language reference.
window-restored KW_WIN_REST 0 No Missing in the keyword index, found elsewhere in the language reference.
x-document KW_X_DOC 0 No Missing in the keyword index, found elsewhere in the language reference.
x-noderef KW_X_NODE 0 No Missing in the keyword index, found elsewhere in the language reference.

Anything listed in the table above as “Missing in the keyword index, untested at this time.” has been found and entered based on text seen in syntax statements in the language reference, but since the keyword has not bee tested, the abbreviation support and reserved keyword status are unknown. Once these are tested, the values can be fixed as needed. All of these keywords are set for no abbreviations and unreserved.

Anything listed as “Not a real keyword, but can be defined in the WebSpeed 4GL include files.” is an artificial keyword that was created to eliminate the need for the WebSpeed include files to be used during FWD conversion. This allows WebSpeed code to parse and convert.

Some entries have inherent conflicts due to ambiguity in the Progress language. For example, WIDTH and WIDTH-CHARS can both be abbreviated as WIDTH even though they are used for completely separate purposes and are described as separate keywords. Since one cannot use WIDTH- or WIDTH-C etc... as a replacement for WIDTH, these really are 2 different keywords but there must be fixups inside Progress that makes it tolerant of this issue. In FWD, the parser detects these possible overlaps and rewrites the token to the expected version so that downstream processing is easier. In this list, some changes have been made to ensure that conflicts don't occur (e.g. WIDTH-CHARS is stated to have a minimum abbreviation of 6 characters instead of the correct value of 5).

There are several keywords which are listed in the keyword index and in the notes column their purpose is stated. However, no other reference to these keywords exists in the language reference. So these are listed above as "possible undocumented ..." features. At this time, there is not enough information to know how to use those keywords, but they have been created in the lexer's dictionary.

There are some cases where the keyword list appears to be missing some keywords that are listed in the Progress Keyword Index. The most common case is a "duplicated" keyword that is really a synonym for another longer keyword. The longer keyword has an abbreviation which makes it match the same text as the shorter keyword. From the Progress compiler's perspective it appears that both forms are treated the same. This is different from the WIDTH and WIDTH- case noted above, since in that case the keywords are not synonyms. In the duplicate case, the shorter keyword is considered a duplicate of the longer one. The longer keyword and an abbreviation is used and the short keyword is not needed since the long keyword's abbreviation handles that case. In other words, this short keyword never needs to be added to the keyword list because the support is already sufficient. It is unknown why Progress documented "both" keywords, because the longer one covers both usages. This is the list:

Short Keyword Text Long Keyword Text Abbreviation
accum accumulate 5
button buttons 6
desc descending 4
field fields 5
form format 4
forward forwards 7
max maximum 3
min minimum 3

The following are keywords that are documented in the Progress 4GL Language Reference Keyword Index but which are not really language keywords at all:

  • DEFINED - this is a symbol that is a preprocessor function but it is not something that has any meaning in a 4GL program so the parser should not have any knowledge of it
  • ENABLED-FIELDS - the keyword index displays this as &quot;ENABLED-FIELDS" (with the double quotes) and this is noted as an option to the validate() method; testing has shown that this is a string literal NOT a real keyword (if you take the double quotes away you get a compiler error)
  • SET-CURRENT-VALUE - this is a possible value returned inside a string from the DBRESTRICTIONS built-in function but this can't appear in directly (unquoted) in 4GL source so this is NOT a real keyword

Progress is so over-the-top keyword intensive that it sometimes has multiple forms of the same keyword (e.g. USER and USERID, WAIT and WAIT-FOR, GETBYTE and GET-BYTE). These are not abbreviations but just synonyms that require separate entries in the keyword index. The key point is that they will both resolve to the same token type (e.g. WAIT and WAIT-FOR both resolve to KW_WAIT_FOR). The order of these in the list will determine what "standard text" will be found when using a reverse text lookup (lookup of the text for a keyword based on its token type). In particular, the LAST entry to be added will be the "canonical" text returned from a reverse lookup. This affects reports and other features. Always order these with the most common form of the keyword as the last entry in the keyword index. So WAIT-FOR must follow WAIT in the list to ensure that the reverse lookup of KW_WAIT_FOR would return the text WAIT-FOR instead of WAIT.

Filename

The lexer can often detect paths and filenames (which include any valid symbol character as well as / or \ or . or ..) and supports absolute and relative filenames including the special references to the current directory and the parent directory. Any filename that is inside a quoted string, is just a string literal. Progress 4GL allows some filenames (depending on each language statement's syntax) to be placed directly into the source code as unquoted text. That is the case that is matched as a filename as described here.

Some filenames may be lexed as a SYMBOL. When a SYMBOL contains characters that can only be present in a filename, then that token type is coerced into the FILENAME token type. For example, filenames may start with the / or \ characters (in which case they are absolute filenames). The second and following characters in filenames can include /, \ or . in addition to all the special symbol characters listed above for user-defined symbols.

DOS and Windows filenames can start with a drive letter followed by a : as in c:. This construct is matched as a symbol followed by a colon. This is needed to allow single character variable names + attribute or method calls to properly work in the parser. The difficulty with putting the whole thing together again into a single filename is left to the ProgressParser.filename() rule.

Note that there are many characters that are not allowed in filenames at this time. This is an artificial limitation designed to keep the current lexer simple and compatible with the known/common cases of filenames while not introducing too many potential ambiguities. Examples of characters that are not matched include:

~
!
@
^
+
=

The general rule: if the character is not a valid symbol char, /, \, . or .. then it is not matched. This can be changed if necessary, but the decision was made to defer such handling until the need arises. When a filename is detected the token type is set to FILENAME. Both relative and absolute filenames are matched by this rule (except for the drive letter component as noted above).

Any filename that starts with ./, ../, .\ or ..\ will be matched as a FILENAME token. That text without any following text are also valid FILENAME tokens.

It is also important to note that any relative filename that does not include any path separator (/ or \) and which has 1 or 2 (but not more than 2) . characters will be matched as a DB_SYMBOL due to inherent ambiguity in the Progress decision to use the . as the database qualifier. This means that the parser must be aware that some filenames can appear as database symbols and the disambiguation occurs based on context.

R-Code Library Reference

During generic symbol processing, the lexer may match an R-Code library reference. R-Code library references are matched with the format pathname<<membername>>. This allows any filename to be specified as a prefix and then the library member name followed as a suffix. The library membername is contained in the unambiguous double angle brackets. The resulting token type is set to LIBRARY_REF.

Database Symbol

A special case exists for partially or fully qualified database symbols. Such symbols are comprised of 2 or 3 regular symbols, each separated by a . and no whitespace. This method recognizes such optional constructions and sets the token type to DB_SYMBOL. In order to make this extra check work, the optional section (following the first or main symbol definition) is differentiated using a semantic predicate. This only allows the database symbol matching if the following conditions hold:

  • a DOT character is found after the symbol without any intervening whitespace
  • the next character after the DOT is an alphabetic character (it can't be numeric or a special symbol because each part of the qualified database symbol name must follow the standard rules (see above) for symbol naming

There is a second optional section nested inside the first one, which handles the condition where there is a fully qualified field name. The resulting possible constructions are:

 user-defined symbol or unqualified db/table/field name    --> sym
 fully qualified table or partially qualified field name   --> sym.sym
 fully qualified field name                                --> sym.sym.sym

Any unqualified database, table or field names will be lexed as a standard SYMBOL (which is the default token type). But in any case where a simple symbol is followed by a . AND an alphabetic character with no intervening whitespace, this is known to be a qualified database name and it cannot be a generic symbol or language keyword.

Due to potential ambiguity with the FILENAME lexing, it is possible to misinterpret filenames as database names. The parser must be aware of this case and disambiguate based on context.

There are cases in which it is valid to place whitespace between the DOT character and the following symbolic field name or between the preceding table name and the DOT character. This is handled by the parser based on context and the lexer will not generate a DB_SYMBOL in that case. For example, the following can all be equivalent:

record    .field
record.  field
record  .  field
record.field

Caret

The caret ^ is used as the “bypass this field” indicator for PROMPT-FOR, SET, UPDATE and IMPORT statements. This character is matched and the result is a CARET token.

Escape Characters

The tilde ~ character and in addition on UNIX/Linux systems the backslash \ character are used as escape sequences in Progress 4GL. When encountered outside of a string literal or comment, these characters are matched and the resulting TILDE and BACKSLASH tokens are specially processed.

If the token stream is read by the ProgressParser, these tokens are marked as hidden and are routed to the hidden token stream. The parser then selectively reads from the hidden token stream as needed to make decisions.

Other users of the lexer (such as the SchemaParser) which do not activate hidden processing, will cause these tokens to be dropped from the main token stream (and they cannot be read by the parser because they have been “skipped”).

Other

There are other special characters that are invalid in Progress 4GL language syntax outside of certain language features that allow arbitrary text. For example, language statements that allow shell commands (e.g. UNIX) can embed many unexpected characters.

This matches the most common unexpected characters and generates a token of type UNKNOWN_TOKEN rather than throwing an exception. Anything that is not matched here will still trigger an exception. The list of matched characters:

`
!
#
$
%
&
{
}
|
;

Unsupported Features

Date Literal Limitations

There is no support for a quirk of Progress date literals in which constructs like 1/1--- are valid dates equivalent to 01/01/00.

In Progress the month must be an integer between 1 and 12 but this limit is not checked in the FWD lexer.

In Progress the day must be between 1 and the number of days in that month, though this limit is not checked in the FWD lexer.

DATETIME and DATETIME-TZ Literal Limitations

At this time, the use of the literal forms of the DATETIME and DATETIME-TZ types is not supported.

Unexpected Input

As documented above in the Top Level Token Types sub-section entitled Other, there are parsing cases where the normal lexical rules of Progress 4GL are ignored. The UNKNOWN_TOKEN is meant to provide a facility through which such cases can be handled. But only a set of the most common unexpected characters is supported in that rule. That rule in the lexer will need modification to add any other characters that are needed but which are not yet supported.

The extended ASCII characters or the range of Unicode characters above the ASCII region would define the list of possible characters.

This has no meaning in regards to the content of string literals, where the FWD lexer already supports all possible character input. This issue is only in regards to characters that appear in “unregulated” areas of the parser such as the shell command language statements.

Unexpected Filename Characters

The characters allowed to be matched as a filename are left deliberately limited. If valid Progress 4GL source code is found in which Progress legitimately interprets the text as a filename, but FWD cannot do so, then the lexer will need to be enhanced to handle those additional characters. See the Top Level Token Types sub-section entitled Filenames, for details.

Untested Keywords

There are hundreds of keywords that have been added based on the syntax needs of the language, but which are not documented in the official Progress Keyword Index. In the Top Level Token Types sub-section entitled Language Keyword, the table documents which of those keywords are untested. Those keywords are set to support no abbreviations and to be unreserved. Either or both decisions may require changes once the keyword has been tested in the Progress 4GL environment.


© 2004-2017 Golden Code Development Corporation. ALL RIGHTS RESERVED.