Understanding PP error


#1

Hello, I try this : https://gist.github.com/Grummfy/0c13d874caa3b32857507a953d630432/74ca12cfe9de01bbb3738709be833403a5f57431 (revision 1)

but I got an error:

PHP Stack trace:
PHP   1. {main}() .../pp/src/GraphQL.php:0
PHP   2. Hoa\Compiler\Llk\Parser->parse() .../pp/src/GraphQL.php:14
PHP   3. strrpos() .../pp/vendor/hoa/compiler/Llk/Parser.php:198
PHP Fatal error:  Uncaught Hoa\Compiler\Llk\Parser::parse(): (0) Unexpected token "(null)" ((null)) at line 1 and column 1:
{
↑  

Why it fails?

the idea is to implements this : http://facebook.github.io/graphql/ but I start with a really simpler subset


#2

Hello :slight_smile: ,

I don’t know why you have this error but the grammar is not correct. Your root rule (the axiom) is the first rule declared (except if your define one when calling the parse method), so according to your Gist, this is name. And it is defined as:

name:
    <name>

That’s all. Nothing can be recognized after that.

Reading the GraphQL specification, you are trying to define a Selection Sets, defined as:

SelectionSet :
    { Selection_list }

Selection :
    Field
    FragmentSpread
    InlineFragment

So the grammar might look like this:

selection_set:
    ::brace_:: selection()* ::_brace::

selection:
    field() | fragment_spread() | inline_fragment()

Field is defined as follows:

Field :
    Alias_opt Name Arguments_opt Directives_opt Selection Set_opt

which likely translates to:

field:
    alias()? name() arguments()? directives()? selection() set()?

etc.

GraphQL is strange because it defines 2 roots:

A GraphQL schema is represented by a root type for each kind of operation: query and mutation; this determines the place in the type system where those operations begin.

So you must define a higher root to choose the type root you want, something like:

#root:
    query() | mutation()

Just follow the specification. The Source Text Section describes all the lexemes, and the siblings Sections describe the rules (parser).

Is it clear?


#3

Well, before going to implements the full GraphQL specification, I was more playing with a small subset. So you come with a lot of things but almost nothing in relation with what I have written :confused:

I mainly try to understand PP, before going further. So I firstly prefer to have something (small and easily understandable) that can parse things like this:

{
  human(id: 1000) {
    name
    height
  }
}

or

{
  human {
    id
    name
    height
  }
}

or

{
  humans(first: 50 limit: 30) {
    id
    name
  }
}

So as I understand the first element that I should put is “#object:”, but even after that I still have error.

I have updated the gist with revision 2


#4

The subset you are trying to implement is exactly the Selection Sets Section I was mentionning. This is what you call an object. From your Gist, this is:

#object:
    ::brace_:: ( objectArgument() | object() | name()* ) ::_brace::

I would recommend to rewrite this rule as:

#root:
    ::brace_:: object()* ::_brace::

#object:
    object_name()
    ( ::parenthesis_:: object_argument_list()* ::_parenthesis )?
    ::brace_:: field() ::_brace::

Not that object_name is likely to be a simple identifier, so <identifier> might work and it will be simpler.

Note that braces are declared outside the object rule. The general rule is object { field… }, and not { object field | object }.

Also, I cannot understand the error I don’t know what data you are parsing :slight_smile:. Please, consider adding them in your Gist.


#5

all is in the gist (see the php file)

I will check and test your remark


#6

the last revision works \o/ !

thanks


#7

Well I’m back on track

I have added some exemple from the learn documentation about graphql

so php src/check-from-example.php should put everything to a valid stats

I write should, because I need to check when it’s invalid, the reason of. But I hope that with this start you can at least help me a bit.


#8

So I work on it.

So klet’s start with the two example that should works: the first use quote inside the parenthesis, and I don’t know why when we remove it it works but not with the quotes cat resources/good/6.gql | vendor/bin/hoa compiler:pp src/GraphQL.pp 0 --visitor dump

the second is a line of comments, I don’t know how to let the parser ignore line that start with an '#' cat resources/good/3.gql | vendor/bin/hoa compiler:pp src/GraphQL.pp 0 --visitor dump

thanks


#9

For your first example, what the result of the lexer, i.e. what is the result of:

$ hoa compiler:pp … --token-sequence

I suspect that your string token could be incorrectly defined.

For your second issue, did you try a token like this one:

%token comment //[^\n]

#10

for the first one, indeed the token say it’s quote number quote instead of strings. So I just add a rule about number between quote and that pass. But it’s probably not the good solution because of the resource/good/34 that have pretty the same issue with the quote arround string with equals inside of it. I think there is an issue with the name and the character sequence.

For the second, i’m not sure to see how to do with that specific point. Honestly for me it’s something very complexe to understand.

Well after the fix I found (thanks) I have 25/29 test that success.


#11

For the string representation, are you able to use a single token to represent the whole string?

Something like:

%token string ("|')(.*?)(?<!\\)\1

(from https://github.com/hoaproject/Ruler/blob/master/Grammar.pp). It recognizes a string delimited by single or double quotes, and escaped delimiters, with a single regular expression.


#12

The problem is that we have several kind of strings… strings with specific range (name) for naming some elemnt, complete string for comments (starting with a ‘#’ and ending with end of line), some specific key words, …


#13

Thanks Hywan, for now, the only issu I still get is about comments (the test 3.gql). I don’t see how to deal with it. For me it can be ignored but I don’t see how to make it.


#14

What is the form of the comment?


#15

In any part of the document (end of line or all the line :slight_smile:start with ‘#’ followed by nothing or anything


#16

well I just fix it …

I add “|#.+|#” in the ignored section :wink:

thanbks for the help