This page is still under construction.

Parts of this page are still being built. What you see may change.

FORCAL

Time limit1sMemory limit128 MB

Summary
Read text lines in blocks and scan each line into FORCAL tokens (identifiers, literals, symbols, keywords), printing TOKEN ERROR and skipping the block on an invalid string.
Level

Medium5 of 10

Topics
String, Implementation, Simulation
Solved
No attempts yet

Problem

FORCAL is a small programming language popular with programmers interested in compiler construction, and especially with students taking a compiler-construction course. Its syntax is defined as follows.

  • The only data type is the integer.
  • Every identifier is declared implicitly and is at most 32 characters long. An identifier is made of letters, digits, and underscores (_), and at least one of its characters is not a digit.
  • A literal is a string of at most 8 digits.
  • A comment begins with -- and continues to the end of the line on which it starts.
  • There are two kinds of statements:
    • Assignment: identifier := expression, where an expression is built from identifiers, literals, the operators + and -, and parentheses, by the following rules:
      1. every identifier and every literal is an expression;
      2. if a and b are expressions, then a + b, a - b, +a, -a, and (a) are expressions.
    • Input / output: read(list of identifiers) and write(list of expressions), where the items of a list are separated by commas.
  • begin, end, read, and write are reserved words.
  • Every statement ends with a semicolon (;).
  • FORCAL is case-insensitive; for example, BegIN is the same keyword as beGin.
  • A FORCAL token is an identifier, a literal, one of the symbols + - ( ) := ; ,, or a reserved word.

Notes:

  • The assignment operator := is a single token.
  • Spaces, tabs, and line breaks are allowed between tokens.
  • No part of a comment is a token.
  • Two consecutive tokens that are both identifiers, literals, or reserved words must be separated by a space, a tab, or a line break.
  • No token may contain a space, a tab, or a line break.

Write a program that reads lines of text and recognizes the FORCAL tokens in them.

Input

The input consists of several blocks of lines. Each block is a sequence of text lines and is terminated by a single empty line.

Output

For every input line the program produces output as follows. A non-empty line that is not being skipped is scanned from left to right, and each recognized FORCAL token is printed on its own line, written exactly as it appears in the input (letter case is preserved). As soon as the scanner meets a string that is neither a FORCAL token, a comment, nor whitespace (a space or a tab), it prints the line TOKEN ERROR and skips the rest of the current block. Every empty line, and every line that is skipped because its block already produced a TOKEN ERROR, is written to the output as a single empty line. Because each block ends with an empty line, this places at least one empty line after every block of output.

Examples3

  1. Example 1

    Input
    A1:= A + (-B);
    
    A123_A123 )
    01.2 A B
    C
    
    := A  beGIn
    
    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
    
    
    Expected output
    A1
    :=
    A
    +
    (
    -
    B
    )
    ;
    
    A123_A123
    )
    01
    TOKEN ERROR
    
    
    :=
    A
    beGIn
    
    TOKEN ERROR
    
    
  2. Example 2

    Input
    begin
      read(A, B);
      Sum := A + B - (12345);
      write(Sum);
    end;
    
    
    Expected output
    begin
    read
    (
    A
    ,
    B
    )
    ;
    Sum
    :=
    A
    +
    B
    -
    (
    12345
    )
    ;
    write
    (
    Sum
    )
    ;
    end
    ;
    
    
  3. Example 3

    Input
    X := 1; -- assign one
    Y := X -- trailing comment
    
    
    Expected output
    X
    :=
    1
    ;
    Y
    :=
    X