Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Lax parser #8

Open
wants to merge 2 commits into
base: antlr
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ script:
- make
- npm test
- npm run fmt
- git diff
- git diff --quiet
2 changes: 1 addition & 1 deletion js/bin/electro-grammar.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const cli = require('cli');
const lib = require('../lib/index');
const lib = require('../lib/lax_parser');

const args = cli.parse({
parser: [ 'p', 'Parser to use (strict | lax)', 'string', 'strict' ],
Expand Down
59 changes: 27 additions & 32 deletions js/lib/lax_parser.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,46 @@
const {ElectroGrammarLexer} = require('./ElectroGrammarLexer');
const {ElectroGrammarParser} = require('./ElectroGrammarParser');
const {ElectroGrammarListener} = require('./ElectroGrammarListener');
const {ToObjectListener} = require('./to_object_listener');
const antlr4 = require('antlr4');

class LexerIgnoreListener extends antlr4.error.ErrorListener {
class IgnoreListener extends ElectroGrammarListener {
constructor() {
super();
this.ignored = '';
this.obj = '';
}
syntaxError(lexer, offendingSymbol, line, char, err) {
console.error('lexer:', err);
// hopefully there is a better way to get the input, but I haven't found it
let input = err.split(':')[1].trim();
input = input.substring(1, input.length - 1);
this.ignored += input;
exitIgnored(ctx) {
ctx.UNKNOWN().forEach(s => {
this.obj += s.getText();
});
}
}

class ParserIgnoreListener extends antlr4.error.ErrorListener {
constructor() {
super();
this.ignored = '';
}
syntaxError(lexer, offendingSymbol, line, char, err) {
console.error('parser:', err);
//this.ignored += input;
function get_parser(start_rule, listener) {
function parse(input) {
const chars = new antlr4.InputStream(input);
const lexer = new ElectroGrammarLexer(chars);
const tokens = new antlr4.CommonTokenStream(lexer);
const parser = new ElectroGrammarParser(tokens);
parser.buildParseTrees = true;

const tree = parser[start_rule]();
antlr4.tree.ParseTreeWalker.DEFAULT.walk(listener, tree);
return listener.obj;
}
return parse;
}

function parse(input) {
const chars = new antlr4.InputStream(input);
const lexer = new ElectroGrammarLexer(chars);
const lexerIgnorer = new LexerIgnoreListener();
lexer.removeErrorListeners();
lexer.addErrorListener(lexerIgnorer);
const tokens = new antlr4.CommonTokenStream(lexer);
const parser = new ElectroGrammarParser(tokens);
const parserIgnorer = new ParserIgnoreListener();
parser.buildParseTrees = true;
parser.removeErrorListeners();
parser.addErrorListener(parserIgnorer);
return get_parser('electro_grammar')(input);
}

const tree = parser.electro_grammar();
const listener = new ToObjectListener();
const walker = antlr4.tree.ParseTreeWalker.DEFAULT.walk(listener, tree);
console.log({lexer: lexerIgnorer.ignored, parser: parserIgnorer.ignored});
return {component: listener.obj, ignored: lexerIgnorer.ignored};
function parse(input) {
const parseComponent = get_parser('electro_grammar', new ToObjectListener());
const component = parseComponent(input);
const parseIgnored = get_parser('ignored', new IgnoreListener());
const ignored = parseIgnored(input);
return {component, ignored};
}

module.exports = {parse};
12 changes: 5 additions & 7 deletions src/ElectroGrammar.g4
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
/*
* Lexer Rules
*/

grammar ElectroGrammar;
import Passive, Semi;
import Passive;

electro_grammar: passive EOF;

electro_grammar: (passive | semi) EOF;
ignored: UNKNOWN* EOF;

WHITESPACE: [\p{White_Space}] -> skip;
UNKNOWN: .+?;
22 changes: 3 additions & 19 deletions src/Passive.g4
Original file line number Diff line number Diff line change
@@ -1,22 +1,6 @@
grammar Passive;
import Dielectric, Package, Units;
import Units;

passive: resistor | capacitor | inductor | oscillator;
passive: resistor;

passive: resistor | capacitor | inductor | oscillator;
resistor: resistance rspec*;
rspec: rtype | rpackage | power;
rtype: POT;
rpackage: package_chip;
POT: P O T | P O T E N T I O M E T E R;

capacitor: capacitance cspec*;
cspec: dielectric | cpackage | voltage;
cpackage: package_chip;

inductor: inductance lspec*;
lspec: lpackage | current;
lpackage: package_chip;

oscillator: frequency ospec*;
ospec: capacitance;
resistor: resistance;
4 changes: 2 additions & 2 deletions src/Units.g4
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ aprefix: MILI | MICRO | NANO | PICO;
power: NUMBER pprefix? WATT tolerance?;
pprefix: MILI;

resistance: NUMBER (rprefix | OHM) tolerance?;
rprefix: MEGA | KILO | MILI;
resistance: NUMBER (RPREFIX | OHM);
RPREFIX: MEGA | KILO | MILI;

capacitance: NUMBER cprefix FARAD tolerance?;
cprefix: MICRO | NANO | PICO;
Expand Down