pythonpython-3.xparsinglark-parser

Beginner Question: "No terminal defined for 'i' at line 2 col 1 int "i" 10" Lark


I am very new to lark and am trying to create a simple parser, but I am getting suck on a seemingly simple quesion, why does "No terminal defined for 'i' at line 2 col 1 int "i" 10" show up? Here is my grammar:

start: set_str
     | set_int

COMMENT: ";" /[^\n]/*

set_str: "str " STRING " " STRING
set_int: "int " STRING " " NUMBER

%import common.ESCAPED_STRING -> STRING
%import common.SIGNED_NUMBER  -> NUMBER
%ignore COMMENT
%ignore " "
%ignore "\n"

and the text input:

int "i" 10 ; this is a comment
str "s" "test"

I am new and do not know why this is not working, any tips would be available

also, just a smaller second question is there a way to get rid of the quotes around "i" and "s", because when I remove them they do not become escaped strings anymore.


Solution

  • If you read the full error message, you see that the only expected Token is <END-OF-FILE>. This means that there is more input than your grammar consumes. I assume what you want is for start to be parsed as often as possible. This is achieved via an operator in ebnf, with * meaning 'repeat zero or more times' and + meaning 'repeat one or more times'. Therefore to fix your grammar:

    start: (set_str | set_int)+
    
    COMMENT: ";" /[^\n]/*
    
    set_str: "str" NAME STRING
    set_int: "int" NAME NUMBER
    
    %import common.ESCAPED_STRING -> STRING
    %import common.CNAME-> NAME
    %import common.SIGNED_NUMBER  -> NUMBER
    %ignore COMMENT
    %ignore " "
    %ignore "\n"
    

    Also note that I made a few other changes: I replaced the first STRING in the set_* with the also from common imported NAME. This is what I assume you want for your second question.

    I also removed the " " in the set_*. Since you %ignore them, it isn't required, and it might cause problems in the future.