grammars-v4 icon indicating copy to clipboard operation
grammars-v4 copied to clipboard

VB6 Write with Format statement

Open phongkien opened this issue 2 years ago • 3 comments

Doesn't look like the grammar support the following

Write #fileNum, Format(abc, "###")
image

phongkien avatar Jan 20 '23 18:01 phongkien

Looks like it is being eaten by DATELITERAL

DATELITERAL: HASH (~ [#\r\n])* HASH;

to support

MyDate = #February 12, 1985#   ' Assign a date.

phongkien avatar Jan 20 '23 23:01 phongkien

Yes, the rule DATELITERAL: HASH (~ [#\r\n])* HASH; is causing #fileNum, Format(abc, "# to be tokenized as a DATELITERAL.

Looking at the documentation for date literals in VB: https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/data-types/date-data-type, it gives the following examples:

  • #5/31/1993#
  • #1993-5-31#
  • #1:15:30 PM#
  • #13:15:30#
  • #8/13/2002 12:14 PM#

So the rule DATELITERAL might be written like this:

DATELITERAL: HASH [0-9A-Z/\-: ]+ HASH;

in which case the following tokens are created for your input Write #fileNum, Format(abc, "###"):

WRITE               'Write'
WS                  ' '
FILENUMBER          '#fileNum'
COMMA               ','
WS                  ' '
IDENTIFIER          'Format'
LPAREN              '('
IDENTIFIER          'abc'
COMMA               ','
WS                  ' '
STRINGLITERAL       '"###"'
RPAREN              ')'
EOF                 '<EOF>'

But I don't know too much of VB, so I'm not sure if my suggestion is correct.

EDIT

Oh, but if #February 12, 1985# is also a valid date literal, the comma in there is messing up my suggestion. In that case, you might try something like:

DATELITERAL: HASH DATELITERALVALUE HASH;

fragment DATELITERALVALUE
 : DATEVALUE
 | TIMEVALUE
 | DATEVALUE WS TIMEVALUE
 | LONGDATEVALUE
 ;

// 5/31/1993
// 1993/1/1
// 12-31-22
fragment DATEVALUE
 : DIGITS '/' DIGITS '/' DIGITS
 | DIGITS '-' DIGITS '-' DIGITS
 ;

// February 12, 1985
// 12 januari, 2050
fragment LONGDATEVALUE
 : LETTER+ WS DIGITS ',' WS DIGITS
 | DIGITS WS LETTER+ ',' WS DIGITS
 ;

// 1:15
// 11:15:30
// 13:15:30 PM
// 23:15 am
fragment TIMEVALUE
 : DIGITS ':' DIGITS (':' DIGITS)? (WS [AP] 'M')?
 ;

fragment DIGITS
 : [0-9]+
 ;

bkiers avatar Jan 21 '23 13:01 bkiers

@bkiers thanks for the suggestions but I think the language support various date format (long, short, ...) and possibly other format as well. Will take your suggestion into consideration.

phongkien avatar Jan 23 '23 13:01 phongkien