Skip to content

Commit

Permalink
Grammar: flat args and params
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanjermakov committed Jun 5, 2023
1 parent 2158a0d commit 64a86c5
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 7 deletions.
10 changes: 8 additions & 2 deletions src/grammar.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ postfix-op ::= call-op
call-op ::= OPEN-PAREN args CLOSE-PAREN
;

args ::= expr COMMA args
args ::= args_
;

args_ ::= expr COMMA args_
| expr trailing-comma
| E
;
Expand All @@ -65,7 +68,10 @@ block ::= OPEN-BRACE statements CLOSE-BRACE
| OPEN-BRACE CLOSE-BRACE
;

params ::= param COMMA params
params ::= params_
;

params_ ::= param COMMA params_
| param trailing-comma
| param
| E
Expand Down
20 changes: 18 additions & 2 deletions src/grammar.json
Original file line number Diff line number Diff line change
Expand Up @@ -224,11 +224,19 @@
},
{
"name": "args",
"branches": [
[
"args_"
]
]
},
{
"name": "args_",
"branches": [
[
"expr",
"comma",
"args"
"args_"
],
[
"expr",
Expand Down Expand Up @@ -268,11 +276,19 @@
},
{
"name": "params",
"branches": [
[
"params_"
]
]
},
{
"name": "params_",
"branches": [
[
"param",
"comma",
"params"
"params_"
],
[
"param",
Expand Down
51 changes: 48 additions & 3 deletions src/parser/parser.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { tokenize } from '../lexer/lexer'
import { expect } from '@jest/globals'
import { compactToken, flattenToken, parse, ParserTokenName, Token } from './parser'
import { compactToken, flattenToken, parse, ParserTokenName, prettySyntaxError, Token } from './parser'

describe('parser', () => {

Expand All @@ -11,7 +11,7 @@ describe('parser', () => {
throw Error('parsing error: skipped root')
}
if ('expect' in token) {
throw Error(`parsing error: ${token}`)
throw Error(`parsing error: ${prettySyntaxError(token)}`)
}
return flattenToken(token)
}
Expand All @@ -28,6 +28,7 @@ describe('parser', () => {
'operand': [{
'function-expr': [
{ 'open-paren': '(' },
{ 'params': [] },
{ 'close-paren': ')' },
{ 'colon': ':' },
{ 'type': [{ 'identifier': 'Unit' }] },
Expand Down Expand Up @@ -78,6 +79,7 @@ describe('parser', () => {
'operand': [{
'function-expr': [
{ 'open-paren': '(' },
{ 'params': [] },
{ 'close-paren': ')' },
{ 'colon': ':' },
{ 'type': [{ 'identifier': 'Unit' }] },
Expand Down Expand Up @@ -176,9 +178,52 @@ describe('parser', () => {
{ 'operand': [{ 'string': '"str"' }] },
{ 'infix-operator': [{ 'period': '.' }] },
{ 'operand': [{ 'identifier': 'ok' }] },
{ 'postfix-op': [{ 'call-op': [{ 'open-paren': '(' }, { 'close-paren': ')' }] }] }
{
'postfix-op': [{
'call-op': [
{ 'open-paren': '(' },
{ 'args': [] },
{ 'close-paren': ')' }]
}]
}
]
})
})

it('parse args', () => {
const rule = parseToken('(a: Int, b: Int, c: Option<String>): Unit {}', 'expr')
expect(compactToken(rule!)).toEqual({
'expr': [{
'operand': [{
'function-expr': [
{ 'open-paren': '(' },
{
'params': [
{ 'param': [{ 'identifier': 'a' }, { 'colon': ':' }, { 'type': [{ 'identifier': 'Int' }] }] },
{ 'comma': ',' },
{ 'param': [{ 'identifier': 'b' }, { 'colon': ':' }, { 'type': [{ 'identifier': 'Int' }] }] },
{ 'comma': ',' },
{
'param': [
{ 'identifier': 'c' }, { 'colon': ':' }, {
'type': [
{ 'identifier': 'Option' },
{ 'open-chevron': '<' },
{ 'type-params': [{ 'type': [{ 'identifier': 'String' }] }] },
{ 'close-chevron': '>' }
]
}
]
}]
},
{ 'close-paren': ')' },
{ 'colon': ':' },
{ 'type': [{ 'identifier': 'Unit' }] },
{ 'block': [{ 'open-brace': '{' }, { 'close-brace': '}' }] }
]
}]
}]
})
})

})
2 changes: 2 additions & 0 deletions src/parser/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,5 @@ export const compactToken = (token: Token): any => {
return { [token.name]: token.value }
}
}

export const prettySyntaxError = (error: SyntaxErrorInfo): string => `Expected ${error.expect}, got: ${error.got} at ${error.location}`

0 comments on commit 64a86c5

Please sign in to comment.