orangeduck / mpc

A Parser Combinator library for C

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

cant seem to capture a hyphen

mgood7123 opened this issue · comments

https://paste.pound-python.org/show/vy90zrfxIKiBVyxAXusz/

#include "../mpc.h"

void eval(char * string, mpc_parser_t *p, mpc_result_t * r) {
	if (mpc_parse("test", string, p, r)) {
	  mpc_ast_print((*r).output);
      mpc_ast_delete((*r).output);
    } else {
      mpc_err_print((*r).error);
      mpc_err_delete((*r).error);
    }
}


#define mpcnew(x)   mpc_parser_t * x = mpc_new(#x)

int main(int argc, char **argv) {
  
  mpcnew(Shell);
  mpcnew(Command);
  mpcnew(Expression);
  mpcnew(Alpha);
  mpcnew(Alnum);
  mpcnew(Digit);
  mpcnew(Dollar);
  mpcnew(At);
  mpcnew(Equals);
  mpcnew(Variable);
  mpcnew(Array);
  mpcnew(Assignment);
  mpcnew(Index);
  mpcnew(Command_End);
  mpcnew(Line);
  mpcnew(Print);
  mpcnew(Args);
  mpcnew(Hyphen);
  mpcnew(Space);
  mpc_parser_t * n = mpc_newline(); mpcnew(nl); mpc_define(nl,n);

  mpca_lang(MPCA_LANG_DEFAULT,
	" Shell      : <Command>+;"
    " Command    : (<Expression> | <Line>) <Command_End> ; "
    " Line       : <Alpha>* | <Hyphen>* | <Space>* ;"
    " Args       : '*';"
    " Hyphen     : '-';"
    " Space      : ' ';"
    " Command_End: ';' | <nl> | /$/; "
    " Expression : <Assignment> | <Variable> | <Array> | <Index>; "
    " Assignment : <Alpha> <Equals> ( <Alnum> | <Variable> | <Array>)?;  "
    " Variable   : <Dollar> ( <At> | <Alnum> ) ;"
    " Array      : <Alpha> <Index> ;"
    " Index      : '[' ( <Digit> | <Array> ) ']' ;"
	" Alpha      : /[a-z]+[A-Z]+/ | /[A-Z]+[a-z]+/ | /[a-z]+/ | /[A-Z]+/;"
	" Alnum      : <Alpha> | <Digit>;"
	" Digit      : /[0-9]+/;"
	" Dollar     : '$' ;"
	" At         : '@' ;"
	" Equals     : '=' ;",
    Shell, Command, Line, Args, Hyphen, Space, Command_End, nl, Expression, Assignment, Variable, Array, Index, Alpha, Alnum, Digit, Dollar, At, Equals, Print, NULL);
  
  mpc_result_t r;
  eval("a=3; b=9; a=$b; a[b[0]]; azG[6] ;ls def kj hgj yih;bash -", Shell, &r);
  mpc_cleanup(20, Shell, Command, Line, Args, Hyphen, Space, Command_End, nl, Expression, Assignment, Variable, Array, Index, Alpha, Alnum, Digit, Dollar, At, Equals, Print, NULL);
  
  return 0;
  
}

mobile_c@Mobile-C:~/git/mpc/examples$ gcc shell.c ../mpc.c && ./a.out> 
  Command|> 
    Expression|Assignment|> 
      Alpha|regex:1:1 'a'
      Equals|char:1:2 '='
      Alnum|Digit|regex:1:3 '3'
    Command_End|char:1:4 ';'
  Command|> 
    Expression|Assignment|> 
      Alpha|regex:1:6 'b'
      Equals|char:1:7 '='
      Alnum|Digit|regex:1:8 '9'
    Command_End|char:1:9 ';'
  Command|> 
    Expression|Assignment|> 
      Alpha|regex:1:11 'a'
      Equals|char:1:12 '='
      Variable|> 
        Dollar|char:1:13 '$'
        Alnum|Alpha|regex:1:14 'b'
    Command_End|char:1:15 ';'
  Command|> 
    Expression|Array|> 
      Alpha|regex:1:17 'a'
      Index|> 
        char:1:18 '['
        Array|> 
          Alpha|regex:1:19 'b'
          Index|> 
            char:1:20 '['
            Digit|regex:1:21 '0'
            char:1:22 ']'
        char:1:23 ']'
    Command_End|char:1:24 ';'
  Command|> 
    Expression|Array|> 
      Alpha|regex:1:26 'azG'
      Index|> 
        char:1:29 '['
        Digit|regex:1:30 '6'
        char:1:31 ']'
    Command_End|char:1:33 ';'
  Command|> 
    Line|> 
      Alpha|regex:1:34 'ls'
      Alpha|regex:1:37 'def'
      Alpha|regex:1:41 'kj'
      Alpha|regex:1:44 'hgj'
      Alpha|regex:1:48 'yih'
    Command_End|char:1:51 ';'
