Семантические действия в Coco/ R без найденного токена

Я новичок в coco/R и пытаюсь создать синтаксический анализатор командной строки, чтобы написать скрипт для нашего продукта.

Мои команды выглядят так <commandid> <specifier> {<params>} (это только образец, а не кокос /R-синтаксис).

Я пытался создать производственные правила, но я не понимаю, как правильно вводится код.

Вот очень очень простой пример-атг:

COMPILER Test

PRODUCTIONS
  Test = 
    "test"    (. Console.WriteLine("This should only be printed if 'test' was parsed!"); .)
  .          

END Test.

Я думал, что это ожидает test и если и только если он был найден, он вызывает указанную командную строку. Но это не так. Выход:

x
-- line 1 col 1: "test" expected
This should only be printed if 'test' was parsed!

test
This should only be printed if 'test' was parsed!

Если я изменю АТГ, просто добавив | оно работает. Но теперь возникают новые проблемы, если я пытаюсь использовать больше токенов.

Что я делаю неправильно? Я хочу, чтобы мой код вызывался только при разборе токена.

Вот АТГ, который, кажется, работает, но вызывает другие проблемы:

COMPILER Test

PRODUCTIONS
  Test = 
    "test"    (. Console.WriteLine("This should only be printed if 'test' was parsed!"); .)
    |
  .          

END Test.

Полностью опробованный АТГ:

COMPILER Test

  public event Action Exit;
  public event Action Cls;
  public event Action<string, string> CreateChannel;

CHARACTERS
  lowerCaseLetter = 'a' .. 'z'.
  upperCaseLetter = 'A' .. 'Z'.
  letter = upperCaseLetter + lowerCaseLetter.
  underscore = '_'.
  digit = "0123456789".
  cr  = '\r'.
  lf  = '\n'.
  tab = '\t'.
  anyButQuote = ANY - '"'.
  anyButSpace = ANY - ' '.

TOKENS
  string = ("\"" { anyButQuote | "\\\"" } "\"") | (anyButSpace { anyButSpace }).

COMMENTS FROM "/*" TO "*/" NESTED
COMMENTS FROM "//" TO lf

IGNORE cr + lf + tab

PRODUCTIONS
  Test = 
    (
      "exit"                            (. this.Exit?.Invoke(); .)
      |
      "cls"                             (. this.Cls?.Invoke(); .)
      |
      ParseCreate                        
    )
    .             

  ParseCreate =
    "create"
    (
      ParseCreateChannel
      |
                                        (. this.SyntaxError?.Invoke("Usage: create channel <params>"); .)
    )
    .

  ParseCreateChannel =
    "channel"
    (
      ParseIdParam<out var channelId>
      ParseTypeParam<out var channelValueType>
                                        (.
                                        if (channelId != null && channelValueType != null)
                                            this.CreateChannel?.Invoke(channelId, channelValueType);
                                        .)
      |
                                        (. this.SyntaxError?.Invoke("Usage: create channel id:<id> type:<type>"); .)
    )
    .

  ParseIdParam<out string id> =         (. id = null; .)
    (
      "id:" string                      (. id = t.val; .)
      |
                                        (. this.SyntaxError?.Invoke("Parameter 'id:<id>' expected."); .)
    )
    .

  ParseTypeParam<out string type> =     (. type = null; .)
    (
      "type:" string                    (. type = t.val; .)
      |
                                        (. this.SyntaxError?.Invoke("Parameter 'type:<type>' expected."); .)
    )
    .

END Test.

Но для правильного ввода create channel id:theid type:thetype Я получаю ошибку line 1 col 16: invalid ParseCreateChannel и я не мог представить почему:-(

0 ответов

Другие вопросы по тегам