mobile_c@Mobile-C:~/git/mpc/examples$ 

it is however possible to capture it alone (with just the hyphen rule), im not sure why yet https://paste.pound-python.org/show/PUHVGTccAcC6Xw53UAjb/

#include "../mpc.h"

void eval(char * string, mpc_parser_t *p, mpc_result_t * r) {
	if (mpc_parse("test", string, p, r)) {
	  mpc_ast_print((*r).output);
      mpc_ast_delete((*r).output);
    } else {
      mpc_err_print((*r).error);
      mpc_err_delete((*r).error);
    }
}


#define mpcnew(x)   mpc_parser_t * x = mpc_new(#x)

int main(int argc, char **argv) {
  
  mpcnew(Hyphen);

  mpca_lang(MPCA_LANG_DEFAULT,
    " Hyphen     : '-';",
    Hyphen, NULL);
  
  mpc_result_t r;
  eval("-", Hyphen, &r);
  mpc_cleanup(1, Hyphen, NULL);
  
  return 0;
  
}

mobile_c@Mobile-C:~/git/mpc/examples$ gcc shell.c ../mpc.c && ./a.out
char:1:1 '-'
mobile_c@Mobile-C:~/git/mpc/examples$ 

if i do

Line       : <Hyphen> | <Equals> | <Digit>

then i get

test:1:1: error: expected '-', '=' or one or more of one of '0123456789' at 'a'

and if i do

Line       : <Hyphen> | <Equals> | <Digit> | <Alpha>

then i get

test:1:2: error: expected one of 'abcdefghijklmnopqrstuvwxyz', one or more of one of 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', ';', newline or end of input at '='

with

Command    : <Line> <Command_End>

aswell as matching against

  mpc_parser_t * n = mpc_newline(); mpcnew(nl); mpc_define(nl,n);

    " Command    : <Expression> <Command_End> ; "
    " Expression : <Assignment> | <Variable> | <Array> | <Index>; "
    " Assignment : <Alpha> <Equals> ( <Alnum> | <Variable> | <Array>)?;  "
    " Variable   : <Dollar> ( <At> | <Alnum> ) ;"
    " Array      : <Alpha> <Index> ;"
    " Index      : '[' ( <Digit> | <Array> ) ']' ;"
	" Alpha      : /[a-z]+[A-Z]+/ | /[A-Z]+[a-z]+/ | /[a-z]+/ | /[A-Z]+/;"
	" Alnum      : <Alpha> | <Digit>;"
	" Digit      : /[0-9]+/;"
	" Dollar     : '$' ;"
	" At         : '@' ;"
	" Equals     : '=' ;",
    " Command_End: ';' | <nl> | /$/; "

with

a=3\nb=9;

i get

test:2:1: error: expected ';', newline or end of input at 'b'

It is hard for me to say exactly what is wrong and how to fix it without knowing what your intent is but in your original grammar I don't think the Hyphen clause can ever be parsed as part of a Line because the Line will always succeed by matching zero or more Alpha first. I.E. Line can be easily matched by the empty string so it will never attempt to parse Hyphen. (See more here.)

Basically you need to work out how to re-structure your grammar probably be factorizing the terms somehow so that your Line rule matches zero or more Things of some kind where the things themselves can either be identifiers, hypens, or spaces.

basically i want Line to match from Alpha to Command_End, accepting all input characters

You can try (<Alpha> | <Hyphen> | <Space>)*

it just loads forever lol

wish there was a mpc_ascii or mpc_printable lol

as mpc_any doesnt work

Okay well I am going to close this issue and leave you to debug the grammar yourself since I don't think it is a bug or error in the library.

  mpc_parser_t * n = mpc_any(); mpcnew(Any); mpc_define(Any,n);

  mpca_lang(MPCA_LANG_DEFAULT,
	" Any      : <Any>*;",
    Any, NULL);
  
  mpc_result_t r;
  eval("a=3; b=9; a=$b; a[b[0]]; azG[6] ;ls def kj hgj yih;bash -", Any, &r);
  mpc_cleanup(1, Any, NULL);
mobile_c@Mobile-C:~/git/mpc/examples$ gcc shell.c ../mpc.c && ./a.out
Segmentation fault (core dumped)
mobile_c@Mobile-C:~/git/mpc/examples$